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

Reply via email to