On 2/15/15 10:06 PM, Vlad Levenfeld wrote:
Since C++17, there's a new iterator category: the contiguous iterator.
Check it out: http://en.cppreference.com/w/cpp/iterator
So, by extension, I think a ContiguousRange would be any
RandomAccessRange which has a member called ptr which supports a
dereferencing operator * that yields an ElementType!R. This notion is
useful for functions which might otherwise perform an element-by-element
transfer to an OutputRange via put, instead perform an optimized batch
transfer directly to a ContiguousRange via ptr. (Not that Contiguous
implies Output; this example assumes the ContigiousRange has enough
length to accomodate the transfer or otherwise has mutable length, e.g.
builtin arrays.)
I've been using the idea implicitly in my code with static if (is
(typeof(*R.init.ptr) == ElementType!R)), but seeing that table made me
realize it could be formally abstracted out to a range concept.
Interesting. This needs, however, a few more implementations that
motivate the concept. Also, I see potential for misuse already: for an
array r, is r.retro contiguous or not? One might argue it is because its
layout is still contiguous; however, in that case people shouldn't
assume that .ptr necessarily points to the first element.
Contiguous ranges would help two useful primitives: r1.before(r2) yields
the portion of r1 before r2 (assumes r2 overlaps r1), and r1.after(r2)
yields the portion of r1 after r2 (same assumption). Basically
r1.before(r2) is r1[0 .. r2.ptr - r1.ptr] and r1.after(r2) is r1[r2.ptr
+ r2.length - r1.ptr .. $].
Andrei