creating a variadic interface

JS js.mdnq at gmail.com
Mon Jul 8 04:25:56 PDT 2013


On Monday, 8 July 2013 at 10:16:22 UTC, John Colvin wrote:
> On Monday, 8 July 2013 at 09:34:46 UTC, JS wrote:
>>
>> this may seem a bit nonsensical but it is just an example:
>>
>> interface A(T, S...)
>> {
>>   ... Generate a getter for each type in S...
>>   // e.g., @property S[0] property1();
>>   //       @property S[1] property2();
>>   // ....
>> }
>>
>> I imagine I have to use a mixin template but I'm unsure how to 
>> create a static loop that can be used properly.
>>
>> I think maybe using mixin's of mixin's is possible but I can't 
>> think of any simple way. Any ideas?
>
> Here you go :)
>
> //just to hide the string mixin.
> mixin template Getters(S ...)
> {
> 	mixin(GettersImpl!S);
> }
>
> import std.conv : to;
> template GettersImpl(S ...)
> {
> 	static if(S.length == 0)
> 	{
> 		enum GettersImpl = "";
> 	}
> 	else static if(S.length == 1)
> 	{
> 		enum GettersImpl = "@property " ~ (S[$-1]).stringof ~ " 
> property" ~ to!string(S.length) ~ "();\n";
> 	}
> 	else
> 	{
> 		enum GettersImpl = "@property " ~ (S[$-1]).stringof ~ " 
> property" ~ to!string(S.length) ~ "();\n"
> 						   ~ GettersImpl!(S[0..$-1]);
> 	}
> }
>
>
> interface A(S...)
> {
> 	mixin Getters!S;
> }
>
> class B : A!(int, long, string)
> {
> 	//if everything works, we get errors here for missing methods.
> }



I guess you beat me too it but I came up with something very 
similar which I think works too(uses foreach instead of 
recursion)..


mixin template a(T...)
{
	template b(TT...)
	{
		static string eval()
		{
			string s;
			int i = 0;
			foreach(t; TT)
				s = "@property "~(t).stringof~" Name"~to!string(i++)~"();\n";
			return s;
		}
		enum b = eval();
	}

	mixin("mixin(b!T);");
	
}


More information about the Digitalmars-d-learn mailing list