Skip to content

Instantly share code, notes, and snippets.

@AndrejMitrovic
Created October 1, 2016 15:42
Show Gist options
  • Save AndrejMitrovic/5479e8241b7c67aa383869ba00c6a2a3 to your computer and use it in GitHub Desktop.
Save AndrejMitrovic/5479e8241b7c67aa383869ba00c6a2a3 to your computer and use it in GitHub Desktop.
module forward_ctors;
import std.string;
import std.typecons;
import std.traits;
import std.exception;
private string stcToString(uint stc) // bug: can't use ParameterStorageClass type
{
string[] result;
if (stc & ParameterStorageClass.scope_)
result ~= "scope";
if (stc & ParameterStorageClass.out_)
result ~= "out";
if (stc & ParameterStorageClass.ref_)
result ~= "ref";
if (stc & ParameterStorageClass.lazy_)
result ~= "lazy";
return result.join(" ");
}
private @property Tuple!(string, string) getParams(alias func)()
{
string[] params;
string[] args;
alias ParameterStorageClassTuple!func STCFunc;
foreach (idx, param; ParameterTypeTuple!func)
{
string arg = xformat("_arg%s", idx);
params ~= xformat("%s %s %s", stcToString(STCFunc[idx]), param.stringof, arg);
args ~= arg;
}
return tuple(params.join(", "), args.join(", "));
}
private @property string ForwardCtorsImpl(T)()
{
string result;
foreach (Ctor; __traits(getOverloads, T, "__ctor"))
{
auto res = getParams!Ctor;
result ~= xformat("this(%s) { super(%s); }\n", res[0], res[1]);
}
return result;
}
mixin template ForwardCtors()
{
mixin(ForwardCtorsImpl!(typeof(this))());
}
class Foo
{
this(ref int x) { }
this(out float x) { }
this(lazy string x) { }
this(scope int[] x) { }
this(float[] z) { }
}
class Bar : Foo
{
mixin ForwardCtors;
}
class MyEx : Exception
{
mixin ForwardCtors;
}
void main()
{
int a;
float b;
string c;
int[] d;
float[] e;
auto b1 = new Bar(a);
auto b2 = new Bar(b);
auto b3 = new Bar(c);
auto b4 = new Bar(d);
auto b5 = new Bar(e);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment