Thread overview
indexing stuff during compile time
Dec 23, 2017
Eric
Dec 24, 2017
Eric
Dec 24, 2017
Eric
Dec 24, 2017
Eric
December 23, 2017
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);
}


December 24, 2017
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++;
  }
}



December 24, 2017
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;
}


December 24, 2017
> 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;
}