Struct Flattening

Jarrett Billingsley jarrett.billingsley at gmail.com
Tue Apr 21 22:36:46 PDT 2009


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 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?

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



More information about the Digitalmars-d mailing list