Struct Flattening

GC const.ref at gmail.com
Thu Apr 23 02:06:56 PDT 2009


dsimcha Wrote:

> I'm working on porting dstats to ranges and I've run across an interesting
> problem.  I've defined a range that I'm going to use for joint entropy, etc.
> It's basically a tuple with some special properties.  Let's say I have a
> template struct:
> 
> struct Joint(T...) {
>    T ranges;
> }
> 
> It's built with:
> 
> SomeType joint(T...)(T args) { // do stuff. }
> 
> When one of the arguments is a Joint, I want it to flatten.  For example,
> 
> Joint!(uint[], uint[]) r1;
> uint[] r2;
> auto result = joint(r1, r2);
> // result is a Joint!(uint[], uint[], uint[]), not a
> // Joint!(Joint!(uint[], uint[]), uint[]).
> 
> Is there an easy metaprogramming trick that I've overlooked to make stuff
> flatten like this?

As a variant:

template jFlate(T...)
{
    static if(T.length == 0)
        alias Tuple!() jFlate;
    else
        static if( is( typeof( T[0].range ) ) )
            alias Tuple!(jFlate!(typeof(T[0].range)), jFlate!(T[ 1 .. $ ]) ) jFlate; // typeof(T[0].range) or jFlate!(typeof(T[0].range)) if you need Joint!(Joint!(uint[], Joint![uint])).range as  (uint[], uint[])
        else
            alias Tuple!(T[0], jFlate!(T[ 1 .. $ ]) ) jFlate;
}

Joint!(jFlate!(T)) joint(T...)(T args)
{
    return Joint!(jFlate!(T))();
}




More information about the Digitalmars-d mailing list