Make a hash out of two ranges

Andrej Mitrovic andrej.mitrovich at gmail.com
Wed Feb 27 20:20:43 PST 2013


On 2/28/13, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> You'd need to wrap them in a single range of pairs with something like zip.

I'm not exactly sure how to do that though. Just using zip in the
argument place won't work.

I've tried to create my own range, but I'm having issues:

import std.string;
import std.stdio;
import std.range;

auto mymap(alias func, Ranges...)(Ranges ranges)
{
    static struct MyMap
    {
        Ranges ranges;

        @property bool empty()
        {
            foreach (ref range; ranges)
                if (range.empty)
                    return true;

            return false;
        }

        @property auto front()
        {
            static string getMixin()
            {
                string[] args;
                foreach (idx; 0 .. Ranges.length)
                    args ~= format("ranges[%s].front", idx);
                return args.join(", ");
            }

            mixin(format(q{
                return func(%s);
            }, getMixin()));
        }

        void popFront()
        {
            foreach (ref range; ranges)
                range.popFront();
        }
    }

    return MyMap(ranges);
}

void main()
{
    auto r = mymap!((a, b) => [a : b])([1, 3], [2, 4]);

    writeln(r.front);  // [1:2]
    r.popFront();
    writeln(r.front);  // [3:4]
    r.popFront();
    // writeln(r.front);  // this would throw as expected

    auto r2 = mymap!((a, b) => [a : b])([1, 3], [2, 4]);
    foreach (x; r2)
        writeln(r2);  // prints "[[1:2], [3:4]]" twice, why?
}


More information about the Digitalmars-d-learn mailing list