www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to implement this?

reply "Elvis" <nospam pureworld.com> writes:
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
next sibling parent Benjamin Thaut <code benjamin-thaut.de> writes:
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
prev sibling parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
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
parent reply "Elvis" <nospam pureworld.com> writes:
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:
 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
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.
Jun 11 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
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
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.
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.
Jun 11 2013