bearophile wrote:
template isInputRange(R) {
    enum bool isInputRange = __traits(compiles, {
        R r;              // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront;       // can invoke next
        auto h = r.front; // can get the front of the range
    });
}

I don't know if this is correct, but if it's correct, is it better looking? It 
looks almost the same to me.

Eh, it has the word "compiles" in it... You're right, though, it's not great.

I guess a single linked list can be seen as an OutputRange then. You can add an 
item where you are and scan it forward (unfortunately linked listes today are 
dead, they are never an efficient solution on modern CPUs)

LinkedList!(T) is basically useless. But how many times have you used a structure with a "next" and/or "previous" pointer? How about separate chaining in hash tables? "parent" pointers (forms a linked list up to the root for trees, also applies to GUI widgets, French fries, directory hierarchies, etc.)? Linked lists are *everywhere*, they're just generally implicit in some structure and not very long.

In what othr situations you may use/need an OutputRange? In a file, as in a stack, you can only add in a very specific point (the end, in files, or replace the current item).

I think an OutputRange doesn't have to be an InputRange. It just needs put().

Reply via email to