I wrote a version of cartesianProduct that will return the cartesian product when the some of the types are not ranges. The original code is below.

My issue is that I can't figure out how to turn it into a variadic template. The latest thing I tried is:

auto mixedCartesianProduct(T...)(T x)
{
        import std.algorithm : cartesianProduct;
        
        foreach(t; x)
                t = conditionalOnly(t);
        
        return cartesianProduct(x);
}

but this doesn't work because it changes the type of x. I don't really want to change the type of x. I just want to be able to pass the changed versions to cartesianProduct as in the original code below.

map won't work for the same reasons.

//Original:
auto conditionalOnly(T)(T x)
{
        import std.range : isInputRange;
        
        static if (isInputRange!T)
                return x;
        else
        {
                import std.range : only;
                return only(x);
        }
}

auto mixedCartesianProduct(T, U)(T x, U y)
{
        import std.algorithm : cartesianProduct;
        
        return cartesianProduct(conditionalOnly(x), conditionalOnly(y));
}

void main()
{
        import std.stdio : writeln;
        import std.range : iota;

        auto a = 1;
        auto b = iota(2);
        
        auto c = mixedCartesianProduct(a, b);
        writeln(c);
}

Reply via email to