On 6/30/12 7:31 AM, monarch_dodra wrote:
I've been enjoying my time with D's ranges, but something is nagging at
me: If the range is not random access, then how does one create a
sub-view of that range?

Use take or takeExactly.

Say I have a forward range (for example, an SList[]). I would like to
create a new range containing only the first 5 elements of that old
range. How can I do that?

take(r, n) or takeExactly(r, n).

I see no logical reason that prevents me from doing it, since C++
iterators can do it quite fine.

Actually, not at all. Iterators are a lot worse off than ranges here.

C++'s std::forward_list (and generally any iterator-providing singly-linked list) only offers an iterator to the first element. (The "end" iterator is a wrapped null pointer. This is by definition of the structure - singly-linked lists don't track their last element.)

So if you were to to take 5 elements off a std::forward_list, you can't use lst.begin() and lst.begin() + 5 because there's no addition; you'd need to define a new iterator type that combines a forward iterator with an integer, and iterate using that. It's all painstaking revealing how much a range is better for such. This is because the range keeps together the iteration limits, whereas iterators insist on the fact that the iteration limits belong separately.

(the C++ algorithms that work only on RA
ranges is mostly for efficiency reasons). Not being able to do this
would severely limit the amount of containers that can seamlessly merge
with algorithms.

For example, I can't call splitter on an SList. Not sure if this is just
"not currently supported", or just not possible...

Any thoughts?

It must be very well understood what the structural limits of singly-linked lists impose on their iteration. There's no way to take 5 elements off a SList and pretend that's pretty much the same as taking the whole list.

We could build a design for using splitter with SLists only if the element type of splitter's result is different from SList's native range.


Andrei

Reply via email to