| /* 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; } |