On Wed, Mar 30, 2016 at 06:12:40PM +0000, jmh530 via Digitalmars-d-learn wrote:
> 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:
[...]

Does this do what you want?

        import std.algorithm.setops : cartesianProduct;
        import std.range : only;
        import std.range.primitives;
        import std.meta : AliasSeq;
        
        template ImplType(T...)
        {
                static if (T.length == 0)
                        alias ImplType = AliasSeq!();
                else
                {
                        static if (isInputRange!(T[0]))
                                alias FirstType = T[0];
                        else
                                alias FirstType = typeof(only(T[0].init));
                        alias ImplType = AliasSeq!(FirstType, ImplType!(T[1 .. 
$]));
                }
        }
        
        auto conditionalOnly(alias fun, T...)(T x) {
                ImplType!T y;
                foreach (i, e; x) {
                        static if (isInputRange!(typeof(e)))
                                y[i] = e;
                        else
                                y[i] = only(e);
                }
                return fun(y);
        }
        
        void main() {
                import std.stdio;
                writeln(conditionalOnly!cartesianProduct(1, [2, 3], 4, [5, 6]));
        }

Note that conditionalOnly isn't specifically tied to cartesianProduct;
you can use it on anything that receives a variadic number of range
arguments.


T

-- 
"I'm not childish; I'm just in touch with the child within!" - RL

Reply via email to