Thread overview
Applying storage to type tuples
Feb 08, 2009
Burton Radons
Feb 09, 2009
Daniel Keep
Feb 09, 2009
Burton Radons
Feb 10, 2009
Daniel Keep
February 08, 2009
I'm writing a couple of modules for dealing with database values (well really it's just storage of aggregates) in a native fashion from within D, using D 2.023. I have a tuple called FieldTypes which contains the D-side types. I'm trying to use it to implement opApply:

    int opApply (int delegate (FieldTypes) func)

Unfortunately, this fails because the compiler only accepts the field types if they're references. But if I do this:

    int opApply (int delegate (ref FieldTypes) each)

It seems that the delegate takes a reference to one type, which is a value tuple! For example it claims that, simplified, "function Table.opApply (int delegate (ref (string, string)) each) does not match parameter types (int delegate (ref string, ref string))".

I've already implemented another opApply that takes a Line containing all the fields, but I'd like to have the expanded form as well if possible. Is it?
February 08, 2009
On Sun, Feb 8, 2009 at 4:25 PM, Burton Radons <burton.radons@gmail.com> wrote:
> I'm writing a couple of modules for dealing with database values (well really it's just storage of aggregates) in a native fashion from within D, using D 2.023. I have a tuple called FieldTypes which contains the D-side types. I'm trying to use it to implement opApply:
>
>    int opApply (int delegate (FieldTypes) func)
>
> Unfortunately, this fails because the compiler only accepts the field types if they're references. But if I do this:
>
>    int opApply (int delegate (ref FieldTypes) each)
>
> It seems that the delegate takes a reference to one type, which is a value tuple! For example it claims that, simplified, "function Table.opApply (int delegate (ref (string, string)) each) does not match parameter types (int delegate (ref string, ref string))".
>
> I've already implemented another opApply that takes a Line containing all the fields, but I'd like to have the expanded form as well if possible. Is it?
>

Strangely, if you have a function which takes a ref tuple parameter, it works as you'd expect:

void initialize(T...)(ref T args)
{
    foreach(arg; args)
        arg = arg.init;
}

void main()
{
    int x;
    float y;
    initialize(x, y); // fine
}

I think I had some trouble getting the compiler to eat opApplies that
did fancy stuff like this.  I ended up just doing int opApply(T)(T
dg).
February 09, 2009

Burton Radons wrote:
> I'm writing a couple of modules for dealing with database values (well really it's just storage of aggregates) in a native fashion from within D, using D 2.023. I have a tuple called FieldTypes which contains the D-side types. I'm trying to use it to implement opApply:
> 
>     int opApply (int delegate (FieldTypes) func)
> 
> Unfortunately, this fails because the compiler only accepts the field types if they're references. But if I do this:
> 
>     int opApply (int delegate (ref FieldTypes) each)
> 
> It seems that the delegate takes a reference to one type, which is a value tuple! For example it claims that, simplified, "function Table.opApply (int delegate (ref (string, string)) each) does not match parameter types (int delegate (ref string, ref string))".
> 
> I've already implemented another opApply that takes a Line containing all the fields, but I'd like to have the expanded form as well if possible. Is it?

Yeah, I've run into this before.  I solved it at the time using CTFE and string mixins:

alias mixin(refDelegateFromTuple!(FieldTypes)) FieldTypesDg;

  -- Daniel
February 09, 2009
Daniel Keep Wrote:

> 
> 
> Burton Radons wrote:
> > I'm writing a couple of modules for dealing with database values (well really it's just storage of aggregates) in a native fashion from within D, using D 2.023. I have a tuple called FieldTypes which contains the D-side types. I'm trying to use it to implement opApply:
> > 
> >     int opApply (int delegate (FieldTypes) func)
> > 
> > Unfortunately, this fails because the compiler only accepts the field types if they're references. But if I do this:
> > 
> >     int opApply (int delegate (ref FieldTypes) each)
> > 
> > It seems that the delegate takes a reference to one type, which is a value tuple! For example it claims that, simplified, "function Table.opApply (int delegate (ref (string, string)) each) does not match parameter types (int delegate (ref string, ref string))".
> > 
> > I've already implemented another opApply that takes a Line containing all the fields, but I'd like to have the expanded form as well if possible. Is it?
> 
> Yeah, I've run into this before.  I solved it at the time using CTFE and string mixins:
> 
> alias mixin(refDelegateFromTuple!(FieldTypes)) FieldTypesDg;

I couldn't quite figure out what you meant by this as DelegateFromTuple's not part of Phobos from what I can tell, but I did get this going:

	pure string BuildArguments (string prefix, T...) ()
	{
		string text;

		foreach (type; T)
		{
			if (text.length) text ~= ", ";
			text ~= prefix ~ " ";
			text ~= type.stringof;
		}

		return text;
	}

	alias TypeTuple! (int, float) FieldTypes;
	mixin ("alias int delegate (" ~ BuildArguments! ("ref", FieldTypes) () ~ ") FieldTypesDeg;");

Seems to work fine, I just don't know whether "stringof" is going to be well-behaved here. Plus it's a little extra work for the compiler.
February 10, 2009

Burton Radons wrote:
> Daniel Keep Wrote:
> 
>>
>> Burton Radons wrote:
>>> I'm writing a couple of modules for dealing with database values (well really it's just storage of aggregates) in a native fashion from within D, using D 2.023. I have a tuple called FieldTypes which contains the D-side types. I'm trying to use it to implement opApply:
>>>
>>>     int opApply (int delegate (FieldTypes) func)
>>>
>>> Unfortunately, this fails because the compiler only accepts the field types if they're references. But if I do this:
>>>
>>>     int opApply (int delegate (ref FieldTypes) each)
>>>
>>> It seems that the delegate takes a reference to one type, which is a value tuple! For example it claims that, simplified, "function Table.opApply (int delegate (ref (string, string)) each) does not match parameter types (int delegate (ref string, ref string))".
>>>
>>> I've already implemented another opApply that takes a Line containing all the fields, but I'd like to have the expanded form as well if possible. Is it?
>> Yeah, I've run into this before.  I solved it at the time using CTFE and string mixins:
>>
>> alias mixin(refDelegateFromTuple!(FieldTypes)) FieldTypesDg;
> 
> I couldn't quite figure out what you meant by this as DelegateFromTuple's not part of Phobos from what I can tell, but I did get this going:

refDelegateFromTuple isn't in Phobos; so far as I'm aware, Phobos doesn't contain any CTFE mixin functions.

> 	pure string BuildArguments (string prefix, T...) ()
> 	{
> 		string text;
> 
> 		foreach (type; T)
> 		{
> 			if (text.length) text ~= ", ";
> 			text ~= prefix ~ " ";
> 			text ~= type.stringof;
> 		}
> 
> 		return text;
> 	}
> 
> 	alias TypeTuple! (int, float) FieldTypes;
> 	mixin ("alias int delegate (" ~ BuildArguments! ("ref", FieldTypes) () ~ ") FieldTypesDeg;");
> 
> Seems to work fine, I just don't know whether "stringof" is going to be well-behaved here. Plus it's a little extra work for the compiler.

Looks fine to me; this is basically what I was suggesting, except I would have made the function build the entire delegate type as a string to clean up the calling code.

  -- Daniel