Closed gnzlbg closed 8 years ago
The semantics of ranges generally follow from the semantics of iterator / sentinel pairs, i.e., tagged_pair<begin(I), end(S)>
is intended to satisfy View
when I
and S
satisfy Sentinel
(IteratorRange
in range-v3 terminology). That tagged_pair
is Copyable
, so requiring Copyable + SinglePass
to imply the same results on each iteration would effectively require all iterators to be multi-pass. There obviously are single-pass ranges that meet your requirement, but it's not something that can be required of all single-pass ranges.
That tagged_pair is Copyable, so requiring Copyable + SinglePass to imply the same results on each iteration would effectively require all iterators to be multi-pass. There obviously are single-pass ranges that meet your requirement, but it's not something that can be required of all single-pass ranges.
Good example, constraining on Copyable
doesn't make any sense then.
I'm not convinced this distinction needs to be surfaced in the range hierarchy. Can you give some concrete examples where this would make a difference?
Closing.
I thought about this some more and looked at my algorithms. Basically they needed to estimate the distance of a range before using the range (e.g. for building an unstructured mesh from an octree). They require ForwardRange
for this, but I am using them with a range composition that uses view::join
. The result is single pass but is cheap to copy, so I "worked around this" by lowering the requirement to InputRange and just copy the range before each usage if the range is SinglePass.
This felt wrong, and I'm inclined to think "don't do that". One should not work around SinglePass ranges like this. Still, some useful views are SinglePass because they need to maintain some state, but they remain cheap to copy (e.g. a couple of pointers) and can in practice be iterated multiple times.
At the end I just changed the API of these algorithms so that the caller needs to pass the distance to them. But a different solution could have been to require InputRange
and Sized
, such that the caller needs to make the range Sized
. I guess this is what view::take_exactly
is there for.
Some SinglePass ranges that can be copied always produce the same sequence when the copies are iterated upon.
Is there a way to differentiate these types of SinglePass ranges from those that can produce different results on each iteration? E.g. is there a guarantee that
Copyable
+SinglePass
implies same results on each iteration?I'm asking because I have a multi pass algorithm that does also work with some SinglePass ranges (and I need it to work with these) if I make a copy of the range before each usage. So
ForwardRange
would over constrain my algorithm, butInputRange
is not strong enough. Still I ended up usingInputRange
+ the following utility function to copy the range before using it, which kind of feels like a hack: