1 /* Create classes from their modules and names. 2 * 3 * Copyright: Copyright (C) D Language Foundation 2023 4 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 5 * Authors: Walter Bright, Steven Schveighoffer 6 * Source: $(DRUNTIMESRC core/_factory.d) 7 */ 8 9 module core.factory; 10 11 /** 12 * Create instance of class specified by the module symbol and a string 13 * representing the name of the class. 14 * The class must either have no constructors or have 15 * a default constructor. 16 * Params: 17 * mod = symbol representing the module that the class is in 18 * classname = string representing the name of the class 19 * Returns: 20 * null if failed 21 * Example: 22 * --- 23 * module foo.bar; 24 * 25 * class C 26 * { 27 * this() { x = 10; } 28 * int x; 29 * } 30 * 31 * void main() 32 * { 33 * auto c = cast(C)factory!(foo.bar)("C"); 34 * assert(c !is null && c.x == 10); 35 * } 36 * --- 37 */ 38 Object factory(alias mod)(string classname) 39 { 40 foreach(cl; _getModuleClasses!mod) 41 { 42 if (cl.stringof == classname) 43 return cl.classinfo.create(); 44 } 45 return null; 46 } 47 48 @system unittest 49 { 50 Object valid_obj = factory!object("Object"); 51 Object invalid_obj = factory!object("__this_class_doesnt_exist__"); 52 53 assert(valid_obj !is null); 54 assert(invalid_obj is null); 55 } 56 57 /************************************** 58 * Retrieve as a tuple all the types of the top level classes in the module mod. 59 */ 60 private template _getModuleClasses(alias mod) { 61 alias result = _AliasSeq!(); 62 static foreach(m; __traits(allMembers, mod)) 63 static if(is(__traits(getMember, mod, m) == class)) 64 result = _AliasSeq!(result, __traits(getMember, mod, m)); 65 alias _getModuleClasses = result; 66 } 67 68 private template _AliasSeq(TList...) { alias _AliasSeq = TList; }