Struct Flattening

dsimcha dsimcha at yahoo.com
Wed Apr 22 06:45:16 PDT 2009


== Quote from Jarrett Billingsley (jarrett.billingsley at gmail.com)'s article
> On Wed, Apr 22, 2009 at 12:42 AM, dsimcha <dsimcha at yahoo.com> wrote:
> > I'm working on porting dstats to ranges and I've run across an interestin
> g
> > 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 exampl
> e,
> >
> > 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?
> So before reading the following solution, don't get your hopes up too
> much.  There's a compiler bug that prevents it from working.
> template Tuple(T...)
> {
> 	alias T Tuple;
> }
> template FlattenJoint(T : Joint!(U), U...)
> {
> 	alias FlatJoint!(U) FlattenJoint;
> }
> template FlattenJoint(T)
> {
> 	alias T FlattenJoint;
> }
> template FlatJoint(T...)
> {
> 	static if(T.length == 0)
> 		alias Tuple!() FlatJoint;
> 	else
> 		alias Tuple!(FlattenJoint!(T[0]), FlatJoint!(T[1 .. $])) FlatJoint;
> }
> struct Joint(T...)
> {
> 	FlatJoint!(T) ranges;
> }
> void main()
> {
> 	Joint!(uint[], uint[]) r1;
> 	Joint!(Joint!(uint[], uint[]), uint[]) r2;
> 	pragma(msg, typeof(r1.ranges).stringof);
> 	pragma(msg, typeof(r2.ranges).stringof);
> }
> This will print out:
> (uint[], uint[])
> (uint[])
> The second line really should be (uint[], uint[], uint[]), but there's
> something wrong with the way DMD matches the FlattenJoint template.  I
> was surprised, it does actually select the correct
> specialization(FlattenJoint(T : Joint!(U), U...), but for some reason,
> U is the empty tuple, even though T is Joint!(uint[], uint[]).
> I think it might have something to do with this bug (D2 is()
> expression, but a very similar mechanism and result):
> http://d.puremagic.com/issues/show_bug.cgi?id=1944

I guess I should clarify:  Getting the flattened type tuple is the easy part.  He
hard part is getting the flattened parameter tuple, i.e. how do I copy all the
data over to the new Joint!(uint[], uint[], uint[]) struct in a generic way?



More information about the Digitalmars-d mailing list