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