Why tuples are not ranges?

Ali Çehreli acehreli at yahoo.com
Thu Jun 28 18:03:09 UTC 2018


On 06/28/2018 10:00 AM, Mr.Bingo wrote:

 > But is this going to be optimized?

Not our job! :o)

 > That is, a tuple is a range!

Similar to the array-slice distinction, tuple is a container, needing 
its range.

 > It is clearly easy to see if a tuple is empty, to get the front,

Ok.

 > and to
 > pop the front and return a new tuple with n - 1 elements, which is
 > really just the tuple(a sliced tuple, say) with the first member hidden.

That would be special for tuples because popFront does not return a new 
range (and definitely not with a new type) but mutates the existing one.

Here is a quick and dirty library solution:

// TODO: Template constraints
auto rangified(T)(T t) {
     import std.traits : CommonType;
     import std.conv : to;

     alias ElementType = CommonType!(T.tupleof);

     struct Range {
         size_t i;

         bool empty() {
             return i >= t.length;
         }

         ElementType front() {
             final switch (i) {
                 static foreach (j; 0 .. t.length) {
                 case j:
                     return t[j].to!ElementType;
                 }
             }
         }

         void popFront() {
             ++i;
         }

         enum length = t.length;

         // TODO: save(), opIndex(), etc.
     }

     return Range();
}

unittest {
     import std.typecons : tuple;
     import std.stdio : writefln;
     import std.range : ElementType;

     auto t = tuple(5, 3.5, false);
     auto r = t.rangified;

     writefln("%s elements of '%s': %(%s, %)",
              r.length, ElementType!(typeof(r)).stringof, r);
}

void main() {
}

Prints

3 elements of 'double': 5, 3.5, 0

Ali



More information about the Digitalmars-d-learn mailing list