/* Create classes from their modules and names. * * Copyright: Copyright (C) D Language Foundation 2023 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Authors: Walter Bright, Steven Schveighoffer * Source: $(DRUNTIMESRC core/_factory.d) */ module core.factory; /** * Create instance of class specified by the module symbol and a string * representing the name of the class. * The class must either have no constructors or have * a default constructor. * Params: * mod = symbol representing the module that the class is in * classname = string representing the name of the class * Returns: * null if failed * Example: * --- * module foo.bar; * * class C * { * this() { x = 10; } * int x; * } * * void main() * { * auto c = cast(C)factory!(foo.bar)("C"); * assert(c !is null && c.x == 10); * } * --- */ Object factory(alias mod)(string classname) { foreach(cl; _getModuleClasses!mod) { if (cl.stringof == classname) return cl.classinfo.create(); } return null; } @system unittest { Object valid_obj = factory!object("Object"); Object invalid_obj = factory!object("__this_class_doesnt_exist__"); assert(valid_obj !is null); assert(invalid_obj is null); } /************************************** * Retrieve as a tuple all the types of the top level classes in the module mod. */ private template _getModuleClasses(alias mod) { alias result = _AliasSeq!(); static foreach(m; __traits(allMembers, mod)) static if(is(__traits(getMember, mod, m) == class)) result = _AliasSeq!(result, __traits(getMember, mod, m)); alias _getModuleClasses = result; } private template _AliasSeq(TList...) { alias _AliasSeq = TList; }