1 module async.container.map;
2 
3 import core.sync.mutex;
4 
5 import std.exception;
6 import std.typecons;
7 import std.traits : isArray;
8 
9 class Map(TKey, TValue)
10 {
11     this()
12     {
13         _lock = new Mutex;
14     }
15 
16     @property bool empty() const
17     {
18         return (_data.length == 0);
19     }
20 
21     @property size_t length() const
22     {
23         return _data.length;
24     }
25 
26     @property size_t opDollar() const
27     {
28         return _data.length;
29     }
30 
31     ref auto opIndex(TKey key)
32     {
33         synchronized (_lock)
34         {
35             if (key !in _data)
36             {
37                 static if (isArray!TValue)
38                 {
39                     _data[key] = [];
40                 }
41                 else
42                 {
43                     return null;
44                 }
45             }
46 
47             return _data[key];
48         }
49     }
50 
51     void opIndexAssign(TValue value, TKey key)
52     {
53         synchronized (_lock)
54         {
55             _data[key] = value;
56         }
57     }
58 
59     @property ref auto front() inout
60     {
61         if (_data.length == 0)
62         {
63             return null;
64         }
65 
66         return _data[_data.keys[0]];
67     }
68 
69     @property ref auto back() inout
70     {
71         if (_data.length == 0)
72         {
73             return null;
74         }
75 
76         return _data[_data.keys[$ - 1]];
77     }
78 
79     int opApply(scope int delegate(ref TValue) dg)
80     {
81         int result = 0;
82 
83         foreach (d; _data)
84         {
85             result = dg(d);
86 
87             if (result)
88             {
89                 break;
90             }
91         }
92 
93         return result;
94     }
95 
96     int opApply(scope int delegate(TKey, ref TValue) dg)
97     {
98         int result = 0;
99 
100         foreach (k, d; _data)
101         {
102             result = dg(k, d);
103 
104             if (result)
105             {
106                 break;
107             }
108         }
109 
110         return result;
111     }
112 
113     @property TKey[] keys()
114     {
115         return _data.keys;
116     }
117 
118     @property TValue[] values()
119     {
120         return _data.values;
121     }
122 
123     bool exists(TKey key)
124     {
125         if (key in _data)
126         {
127             return true;
128         }
129         return false;
130     }
131 
132     void remove(TKey key)
133     {
134         synchronized (_lock)
135         {
136             _data.remove(key);
137         }
138     }
139 
140     void clear()
141     {
142         synchronized (_lock)
143         {
144             _data.clear();
145         }
146     }
147 
148     void lock()
149     {
150         _lock.lock();
151     }
152 
153     void unlock()
154     {
155         _lock.unlock();
156     }
157 
158 private:
159 
160     TValue[TKey] _data;
161     Mutex        _lock;
162 }