www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template unique IDs per type

reply "Roderick Gibson" <kniteli gmail.com> writes:
I was recently looking up how to assign a unique ID based on each
different implementation of a templated type (NOT per instance,
but per unique type). For example:

class MyTemplate(T) {
      //the ? where the actual number would go
      const int type_id = ?;
}

void main() {
      auto a = new MyTemplate!(int)(); //a.type_id = 0
      auto b = new MyTemplate!(string)(); //b.type = 1
      auto c = new MyTemplate!(int)(); //c.type_id = 0
      auto d = new MyTemplate!(double)();//d.type_id = 2
}

There's some solutions to this sort of thing at this
stackoverflow question in c++ which are possible at run-time:

http://stackoverflow.com/questions/8596490/counting-with-template-metaprogramming

BUT I was wondering with CTFE and/or mixins would it be possible
to do this at compile time?
Jul 11 2013
next sibling parent reply "JS" <js.mdnq gmail.com> writes:
On Friday, 12 July 2013 at 03:15:46 UTC, Roderick Gibson wrote:
 I was recently looking up how to assign a unique ID based on 
 each
 different implementation of a templated type (NOT per instance,
 but per unique type). For example:

 class MyTemplate(T) {
      //the ? where the actual number would go
      const int type_id = ?;
 }

 void main() {
      auto a = new MyTemplate!(int)(); //a.type_id = 0
      auto b = new MyTemplate!(string)(); //b.type = 1
      auto c = new MyTemplate!(int)(); //c.type_id = 0
      auto d = new MyTemplate!(double)();//d.type_id = 2
 }

 There's some solutions to this sort of thing at this
 stackoverflow question in c++ which are possible at run-time:

 http://stackoverflow.com/questions/8596490/counting-with-template-metaprogramming

 BUT I was wondering with CTFE and/or mixins would it be possible
 to do this at compile time?
sure, each type name is unique. All you have to do is convert them to an int... use a hash or some other method or just use the string names. If you need the id's to be continuous try to use an set(array) of the type names. Not sure if the last method works well with ctfe's though.
Jul 11 2013
parent "Roderick Gibson" <kniteli gmail.com> writes:
On Friday, 12 July 2013 at 03:56:50 UTC, JS wrote:
 sure, each type name is unique. All you have to do is convert 
 them to an int... use a hash or some other method or just use 
 the string names. If you need the id's to be continuous try to 
 use an set(array) of the type names. Not sure if the last 
 method works well with ctfe's though.
Hmm, I think in my case I may need them to be sequential from 0 (though order doesn't matter). I'm beginning to think it just isn't possible, as there is no way to store state during compilation, and thus no way to "count" how far along we are in ids. I'm not sure what you mean by "try to us an set(array) of type names".
Jul 11 2013
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, July 12, 2013 05:15:43 Roderick Gibson wrote:
 I was recently looking up how to assign a unique ID based on each
 different implementation of a templated type (NOT per instance,
 but per unique type). For example:
 
 class MyTemplate(T) {
       //the ? where the actual number would go
       const int type_id = ?;
 }
 
 void main() {
       auto a = new MyTemplate!(int)(); //a.type_id = 0
       auto b = new MyTemplate!(string)(); //b.type = 1
       auto c = new MyTemplate!(int)(); //c.type_id = 0
       auto d = new MyTemplate!(double)();//d.type_id = 2
 }
 
 There's some solutions to this sort of thing at this
 stackoverflow question in c++ which are possible at run-time:
 
 http://stackoverflow.com/questions/8596490/counting-with-template-metaprogra
 mming
 
 BUT I was wondering with CTFE and/or mixins would it be possible
 to do this at compile time?
You can't have any kind of global mutable state in CTFE, so there's no way for different template instantiations to share data like that. You could generate IDs based on the types (e.g. a hash) and get different values that way (though it might be tricky to do that in a way that would guarantee no collisions), but if you want some kind of incrementing ID across them, I think that you're stuck with a runtime solution. Now, it's probably possible to use static constructors to use global mutable state to intialize all of those IDs when the program starts up, which would initialize the IDs to incrementing values, so they could be immutable if you wanted, but that would still be at runtime. - Jonathan M Davis
Jul 11 2013
next sibling parent "Roderick Gibson" <kniteli gmail.com> writes:
On Friday, 12 July 2013 at 04:42:28 UTC, Jonathan M Davis wrote:
 On Friday, July 12, 2013 05:15:43 Roderick Gibson wrote:
 I was recently looking up how to assign a unique ID based on 
 each
 different implementation of a templated type (NOT per instance,
 but per unique type). For example:
 
 class MyTemplate(T) {
       //the ? where the actual number would go
       const int type_id = ?;
 }
 
 void main() {
       auto a = new MyTemplate!(int)(); //a.type_id = 0
       auto b = new MyTemplate!(string)(); //b.type = 1
       auto c = new MyTemplate!(int)(); //c.type_id = 0
       auto d = new MyTemplate!(double)();//d.type_id = 2
 }
 
 There's some solutions to this sort of thing at this
 stackoverflow question in c++ which are possible at run-time:
 
 http://stackoverflow.com/questions/8596490/counting-with-template-metaprogra
 mming
 
 BUT I was wondering with CTFE and/or mixins would it be 
 possible
 to do this at compile time?
You can't have any kind of global mutable state in CTFE, so there's no way for different template instantiations to share data like that. You could generate IDs based on the types (e.g. a hash) and get different values that way (though it might be tricky to do that in a way that would guarantee no collisions), but if you want some kind of incrementing ID across them, I think that you're stuck with a runtime solution. Now, it's probably possible to use static constructors to use global mutable state to intialize all of those IDs when the program starts up, which would initialize the IDs to incrementing values, so they could be immutable if you wanted, but that would still be at runtime. - Jonathan M Davis
Hmm, I'll look into the static constructors, as that sounds like a fairly ideal solution anyway. I was more just curious to see if the problem was solvable in D at compile time (as it seems to be a fairly common request in C++).
Jul 11 2013
prev sibling parent "Roderick Gibson" <kniteli gmail.com> writes:
On Friday, 12 July 2013 at 04:42:28 UTC, Jonathan M Davis wrote:
 Now, it's probably possible to use static constructors to use 
 global mutable
 state to intialize all of those IDs when the program starts up, 
 which would
 initialize the IDs to incrementing values, so they could be 
 immutable if you
 wanted, but that would still be at runtime.

 - Jonathan M Davis
As a follow up, here's what it looks like, and it works perfectly: alias size_t component_type; class Component(T) : BaseComponent { static immutable component_type component_type_id; static this() { component_type_id = component_type_counter++; } } class BaseComponent { static component_type component_type_counter; }
Jul 11 2013