Define "createXXX" functions for the constructors of class XXX
Chris Wright via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Jan 23 12:54:50 PST 2016
On Sat, 23 Jan 2016 19:42:29 +0000, Johan Engelen wrote:
> // Somehow define these guys automatically, "genCreateCtors!(XXX)" ?
> XXX createXXX(int a, int b) { return new XXX(a, b); }
> XXX createXXX(bool flag) { return new XXX(flag); }
Check out http://dpaste.dzfl.pl/430dabf25935
I used string mixins to be absolutely, 100% sure that the right things
ended up in the symbol table.
__traits(getOverloads, Type, "name") gets function overloads for the
given name. It gets them as an AliasSeq, which presents an array-like
interface.
Constructors use the name "__ctor". So you can get all constructors for a
class named MyClass with:
__traits(getOverloads, MyClass, "__ctor")
This only includes explicitly defined constructors, not the default
constructor, so we handle that separately.
std.traits defines a Parameters template that takes a function and yields
a parameter type tuple. We can hand it a constructor and it does the
right thing. We can treat a bunch of values as one value if their type is
a type tuple, so that's exactly what we do.
Then it's just a bit of string manipulation to get the right class names
and overloads in the right places and we've generated a string of D code
that does what we want. Mix it in and Bob's your uncle.
In your code, the line
mixin(factory!MyClass);
should be inside an extern(C++) block, naturally.
The major caveat there: wherever you call "mixin(factory!MyClass);", you
need MyClass to be in scope directly. If you have to refer to it with a
qualified name, this will break. If that causes problems for you, you can
use:
extern(C++) {
{
import mypkg.mymodule : MyClass;
mixin(factory!MyClass);
}
}
And that should import just that class for just that one block of code.
More information about the Digitalmars-d-learn
mailing list