www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - indexing stuff during compile time

reply Eric <nil example.com> writes:
I am trying to build a string->int dictionary at compile time.
The ints are unique and must not be greater than the number of 
unique strings.
So, they are sequential for each string that is not yet indexed.

Example:

size_t idx1 = nameToIndex!"blah";  // 0
size_t idx2 = nameToIndex!"blah2"; // 1
size_t idx3 = nameToIndex!"blah";  // 0
size_t idx4 = nameToIndex!"blah3"; // 2


So, you need to keep a static nextFreeIndex somewhere,
but the problem is that you can't use static vars during compile 
time.

Any ideas how to work around this?




FWISW, here's some code.
I am actually trying to map a combination of types to an index:

struct A {}
struct B {}


void test() {
   writeln("a  : " ~ groupIndex!(A).tostr);   // 0
   writeln("b  : " ~ groupIndex!(B).tostr);   // 1
   writeln("ab : " ~ groupIndex!(A,B).tostr); // 2
}


auto groupIndex(Ts...)() {
   enum n = groupName!Ts();
   enum idx = nameToIdx(n);
   return idx;
}




// get or associate new index with the name
size_t nameToIdx(string n) {
   static size_t[string] name2idx;
   static size_t s_nextIdx = 0;

   size_t* idx = n in name2idx;
   if (!idx) {
     name2idx[n] = s_nextIdx++;
     return s_nextIdx-1;
   }
   else return *idx;
}

// different attempt, but same problem:
//size_t nameToIdx(string n)() {
//  mixin("static struct _"~n ~ "{ static int id;}");
//  return mixin("_"~n~".id");
//}


string groupName(Ts...)() {
   string n;
   foreach(t; Ts) {
      n = n ~ t.stringof;
   }
   return n;
}

string tostr(T)(T t) {
     import std.conv;
     return to!string(t);
}
Dec 23 2017
parent reply Eric <nil example.com> writes:
Forgot to mention that I also want groupIndex!(A,B) == 
groupIndex!(B,A)
Which I wanted to do by sorting the names.

If that requirement wasn't there it would be as simple as:


auto groupIndex(Ts...)() {
   return GroupId!Ts.id;
}


size_t s_nextIdx=1;

struct GroupId(Ts ...) {
   static size_t id;

   static this() {
     id = s_nextIdx++;
   }
}
Dec 24 2017
parent reply Eric <nil example.com> writes:
Ok, solved. It appears you can sort tuples.

I am just a bit confused why I had to use tuple() while the doc 
for staticSort states it works on AliasSeq.

auto groupIndex(Ts...)() {
	import std.meta;
	enum Comp(alias N1, alias N2) = { __traits(identifier, 
typeof(N1)) < __traits(identifier, typeof(N2))};
	enum t = tuple!(Ts);
	enum sorted = staticSort!(Comp, t);
	return GroupId!sorted.id;
}
Dec 24 2017
parent Eric <nil example.com> writes:
 I am just a bit confused why I had to use tuple() while the doc
Because of the enum, that code was full of errors :/ Got it now: auto groupIndex(Ts...)() { import std.meta; import std.algorithm.comparison : cmp, strcmp = cmp; enum Comp(N1, N2) = strcmp(N1.stringof, N2.stringof); alias sorted = staticSort!(Comp, Ts); return GroupId!sorted.id; }
Dec 24 2017