1 module mango_stl.collections;
2 
3 import mango_stl.exception;
4 
5 import std.exception;
6 import std.algorithm;
7 import std.conv;
8 
9 private alias algorithm_remove = std.algorithm.remove;
10 
11 class ArrayList(T) {
12 	shared {
13 		protected T[] values;
14 	}
15 	
16 	void reserve(size_t amount) @trusted {
17 	    synchronized(this) {
18 	        values.reserve(amount);
19 	    }
20 	}
21 	
22 	void add(T val) @trusted {
23 		synchronized(this) {
24 			values ~= cast(shared) val;
25 		}
26 	}
27 	
28 	void remove(size_t location) @trusted {
29 		synchronized(this) {
30 			this.values = algorithm_remove(values, location);
31 		}
32 	}
33 	
34 	void clear() @trusted {
35 		synchronized(this) {
36 			values.length = 0;
37 		}
38 	}
39 	
40 	void debugDump() {
41 		import std.stdio;
42 		writeln("Dump: ", values);
43 	}
44 }
45 
46 class Queue(T) {
47     shared {
48         protected size_t valueCounter = 0;
49         protected T[size_t] values;
50         
51         protected size_t head = 0;
52     }
53 
54     void add(T val) @trusted {
55         import core.atomic : atomicOp;
56         synchronized(this) {
57             values[atomicOp!"+="(this.valueCounter, 1)] = cast(shared) val;
58         }
59     }
60 
61     void clear() @trusted {
62         synchronized(this) {
63             head = 0;
64             valueCounter = 0;
65             values.clear();
66         }
67     }
68 
69     T pop() @trusted {
70         synchronized(this) {
71             enforce(!isEmpty(), new Exception("Queue is empty!"));
72 
73             auto val = values[head];
74             values.remove(head);
75             head = head + 1;
76             return cast(T) val;
77         }
78     }
79     
80     bool isEmpty() {
81 	    synchronized(this) {
82     	    return values.length <= 0;
83         }
84     }
85 	
86 	void debugDump() {
87 		import std.stdio;
88 		writeln("Head: ", head, ", ", valueCounter, ", Values: ", cast(T[size_t]) values);
89 	}
90 }
91 
92 class UnsafeQueue(T) {
93     shared {
94         protected size_t valueCounter = 0;
95         protected T[size_t] values;
96         
97         protected size_t head = 0;
98     }
99 
100     void add(T val) @trusted nothrow {
101         import core.atomic : atomicOp;
102         values[atomicOp!"+="(this.valueCounter, 1)] = cast(shared) val;
103     }
104 
105     void clear() @trusted nothrow {
106         head = 0;
107         valueCounter = 0;
108         values.clear();
109     }
110 
111     T pop() @trusted nothrow {
112         auto val = values[head];
113 		values.remove(head);
114         head = head + 1;
115         return cast(T) val;
116     }
117     
118     bool isEmpty() @trusted nothrow {
119     	return values.length <= 0;
120     }
121 }