1 module mutils.container.ct_map; 2 3 4 import std.traits; 5 import std.meta; 6 7 import mutils.meta; 8 9 10 11 12 13 14 struct CTMap(ElementsPar...){ 15 static assert(ElementsPar.length%2==0); 16 alias Elements=ElementsPar; 17 18 struct KeyValue(alias KeyPar, alias ValPar){ 19 alias key=KeyPar; 20 alias value=ValPar; 21 } 22 struct KeyValue(alias KeyPar, ValPar){ 23 alias key=KeyPar; 24 alias value=ValPar; 25 } 26 struct KeyValue(KeyPar, alias ValPar){ 27 alias key=KeyPar; 28 alias value=ValPar; 29 } 30 31 template getValues(){ 32 alias getValues=removeEven!Elements; 33 } 34 35 template getKeys(){ 36 alias getKeys=removeOdd!Elements; 37 } 38 39 template getValueType(){ 40 static assert(valuesHaveSameType); 41 alias getValueType=typeof(Elements[1]); 42 } 43 44 template getKeyType(){ 45 static assert(keysHaveSameType); 46 alias getKeyType=typeof(Elements[0]); 47 } 48 49 50 static bool valuesAreValueType(){ 51 return allSatisfy!(isExpressions, getValues!()); 52 } 53 54 static bool keysAreValueType(){ 55 return allSatisfy!(isExpressions, getKeys!()); 56 } 57 58 static bool valuesHaveSameType(){ 59 static if(keysAreValueType){ 60 alias Types=staticMap!(getType, getValues!()); 61 return NoDuplicates!(Types).length==1; 62 }else{ 63 return false; 64 } 65 } 66 67 static bool keysHaveSameType(){ 68 static if(keysAreValueType){ 69 alias Types=staticMap!(getType, getKeys!()); 70 return NoDuplicates!(Types).length==1; 71 }else{ 72 return false; 73 } 74 } 75 76 77 template getImpl(){ 78 auto getImpl(){ 79 foreach(i,Key;Elements){ 80 static if(i%2==0 && 81 ( 82 (__traits(compiles,T==Key) && T==Key) || 83 (__traits(compiles,is(T==Key)) && is(T==Key)) 84 ) 85 86 ){//even elements are keys 87 struct Returner{ 88 static if(isExpressions!(Elements[i+1])){ 89 enum value=Elements[i+1]; 90 }else{ 91 alias value=Elements[i+1]; 92 } 93 } 94 Returner ret; 95 return ret; 96 } 97 98 } 99 } 100 101 } 102 103 static auto get(T)(){ 104 mixin getImpl; 105 return getImpl(); 106 } 107 108 static auto get(alias T)(){ 109 mixin getImpl; 110 return getImpl(); 111 } 112 113 //static if(valuesHaveSameType && keysHaveSameType){ 114 alias byKeyValue=toKeyValue!(Elements); 115 //} 116 117 private template toKeyValue(Arr...){ 118 static if(Arr.length>2){ 119 alias toKeyValue=AliasSeq!(KeyValue!(Arr[0], Arr[1]), toKeyValue!(Arr[2..$])); 120 }else static if(Arr.length==2){ 121 alias toKeyValue=AliasSeq!(KeyValue!(Arr[0], Arr[1])); 122 }else{ 123 alias toKeyValue=AliasSeq!(); 124 } 125 } 126 127 128 } 129 130 131 unittest{ 132 alias myMap=CTMap!( 133 6,int, 134 long, 12, 135 18,23 136 ); 137 138 static assert(is(myMap.get!(6).value==int)); 139 static assert(myMap.get!(long).value==12); 140 static assert(myMap.get!(18).value==23); 141 static assert(!myMap.keysAreValueType); 142 static assert(!myMap.valuesAreValueType); 143 } 144 145 unittest{ 146 alias myMap=CTMap!( 147 "str1",8, 148 "str2", 12, 149 "str3",23 150 ); 151 152 static assert(myMap.keysAreValueType); 153 static assert(myMap.valuesAreValueType); 154 static assert(myMap.keysHaveSameType); 155 static assert(myMap.valuesHaveSameType); 156 static assert(is(myMap.getValueType!()==int)); 157 static assert(is(myMap.getKeyType!()==string)); 158 159 } 160 161 162 163 unittest{ 164 alias myMap=CTMap!( 165 "str1",8, 166 "str2", 12, 167 "str3",23 168 ); 169 170 171 int runtimeLookUp(string var){ 172 switch(var){ 173 foreach(keyValue;myMap.byKeyValue){ 174 case keyValue.key: 175 return keyValue.value; 176 } 177 default: 178 return 0; 179 } 180 } 181 assert(runtimeLookUp("str0")==0); 182 assert(runtimeLookUp("str1")==8); 183 assert(runtimeLookUp("str2")==12); 184 assert(runtimeLookUp("str3")==23); 185 assert(runtimeLookUp("str4")==0); 186 }