On Thursday, 28 June 2018 at 18:03:09 UTC, Ali Çehreli wrote:
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

Thanks, why not add the ability to pass through ranges and arrays and add it to phobos?

Reply via email to