patterncppMinor
The final word on contiguous iterators
Viewed 0 times
thewordfinalcontiguousiterators
Problem
Following the paradigms of SCARY iterators, there should only be a single iterator-type for contiguous iterators per value-type.
Here my code for that iterator, working with C++11+:
```
#include
#include
template
struct is_more_cv_qualified : std::integral_constant{}
|| std::is_same{} || std::is_same{}>;
struct contiguous_iterator_tag : std::random_access_iterator_tag {};
struct mutable_contiguous_iterator_tag : contiguous_iterator_tag, std::output_iterator_tag {};
template
struct contiguous_iterator_base {
constexpr bool operator==(contiguous_iterator_base other) const noexcept { return _p == other.p; }
constexpr bool operator!=(contiguous_iterator_base other) const noexcept { return _p != other.p; }
constexpr bool operator(contiguous_iterator_base other) const noexcept { return _p > other._p; }
constexpr bool operator=(contiguous_iterator_base other) const noexcept { return _p >= other._p; }
constexpr std::ptrdiff_t operator-(contiguous_iterator_base other) const noexcept { return _p - other._p; }
protected:
constexpr contiguous_iterator_base& operator=(const contiguous_iterator_base&) noexcept = default;
T* _p = nullptr;
};
template
struct contiguous_iterator : contiguous_iterator_base::type>
, std::iterator{}, contiguous_iterator_tag, mutable_contiguous_iterator_tag>::type, T> {
constexpr contiguous_iterator() noexcept = default;
template{}>::type>
constexpr contiguous_iterator(contiguous_iterator other) noexcept : contiguous_iterator_base::type>(other) {}
constexpr explicit contiguous_iterator(contiguous_iterator_base::type> other) noexcept : decltype(other)(other) {}
constexpr explicit contiguous_iterator(T* p) noexcept { _p = const_cast(p); }
template
constexpr contiguous_iterator rebind() const noexcept { return contiguous_iterator(_p); }
constexpr T* operator->() const noexcept { return _p; }
constexpr T& operator () const noexcept { return _p; }
constexpr T& operator[](std::
Here my code for that iterator, working with C++11+:
```
#include
#include
template
struct is_more_cv_qualified : std::integral_constant{}
|| std::is_same{} || std::is_same{}>;
struct contiguous_iterator_tag : std::random_access_iterator_tag {};
struct mutable_contiguous_iterator_tag : contiguous_iterator_tag, std::output_iterator_tag {};
template
struct contiguous_iterator_base {
constexpr bool operator==(contiguous_iterator_base other) const noexcept { return _p == other.p; }
constexpr bool operator!=(contiguous_iterator_base other) const noexcept { return _p != other.p; }
constexpr bool operator(contiguous_iterator_base other) const noexcept { return _p > other._p; }
constexpr bool operator=(contiguous_iterator_base other) const noexcept { return _p >= other._p; }
constexpr std::ptrdiff_t operator-(contiguous_iterator_base other) const noexcept { return _p - other._p; }
protected:
constexpr contiguous_iterator_base& operator=(const contiguous_iterator_base&) noexcept = default;
T* _p = nullptr;
};
template
struct contiguous_iterator : contiguous_iterator_base::type>
, std::iterator{}, contiguous_iterator_tag, mutable_contiguous_iterator_tag>::type, T> {
constexpr contiguous_iterator() noexcept = default;
template{}>::type>
constexpr contiguous_iterator(contiguous_iterator other) noexcept : contiguous_iterator_base::type>(other) {}
constexpr explicit contiguous_iterator(contiguous_iterator_base::type> other) noexcept : decltype(other)(other) {}
constexpr explicit contiguous_iterator(T* p) noexcept { _p = const_cast(p); }
template
constexpr contiguous_iterator rebind() const noexcept { return contiguous_iterator(_p); }
constexpr T* operator->() const noexcept { return _p; }
constexpr T& operator () const noexcept { return _p; }
constexpr T& operator[](std::
Solution
There really isn't much to say here. This looks really good.
Typos
You have a couple typos in your code on your equality operators. You're comparing against
Not restrictive enough
We have this constructor:
But that means if we have
On a similar vein,
Add another alias
Rather than writing this:
If you added a
which makes way more sense.
Missing alias
You're using the alias templates for the type traits throughout, except you're using
Line widths
Some of these lines are really long! Add some line breaks.
Why?
I guess lastly... what does
Typos
You have a couple typos in your code on your equality operators. You're comparing against
other.p instead of other._p. Not restrictive enough
We have this constructor:
constexpr explicit contiguous_iterator(T* p);But that means if we have
contiguous_iterator, we can construct it with a Derived*. We definitely need to disallow this. On a similar vein,
rebind should be restricted to those Us which are the same type as T and are at least as cv-qualified. Add another alias
Rather than writing this:
constexpr explicit contiguous_iterator(contiguous_iterator_base> other) noexcept : decltype(other)(other) {}If you added a
using base = contiguous_iterator_base>;, you could write:constexpr explicit(base other) noexcept : base(other) {}which makes way more sense.
Missing alias
You're using the alias templates for the type traits throughout, except you're using
typename std::conditional::type instead of std::conditional_t. Line widths
Some of these lines are really long! Add some line breaks.
Why?
I guess lastly... what does
contiguous_iterator accomplish that simple T* doesn't?Code Snippets
constexpr explicit contiguous_iterator(T* p);constexpr explicit contiguous_iterator(contiguous_iterator_base<std::remove_cv_t<T>> other) noexcept : decltype(other)(other) {}constexpr explicit(base other) noexcept : base(other) {}Context
StackExchange Code Review Q#113866, answer score: 4
Revisions (0)
No revisions yet.