How to work with an "arbitrary input range"?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Thu Oct 21 17:34:00 PDT 2010


On 10/21/10 17:32 CDT, Adam D. Ruppe wrote:
> I've seen the requirement tossed around a few times that functions should work
> with arbitrary input ranges.
>
> What, exactly, does this mean?
>
> My first impression is:
>
> void myFunction(T)(T t) if(isInputRange!(T)) {}
>
> But I don't see how that actually works in practice. Suppose my function
> parses some kind of text format, like D code or XML. It won't work with a
> stream of integers.
>
> OK, what about:
>
> void myFunction(T)(T t) if(isSomeString!(T)) {}
>
>
> The function could certainly work with that, but it doesn't seem to me to be
> an arbitrary input range anymore; it is little different than if I just said
> myFunction(string t).
>
>
> Should it be something like this?
>
> if(is(T.front : dchar))
>
> (I'm sure that's actually wrong syntax, but hopefully you know what I mean)
>
>
> That seems weak, since it wouldn't work with stdin.byLine, but perhaps it
> shouldn't - the file format is char based, not line based. (should there be an
> adapter range available there, to feed me one char at a time from a series of
> lines? That seems to be adding a layer just to cancel out the one beneath it
> though.)
>
>
> Anyway, what's the right thing to do here?

Good discussion. I think the algorithm is:

1. Figure out requirements on the range type (choose the weakest of 
input, forward, bidir, and random access)

2. Figure out requirements on the element type (choose the most general 
that works). Don't forget that you can access the element type of any 
range with ElementType!R.

3. Put the requirements in the template constraint.

Example:

// Process any range of characters
void process1(R)(R r) if (isInputRange!R && isSomeChar!(ElementType!R));

// Process any range of built-in numbers
void process2(R)(R r) if (isInputRange!R && is(ElementType!R : real));

// Process a random-acces range of ints
void process3(R)(R r) if (isRandomAccessRange!R
     && is(Unqual!(ElementType!R) == int));



Andrei


More information about the Digitalmars-d mailing list