1 module mutils.container.hash_map;
2 
3 import std.stdio;
4 import mutils.container.hash_set;
5 
6 struct HashMap(Key, T){
7 	alias KeyType=Key;
8 	alias ValueType=T;
9 
10 	HashSet!(Key, defaultHashFunc, ValueType) set;
11 
12 	void add(Key k, T v){
13 		size_t index=set.getIndex(k);
14 		if(index==set.getIndexEmptyValue){
15 			set.add(k, v);
16 		}else{
17 			size_t group=index/8;
18 			size_t elIndex=index%8;
19 			set.groups[group].values[elIndex]=v;
20 		}
21 	}
22 	
23 	size_t length(){
24 		return set.length;
25 	}
26 
27 	bool tryRemove(Key k){	
28 		return set.tryRemove(k);
29 	}
30 
31 	void remove(Key k){
32 		set.remove(k);
33 	}
34 
35 	bool isIn(Key k){
36 		size_t index=set.getIndex(k);
37 		return index!=set.getIndexEmptyValue;		
38 	}
39 
40 	T get(Key k){
41 		size_t index=set.getIndex(k);
42 		assert(index!=set.getIndexEmptyValue);
43 		size_t group=index/8;
44 		size_t elIndex=index%8;
45 		return set.groups[group].values[elIndex];
46 
47 	}
48 
49 	T getDefault(Key k, T defaultValue){
50 		size_t index=set.getIndex(k);
51 		if(index==set.getIndexEmptyValue){
52 			return defaultValue;
53 		}else{
54 			size_t group=index/8;
55 			size_t elIndex=index%8;
56 			return set.groups[group].values[elIndex];
57 		}
58 		
59 	}
60 
61 	T getInsertDefault(Key k, T defaultValue){		
62 		size_t index=set.getIndex(k);
63 		if(index==set.getIndexEmptyValue){
64 			set.add(k, defaultValue);
65 			return defaultValue;
66 		}else{
67 			size_t group=index/8;
68 			size_t elIndex=index%8;
69 			return set.groups[group].values[elIndex];
70 		}		
71 	}
72 
73 	int byKey(scope int delegate(KeyType k) dg){
74 		int result;
75 		foreach(ref KeyType k;set){
76 			result=dg(k);
77 			if (result)
78 				break;	
79 		}
80 		return result;		
81 	}
82 
83 	int byValue(scope int delegate(ref T k) dg){
84 		int result;
85 		foreach(ref Control c, ref KeyType k, ref ValueType v; set){
86 			result=dg(v);
87 			if (result)
88 				break;	
89 		}
90 		return result;		
91 	}
92 
93 	int byKeyValue(scope int delegate(ref KeyType k, ref ValueType k) dg){
94 		int result;
95 		foreach(ref Control c, ref KeyType k, ref ValueType v; set){
96 			result=dg(k, v);
97 			if (result)
98 				break;	
99 		}
100 		return result;		
101 	}
102 
103 	import std.format:FormatSpec,formatValue;
104 	/**
105 	 * Preety print
106 	 */
107 	void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)
108 	{
109 		formatValue(sink, '[', fmt);
110 		foreach(ref k, ref v; &byKeyValue){
111 			formatValue(sink, k, fmt);
112 			formatValue(sink, ':', fmt);
113 			formatValue(sink, v, fmt);
114 			formatValue(sink, ", ", fmt);
115 		}
116 		formatValue(sink, ']', fmt);
117 	}
118 }
119 
120 unittest{
121 	HashMap!(int, int) map;
122 	map.add(1, 10);
123 	assert(map.get(1)==10);
124 	assert(map.getDefault(2, 20)==20);
125 	assert(!map.isIn(2));
126 	assert(map.getInsertDefault(2, 20)==20);
127 	assert(map.get(2)==20);
128 	foreach(k; &map.byKey){}
129 	foreach(k, v; &map.byKeyValue){}
130 	foreach(v; &map.byValue){}
131 
132 }