algorithms that take ranges by reference
Kevin Bealer
kevinbealer at gmail.com
Wed Dec 30 15:22:16 PST 2009
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.
}
Then you can write something like:
bool consumeQuotedString(R1,R2)(ref R1 text, ref R2 quoted)
{
if (skip(text, "'")) {
if (! readUntil(text, "'", quoted)) {
/*error*/
}
return true;
}
return found;
}
Kevin
More information about the Digitalmars-d
mailing list