digitalmars.D.learn - getting all children classes in program
- Ondra (30/30) Jan 03 2015 Hi,
- Adam D. Ruppe (15/16) Jan 03 2015 The reason is that's technically not a class and doesn't exist at
Hi, how can I get list of all children classes of class in program? I was trying to use ModuleInfo from D Coockbook but this does not work for template classes? ex.: class A{} class B:A{} // ok in ModuleInfo class C(T): B {} // missing in ModuleInfo I am trying to assign every class its unique ID that is same for all instances. Code: int result[string]; int counter = 0; foreach(mod; ModuleInfo) { foreach(cla; mod.localClasses) { auto base = cla.base; while (base) { if (base is T.classinfo) { result[cla.name] = counter; counter++; } base = base.base; } } }
Jan 03 2015
On Saturday, 3 January 2015 at 14:28:07 UTC, Ondra wrote:class C(T): B {} // missing in ModuleInfoThe reason is that's technically not a class and doesn't exist at runtime, it is just a template for one (you can't new that, you'd have to new C!some_actual_type). If you were to add a class D : C!int {} then you'd see class D shows up and has a parent of C!int... however, you're right, C!int doesn't want to show up at all, even if I instantiate it. I'm not sure if there's a way around that other than to add some code in the class to register itself. You could use a static constructor that adds itself to a list. Or, to give each class a shared ID, you could add a static member which returns some variation of its typeinfo. In fact, typeid(any_class) returns a unique identifier for each class (an instance of TypeInfo), maybe you can use it directly.
Jan 03 2015
I'm not sure if there's a way around that other than to add some code in the class to register itself. You could use a static constructor that adds itself to a list. Or, to give each class a shared ID, you could add a static member which returns some variation of its typeinfo. In fact, typeid(any_class) returns a unique identifier for each class (an instance of TypeInfo), maybe you can use it directly.Hi Adam, static this is probably way to go, I wanted to avoid this solution because if it leads to copy-pasting code to every child. I need to have IDs small like 8bits, co I probably can't use typeid... Thank you for answer. Knowing that someting cannot be done is better than spend on this another few hour. Great book btw. Ondra
Jan 03 2015
On Saturday, 3 January 2015 at 15:00:53 UTC, Ondra wrote:Hello, here is another solution: a class ID is generated lazily, when queried It does not recquire a static constructor. ---- module runnable; static string[] IDs; ptrdiff_t getClassID(ClassType)() if (is(ClassType == class)) { import std.algorithm; auto classTypeString = ClassType.stringof; ptrdiff_t result = countUntil(IDs, classTypeString); if (result == -1) { IDs ~= classTypeString; result = IDs.length -1; } return result; } void main(string[] args) { class A{} class B{} class C{} class D{} assert(getClassID!A == 0); assert(getClassID!B == 1); assert(getClassID!C == 2); assert(getClassID!D == 3); assert(getClassID!C == 2); assert(getClassID!B == 1); assert(getClassID!A == 0); } ---- Hoping it matches to your needs.I'm not sure if there's a way around that other than to add some code in the class to register itself. You could use a static constructor that adds itself to a list. Or, to give each class a shared ID, you could add a static member which returns some variation of its typeinfo. In fact, typeid(any_class) returns a unique identifier for each class (an instance of TypeInfo), maybe you can use it directly.Hi Adam, static this is probably way to go, I wanted to avoid this solution because if it leads to copy-pasting code to every child. I need to have IDs small like 8bits, co I probably can't use typeid... Thank you for answer. Knowing that someting cannot be done is better than spend on this another few hour. Great book btw. Ondra
Jan 03 2015
Off Topic ! But in the same way: ------- static string[] IDs; ptrdiff_t getClassID(ClassType, ClassBase)() if ((is(ClassType == class)) && (is(ClassBase == class))) { import std.algorithm; if (!is(ClassType : ClassBase)) return -1; else { auto classTypeString = ClassType.stringof; ptrdiff_t result = countUntil(IDs, classTypeString); if (result == -1) { IDs ~= classTypeString; result = IDs.length -1; } return result; } } void main(string[] args) { class Oops {} class A : Oops{} class B : Oops{} class C : Oops{} class D : Oops{} class E {} assert(getClassID!(A,Oops) == 0); assert(getClassID!(B,Oops) == 1); assert(getClassID!(C,Oops) == 2); assert(getClassID!(D,Oops) == 3); assert(getClassID!(C,Oops) == 2); assert(getClassID!(B,Oops) == 1); assert(getClassID!(A,Oops) == 0); assert(getClassID!(E,Oops) == -1); } -------
Jan 03 2015
Hi Baz & jklp, thank you for ideas I will use your approach for this problem.
Jan 03 2015