www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: Struct Flattening

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))(); }
Apr 23 2009