Kevin Bealer wrote:
Andrei Alexandrescu Wrote:

The grand STL tradition is to _always_ take iterators by value. If iterators are computed, they are returned by the algorithm.

My initial approach to defining std.algorithm was to continue that tradition for ranges: ranges are values. No algorithm currently takes a range by reference. There are a couple of simple functions that emphatically do take ref, namely popFrontN and popBackN in std.range.

It is becoming, however, increasingly clear that there are algorithms that could and should manipulate ranges by reference. They might take and return values, but it's just too messy to do so. (Cue music for the "improve built-in tuples choir.)

A concrete case is text processing. Many contemporary libraries use index-based processing, but that's difficult when handling multibyte characters. To address that, bidirectional ranges are one correct way to go. Phobos defines a ByCodeUnit range that spans a string correctly, one dchar at a time. With that, you can write:

...
Andrei

I would vote yes -- I've used this technique (with my own character slice 
classes in C++) and they are a great idiom to work with.

I think ranges (and slices) have some of the properties from each of pointers, 
containers, and streams.  A stream is always a by-ref kind of thing unless you 
are in a language that needs monads etc.

Let me suggest one more function I've found very useful:

bool readUntil(R1, R2, R3)(ref R1 input, R2 delim, ref R3 result)
{
  // Like findSkip, but returning intervening text.
}

You read my mind. I was thinking of something with "copy" in the name.

Andrei

Reply via email to