HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

The final word on contiguous iterators

Submitted by: @import:stackexchange-codereview··
0
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::

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 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.