1 module symbols; 2 3 class SymbolTable 4 { 5 private size_t[string] table = null; 6 7 private string[] pool = null; 8 9 invariant (table.length == pool.length); 10 11 size_t intern(const(char)[] value) nothrow pure @safe 12 { 13 if (auto id = value in table) 14 return *id; 15 16 size_t id = pool.length; 17 18 pool ~= value.idup; 19 table[pool[id]] = id; 20 return id; 21 } 22 23 @("intern equal strings") 24 unittest 25 { 26 with (new SymbolTable) 27 { 28 assert(intern("foo") == intern("foo")); 29 } 30 } 31 32 @("intern different strings") 33 unittest 34 { 35 with (new SymbolTable) 36 { 37 assert(intern("foo") != intern("bar")); 38 } 39 } 40 41 string symbol(size_t id) @nogc nothrow pure @safe 42 in (id < pool.length) 43 { 44 return pool[id]; 45 } 46 47 @("get interned symbol") 48 unittest 49 { 50 with (new SymbolTable) 51 { 52 assert(symbol(intern("foo")) == "foo"); 53 } 54 } 55 }