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 }