C++17 introduced the concept of ContiguousIterator http://en.cppreference.com/w/cpp/iterator.
However it doesn't seem that there are plans to have a contiguous_iterator_tag
(in the same way we now have random_access_iterator_tag
) reported by std::iterator_traits<It>::iterator_category
.
Why is contiguous_iterator_tag
missing?
Is there a conventional protocol to determine if an iterator is Contiguous? Or a compile time test?
In the past I mentioned that for containers if there is a .data()
member that converts to a pointer to ::value
type and there is .size()
member convertible to pointer differences, then one should assume that the container is contiguous, but I can't pull an analogous feature of iterators.
One solution could be to have also a data
function for contiguous iterators.
Of course the Contiguous concept works if &(it[n]) == (&(*it)) + n
, for all n
, but this can't be checked at compile time.
EDIT: I found this video which puts this in the more broader context of C++ concepts. CppCon 2016: "Building and Extending the Iterator Hierarchy in a Modern, Multicore World" by Patrick Niedzielski. The solution uses concepts (Lite) but at the end the idea is that contiguous iterators should implement a pointer_from
function (same as my data(...)
function).
The conclusion is that concepts will help formalizing the theory, but they are not magic, in the sense that someone, somewhere will define new especially named functions over iterators that are contiguous.
The talk generalizes to segmented iterators (with corresponding functions segment
and local
), unfortunatelly it doesn't say anything about strided pointers.
The rationale is given in N4284, which is the adopted version of the contiguous iterators proposal:
Some code was broken because it assumed that
std::random_access_iterator
couldn't be refined, and had explicit checks against it. Basically it broke bad code that didn't rely on polymorphism to check for the categories of iterators, but it broke code nonetheless, socontiguous_iterator_tag
was removed from the proposal.Also, there was an additional problem with
std::reverse_iterator
-like classes: a reversed contiguous iterator can't be a contiguous iterator, but a regular random-access iterator. This problem could have been solved forstd::reverse_iterator
, but more user-defined iterator wrappers that augment an iterator while copying its iterator category would have either lied or stopped working correctly (for example Boost iterator adaptors).On a side note, there are plans to bring back an equivalent of
std::contiguous_iterator_tag
with a few workarounds to make it work with the integration of the Ranges TS in C++20.