Composite Pattern and simplificaton

JS js.mdnq at gmail.com
Wed Jul 3 21:25:29 PDT 2013


I'm trying to write a mixin that will solve the problem but since 
I can't seem to build up strings progressively it's a huge pain 
in the ass.


import std.stdio, std.cstream, std.traits, std.conv;

interface A { void myfunc(real, int, string); @property int 
myvalue(); }


template reverseEnum(alias e, alias value)
{
	string eval()
	{
		foreach(v; EnumMembers!e)
		{
			static if (to!int(v) - to!int(value) == 0)
				return to!string(v);
		}
		
		return "";
	}
	enum reverseEnum = '"' ~ eval() ~ '"';
}
template evaluateParameterTypeTuple(string x) { enum 
evaluateParameterTypeTuple = 
"ParameterTypeTuple!("~x~").stringof"; }
template evaluateReturnType(string x) { enum evaluateReturnType = 
"ReturnType!("~x~").stringof"; }
template evaluateAttributes(string x) { enum evaluateAttributes = 
"functionAttributes!("~x~")"; }
template replaceString(string x, string y, string z) { string 
eval() { static if(x == y) return z; return x; } enum 
replaceString = "'~eval()~'"';
}

template implementInterface(alias I, alias i)
{
	
	static string implement()
	{
		//string x;
		foreach(name; __traits(allMembers, I))
		{
			enum qname = I.stringof ~ "." ~ name;
			enum a = 
mixin(replaceString!("@"~mixin(reverseEnum!(FunctionAttribute, 
to!int(mixin(evaluateAttributes!(qname))))) ~ " ", "@none ", ""));
			enum bbody = " { return " ~ i.stringof ~ "." ~ name ~ "(); }";
			enum x = a ~ mixin(evaluateReturnType!(qname)) ~ " " ~ name ~ 
mixin(evaluateParameterTypeTuple!(qname)) ~ bbody;
			pragma(msg, ">" ~ x);
		}
		
		return "";
	}
	enum implementInterface = implement();
}

class B : A
{
	A a;
	mixin(implementInterface!(A, a));
}


void main(string[] args)
{
	din.getc();
}



The code produces results like

void myfunc(real, int, string) { return a.myfunc(); } and
@property myvalue() { return a.myvalue(); }

which at some point, when finished, can be inserted into class B 
to implement A.

The problem, is that I can't build up the strings progressively 
in the mixin templates because I get errors that the variable 
can't be read at compile time.

I can do stuff like

enum x = "a" ~ "b" ~ "c";

but not

enum x = "a";
x ~= "b";
x ~= "c";

or whatever...

strings are about useless as they have the same issue.

I understand that compile time evaluation needs to have static 
behavior but I'm not doing anything that can't be done at compile 
time.

I had to write a template just to replace a the "none" attribute 
because I couldn't easily do it directly.  I can't have the 
reverseEnum work with multiple flags because I can't build up the 
attribute string progressively. While I imagine it is possible to 
hack it up by tricking the compiler it starts to feel C'sh with 
something that should be pretty simple...

Maybe someone has some ideas?


More information about the Digitalmars-d mailing list