Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import std.traits : isIntegral, isFloatingPoint, isCallable,
- PIT=ParameterIdentifierTuple, PTT=ParameterTypeTuple;
- import std.conv : to ;
- import std.algorithm : startsWith ;
- import std.array : split ;
- //import std.stdio : writeln ;
- template GenStructs(uint count, U...)
- {
- static if (U.length == 0)
- {
- enum GenStructs = "\n";
- }
- else
- {
- enum GenStructs = "\n" ~ (U[0]).stringof ~ " _s" ~ to!string(count) ~ ";" ~
- GenStructs!(1+count, U[1..$]);
- }
- //pragma(msg, GenStructs);
- }
- /*
- struct test0 { }
- struct test1(T)
- {
- T A;
- this(T A_) { A = A_; }
- void setA(T A_) { A = A_; }
- T getA() { return A; }
- void empty() { writeln("empty() called"); }
- ~this() { }
- }
- */
- //pragma(msg, GenStructs!(0, test0, test1!(int)) );
- //pragma(msg, __traits(allMembers, test1!(int)));
- template Filter(U...)
- {
- static if (U.length == 0)
- {
- enum Filter = "";
- }
- else
- {
- static if ( (U[0]).startsWith("__") || (U[0]).startsWith("op") )
- {
- enum Filter = Filter!(U[1..$]); //skip U[0]
- }
- else
- {
- enum Filter = U[0] ~ "," ~ Filter!(U[1..$]);
- }
- }
- }
- //pragma(msg, Filter!(__traits(allMembers, test1!(int)))[0..$-1].split(",") );
- template StringOf(TS...)
- {
- static if(TS.length == 0)
- {
- enum StringOf = "";
- }
- else static if(TS.length == 1)
- {
- enum StringOf = (TS[0]).stringof;
- }
- else
- {
- enum StringOf = (TS[0]).stringof ~ "," ~ StringOf!(TS[1..$]) ;
- }
- }
- template ArgStringOf(TS...)
- {
- static if(TS.length == 0)
- {
- enum ArgStringOf = "";
- }
- else static if(TS.length == 1)
- {
- enum ArgStringOf = TS[0];
- }
- else
- {
- enum ArgStringOf = TS[0] ~ "," ~ ArgStringOf!(TS[1..$]);
- }
- }
- string combine(string[] types, string[] members)
- {
- assert(types.length == members.length);
- string combined = "";
- for(int i=0; i < (types.length) ; ++i)
- {
- combined ~= types[i] ~ " " ~ members[i] ~ ", ";
- }
- if(combined != "") combined = combined[0..$-2] ; //trim end ", "
- return combined;
- }
- template GenProperty(string M, string N, alias SN)
- {
- enum GenProperty = `
- @property auto ref ` ~ N ~ `(` ~
- combine( StringOf!(PTT!(SN)).split(","),
- ArgStringOf!(PIT!(SN)).split(",") )~ `)
- { return ` ~ M ~ `(` ~ ArgStringOf!(PIT!(SN)) ~ `); }`;
- //pragma(msg, GenProperty);
- }
- string genProperty(string mem, string name, string s_name)
- {
- return `static if ( !__traits(compiles, ` ~ name ~ `) )
- { static if (isCallable!(` ~ s_name ~ `.` ~ name ~ `))
- {
- mixin (GenProperty!( "`~ mem ~`", "`~ name ~`", `~ s_name ~`.`~ name ~`));
- }
- else
- {
- @property auto ref ` ~ name ~ `() { return ` ~ mem ~ `; };
- @property ` ~ name ~ `(typeof(` ~ s_name ~ `.` ~ name ~ `) _` ~ name ~ `)
- { ` ~ mem ~ ` = _` ~ name ~ `; }
- }
- }
- else
- {
- }
- `;
- }
- string getAlias(uint id, string[] members, string s_name)
- {
- string output;
- foreach(m ; members)
- {
- output ~= genProperty("this._s" ~ to!string(id) ~ "." ~ m, m, s_name);
- }
- return output;
- }
- template GenAliases(uint count, U...)
- {
- static if (U.length == 0)
- {
- enum GenAliases = "";
- }
- else
- {
- enum GenAliases = getAlias(count,
- Filter!(__traits(allMembers, U[0]))[0..$-1].split(","),
- U[0].stringof) ~ GenAliases!(1+count, U[1..$]);
- }
- //pragma(msg, GenAliases);
- }
- /*
- struct test2
- {
- int X;
- int sumX(int val) { return (cast(int)(X + val)); }
- }
- */
- //pragma(msg, GenAliases!(0, test1!(int), test2) );
- template Gen(string name, U...)
- {
- static assert(U.length != 0); //otherwise no use for this template
- enum Gen = `struct ` ~ name ~ ` { ` ~ GenStructs!(0, U) ~
- GenAliases!(0, U) ~ ` }`;
- //pragma(msg, Gen);
- }
- //pragma(msg, Gen!("T1", test1!(int)));
- //mixin (Gen!("T1", test1!(int)));
- ////////////////////////////////////////////////////////////
- struct S_A { int x; int y; void func() { x = 2*x; } ; void funcA() { } ; }
- struct S_B { int x; int z; void func() { x = 3*x; } ; void funcB() { } ; }
- void main()
- {
- import std.stdio: writeln;
- mixin (Gen!("S_AB", S_A, S_B));
- pragma(msg, __traits(allMembers, S_AB));
- S_AB s_ab;
- s_ab.x = 10;
- s_ab.func();
- assert(s_ab.x == 20);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement