1 module reggae.ctaa; 2 3 /** 4 An implementation of an associative array useable at compile-time. 5 Shameless copy of association lists from Lisp. 6 */ 7 8 9 @safe: 10 11 12 struct AssocList(K, V) { 13 import std.algorithm: find; 14 import std.array: empty, front; 15 16 AssocEntry!(K, V)[] entries; 17 18 const(V) opIndex(in K key) pure const nothrow { 19 auto res = entries.find!(a => a.key == key); 20 assert(!res.empty, "AssocList does not contain key " ~ key); 21 return res.front.value; 22 } 23 24 T get(T)(in K key, T defaultValue) pure const { 25 import std.conv: to; 26 auto res = entries.find!(a => a.key == key); 27 return res.empty ? defaultValue : res.front.value.to!T; 28 } 29 30 const(K)[] keys() pure const nothrow { 31 import std.algorithm: map; 32 import std.array: array; 33 return entries.map!(a => a.key).array; 34 } 35 } 36 37 struct AssocEntry(K, V) { 38 K key; 39 V value; 40 } 41 42 43 AssocEntry!(K, V) assocEntry(K, V)(K key, V value) { 44 return AssocEntry!(K, V)(key, value); 45 } 46 47 AssocList!(K, V) assocList(K, V)(AssocEntry!(K, V)[] entries = []) { 48 return AssocList!(K, V)(entries); 49 } 50 51 auto assocListT(T...)(T args) if(T.length % 2 == 0 && T.length > 0) { 52 alias K = T[0]; 53 alias V = T[1]; 54 AssocEntry!(K, V)[] entries; 55 foreach(i, elt; args) { 56 static if(i % 2 == 0) entries ~= assocEntry(args[i], args[i+1]); 57 } 58 return AssocList!(K, V)(entries); 59 }