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 }