digitalmars.D.learn - How to implement this?
- Elvis (19/19) Jun 10 2013 class A
- Benjamin Thaut (16/35) Jun 10 2013 Thats not possible due to the compilation model. You can however do:
- Kenji Hara (49/68) Jun 10 2013 version(A)
- Elvis (5/78) Jun 11 2013 Thank you, however both versions are not applicable, you need
- H. S. Teoh (11/96) Jun 11 2013 The problem is, when you have separate compilation, how would the
class A { enum TypeID = 1; } class B : A { enum TypeID = 2; } class C : A { enum TypeID = 3; } class D : B { enum TypeID = 4; } ... Could anybody shed some light on how to make these TypeIDs auto increment at compile time?
Jun 10 2013
Am 10/06/2013 11:42, schrieb Elvis:class A { enum TypeID = 1; } class B : A { enum TypeID = 2; } class C : A { enum TypeID = 3; } class D : B { enum TypeID = 4; } ... Could anybody shed some light on how to make these TypeIDs auto increment at compile time?Thats not possible due to the compilation model. You can however do: alias TypeTuple!(A, B, C, D) list; class A { enum TypeID = staticIndexOf!(typeof(this), list); } class B { enum TypeID = staticIndexOf!(typeof(this), list); } Further you could write yoruself a helper template which calls staticIndexOf and does a static assert in case it returns -1 (type not found). Kind Regards Benjamin Thaut
Jun 10 2013
On Monday, 10 June 2013 at 09:42:56 UTC, Elvis wrote:class A { enum TypeID = 1; } class B : A { enum TypeID = 2; } class C : A { enum TypeID = 3; } class D : B { enum TypeID = 4; } ... Could anybody shed some light on how to make these TypeIDs auto increment at compile time?version(A) { class A { enum TypeID = 1; } template IncrementTypeID(Class) { class IncrementTypeID : Class { enum TypeID = Class.TypeID + 1; } } alias B = IncrementTypeID!A; alias C = IncrementTypeID!B; alias D = IncrementTypeID!C; } version(B) // more generative way { template MakeContinuousClasses(int endID) { static if (endID > 0) { mixin MakeContinuousClasses!(endID - 1); enum className = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 1]; static if (endID == 1) enum baseClass = ""; else enum baseClass = " : " ~ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 2]; import std.conv : to; mixin("class "~className~baseClass~" { enum TypeID = "~endID.to!string~"; }"); } } mixin MakeContinuousClasses!4; } // test case import std.traits; pragma(msg, A.TypeID, ", ", BaseClassesTuple!A); // 1, (Object) pragma(msg, B.TypeID, ", ", BaseClassesTuple!B); // 2, (A, Object) pragma(msg, C.TypeID, ", ", BaseClassesTuple!C); // 3, (B, A, Object) pragma(msg, D.TypeID, ", ", BaseClassesTuple!D); // 4, (C, B, A, Object) Kenji Hara
Jun 10 2013
On Monday, 10 June 2013 at 14:40:05 UTC, Kenji Hara wrote:On Monday, 10 June 2013 at 09:42:56 UTC, Elvis wrote:Thank you, however both versions are not applicable, you need give them some type of orders manully in version A while class names are suppose to be more generic in real project other than just A to Z in version B.class A { enum TypeID = 1; } class B : A { enum TypeID = 2; } class C : A { enum TypeID = 3; } class D : B { enum TypeID = 4; } ... Could anybody shed some light on how to make these TypeIDs auto increment at compile time?version(A) { class A { enum TypeID = 1; } template IncrementTypeID(Class) { class IncrementTypeID : Class { enum TypeID = Class.TypeID + 1; } } alias B = IncrementTypeID!A; alias C = IncrementTypeID!B; alias D = IncrementTypeID!C; } version(B) // more generative way { template MakeContinuousClasses(int endID) { static if (endID > 0) { mixin MakeContinuousClasses!(endID - 1); enum className = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 1]; static if (endID == 1) enum baseClass = ""; else enum baseClass = " : " ~ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 2]; import std.conv : to; mixin("class "~className~baseClass~" { enum TypeID = "~endID.to!string~"; }"); } } mixin MakeContinuousClasses!4; } // test case import std.traits; pragma(msg, A.TypeID, ", ", BaseClassesTuple!A); // 1, (Object) pragma(msg, B.TypeID, ", ", BaseClassesTuple!B); // 2, (A, Object) pragma(msg, C.TypeID, ", ", BaseClassesTuple!C); // 3, (B, A, Object) pragma(msg, D.TypeID, ", ", BaseClassesTuple!D); // 4, (C, B, A, Object) Kenji Hara
Jun 11 2013
On Tue, Jun 11, 2013 at 02:34:37PM +0200, Elvis wrote:On Monday, 10 June 2013 at 14:40:05 UTC, Kenji Hara wrote:The problem is, when you have separate compilation, how would the compiler know what order to assign the classes? If I define 10 classes in file1.d and 10 classes in file2.d, and they are compiled separately, then the compiler has to way to know what numbers to assign each class. (Remember that compile separately means the compiler never gets to see file1.d and file2.d at the same time, so it can't know how to apply any ordering to the classes defined therein.) T -- Help a man when he is in trouble and he will remember you when he is in trouble again.On Monday, 10 June 2013 at 09:42:56 UTC, Elvis wrote:Thank you, however both versions are not applicable, you need give them some type of orders manully in version A while class names are suppose to be more generic in real project other than just A to Z in version B.class A { enum TypeID = 1; } class B : A { enum TypeID = 2; } class C : A { enum TypeID = 3; } class D : B { enum TypeID = 4; } ... Could anybody shed some light on how to make these TypeIDs auto increment at compile time?version(A) { class A { enum TypeID = 1; } template IncrementTypeID(Class) { class IncrementTypeID : Class { enum TypeID = Class.TypeID + 1; } } alias B = IncrementTypeID!A; alias C = IncrementTypeID!B; alias D = IncrementTypeID!C; } version(B) // more generative way { template MakeContinuousClasses(int endID) { static if (endID > 0) { mixin MakeContinuousClasses!(endID - 1); enum className = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 1]; static if (endID == 1) enum baseClass = ""; else enum baseClass = " : " ~ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[endID - 2]; import std.conv : to; mixin("class "~className~baseClass~" { enum TypeID = "~endID.to!string~"; }"); } } mixin MakeContinuousClasses!4; } // test case import std.traits; pragma(msg, A.TypeID, ", ", BaseClassesTuple!A); // 1, (Object) pragma(msg, B.TypeID, ", ", BaseClassesTuple!B); // 2, (A, Object) pragma(msg, C.TypeID, ", ", BaseClassesTuple!C); // 3, (B, A, Object) pragma(msg, D.TypeID, ", ", BaseClassesTuple!D); // 4, (C, B, A, Object) Kenji Hara
Jun 11 2013