digitalmars.D - Static map
- Max Samukha (77/77) Nov 12 2008 The problem is to create a generic construct that would allow to map
The problem is to create a generic construct that would allow to map types, literals and other statically available stuff to other types, aliases, etc. I'm sure, Andrei knows a scientific term for it but I'll further abuse 'static' and name the construct StaticMap. My first naive attempt was to use regular mixins: /** Enables aliasing of expressions. */ template Alias(A...) if (A.length = 1) { static if (__traits(compiles, { alias A[0] x; })) alias A[0] Alias; else enum Alias = A[0]; } template StaticMap(A...) { template Parse(B...) { static if (B.length) { static assert (B.length > 1, "No value for key " ~ B[0] ~ " in " ~ A.stringof); static if (is(B[0])) { template Get(Key) if (is(Key == B[0])) { alias Alias!(B[1]) Get; } } else static if (__traits(compiles, { static if(B[0] == B[0]) {} })) { template Get(alias key) if ( B[0] == key ) { alias Alias!(B[1]) Get; } } else { template Get(alias key) if ( __traits(isSame, key, B[0]) ) { alias Alias!(B[1]) Get; } } mixin Parse!(B[2..$]); } } mixin Parse!(A); } alias StaticMap!( int, "type", 2, "two", StaticMap, int ) map; static assert(map.Get!(int) == "type"); static assert(map.Get!(2) == "two"); static assert(is(map.Get!(StaticMap) == int)); ---- But the above doesn't work because the template overloads get mixed in their own scopes and only the outmost is matched. With functions, one can alias the overload into the surrounding scope by using a named mixin like this: template Foo() { void foo(int x) {} ; } void foo() {}; mixin Foo a; alias a.foo foo; // now foo(int) from the mixin overloads foo(); But one can't do the same with overloaded templates. So there are two questions: 1. Is it a bug, unimplemented feature or by design? 2. Is there a way to implement the construct without falling back to string mixins?
Nov 12 2008