1 /**
2 Dynamic Variant array.
3 
4 Copyright:
5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.  
6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)  
7 Copyright (c) 2017-2018 Godot-D contributors  
8 
9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License)
10 
11 
12 */
13 module godot.core.array;
14 
15 import godot.c;
16 import godot.core.variant;
17 import godot.core.poolarrays;
18 
19 /**
20 Generic array, contains several elements of any type, accessible by numerical index starting at 0. Negative indices can be used to count from the right, like in Python. Arrays are always passed by reference.
21 */
22 struct Array
23 {
24 	int opApply(int delegate(size_t, ref Variant) dg)
25 	{
26 		foreach(i; 0..length)
27 		{
28 			Variant* v = cast(Variant*)&(this[i]);
29 			int res = dg(cast(size_t)i, *v);
30 			if(res) return res;
31 		}
32 		return 0;
33 	}
34 	
35 	int opApply(int delegate(size_t, const(Variant)) dg) const
36 	{
37 		foreach(i; 0..length)
38 		{
39 			int res = dg(cast(size_t)i, this[i]);
40 			if(res) return res;
41 		}
42 		return 0;
43 	}
44 	
45 	int opApply(int delegate(ref Variant) dg)
46 	{
47 		foreach(i; 0..length)
48 		{
49 			Variant* v = cast(Variant*)&(this[i]);
50 			int res = dg(*v);
51 			if(res) return res;
52 		}
53 		return 0;
54 	}
55 	
56 	int opApply(int delegate(const(Variant)) dg) const
57 	{
58 		foreach(i; 0..length)
59 		{
60 			int res = dg(this[i]);
61 			if(res) return res;
62 		}
63 		return 0;
64 	}
65 	
66 	
67 	@nogc nothrow:
68 	
69 	package(godot) godot_array _godot_array;
70 	
71 	@disable this();
72 	
73 	this(this)
74 	{
75 		const godot_array tmp = _godot_array;
76 		_godot_api.godot_array_new_copy(&_godot_array, &tmp);
77 	}
78 	
79 	Array opAssign(in Array other)
80 	{
81 		_godot_api.godot_array_destroy(&_godot_array);
82 		_godot_api.godot_array_new_copy(&_godot_array, &other._godot_array);
83 		return this;
84 	}
85 	
86 	/++
87 	Assigning null empties the Array variable, but unlike `clear`, does not
88 	destroy the original memory unless it was the only remaining reference.
89 	
90 	Equivalent to assigning empty_array.
91 	+/
92 	Array opAssign(in typeof(null) n)
93 	{
94 		return opAssign(empty_array);
95 	}
96 	
97 	static Array empty_array()
98 	{
99 		Array ret = void;
100 		_godot_api.godot_array_new(&ret._godot_array);
101 		return ret;
102 	}
103 	
104 	this(in typeof(null) n)
105 	{
106 		_godot_api.godot_array_new(&_godot_array);
107 	}
108 	
109 	this(in PoolByteArray a)
110 	{
111 		_godot_api.godot_array_new_pool_byte_array(&_godot_array, &a._godot_array);
112 	}
113 	
114 	this(in PoolIntArray a)
115 	{
116 		_godot_api.godot_array_new_pool_int_array(&_godot_array, &a._godot_array);
117 	}
118 	
119 	this(in PoolRealArray a)
120 	{
121 		_godot_api.godot_array_new_pool_real_array(&_godot_array, &a._godot_array);
122 	}
123 	
124 	this(in PoolStringArray a)
125 	{
126 		_godot_api.godot_array_new_pool_string_array(&_godot_array, &a._godot_array);
127 	}
128 	
129 	this(in PoolVector2Array a)
130 	{
131 		_godot_api.godot_array_new_pool_vector2_array(&_godot_array, &a._godot_array);
132 	}
133 	
134 	this(in PoolVector3Array a)
135 	{
136 		_godot_api.godot_array_new_pool_vector3_array(&_godot_array, &a._godot_array);
137 	}
138 	
139 	this(in PoolColorArray a)
140 	{
141 		_godot_api.godot_array_new_pool_color_array(&_godot_array, &a._godot_array);
142 	}
143 	
144 	auto ref inout(Variant) opIndex(size_t idx) inout
145 	{
146 		godot_variant* v = _godot_api.godot_array_operator_index(cast(godot_array*)&_godot_array, cast(int)idx);
147 		return *cast(inout(Variant)*)v;
148 	}
149 	
150 	void opIndexAssign(T)(auto ref T value, in size_t idx) if(is(T : Variant) || Variant.compatibleToGodot!T)
151 	{
152 		Variant v = Variant(value);
153 		_godot_api.godot_array_set(&_godot_array, cast(int)idx, &v._godot_variant);
154 	}
155 	
156 	void append(T)(auto ref T t) if(is(T : Variant) || Variant.compatibleToGodot!T)
157 	{
158 		Variant v = Variant(t);
159 		_godot_api.godot_array_append(&_godot_array, &v._godot_variant);
160 	}
161 	alias opOpAssign(string op : "~") = append;
162 	
163 	void clear()
164 	{
165 		_godot_api.godot_array_clear(&_godot_array);
166 	}
167 	
168 	size_t count(in Variant v)
169 	{
170 		return _godot_api.godot_array_count(&_godot_array, &v._godot_variant);
171 	}
172 	
173 	bool empty() const
174 	{
175 		return cast(bool)_godot_api.godot_array_empty(&_godot_array);
176 	}
177 	
178 	void erase(T)(T v)  if(is(T : Variant) || Variant.compatibleToGodot!T)
179 	{
180 		Variant vv = v;
181 		_godot_api.godot_array_erase(&_godot_array, &vv._godot_variant);
182 	}
183 	
184 	Variant front() const
185 	{
186 		godot_variant v = _godot_api.godot_array_front(&_godot_array);
187 		return cast(Variant)v;
188 	}
189 	
190 	Variant back() const
191 	{
192 		godot_variant v = _godot_api.godot_array_back(&_godot_array);
193 		return cast(Variant)v;
194 	}
195 	
196 	int find(T)(in T what, size_t from) const if(is(T : Variant) || Variant.compatibleToGodot!T)
197 	{
198 		const Variant vv = what;
199 		return _godot_api.godot_array_find(&_godot_array, &vv._godot_variant, cast(int)from);
200 	}
201 	
202 	int findLast(T)(in T what) const if(is(T : Variant) || Variant.compatibleToGodot!T)
203 	{
204 		const Variant vv = what;
205 		return _godot_api.godot_array_find_last(&_godot_array, &vv._godot_variant);
206 	}
207 	
208 	bool has(T)(in T what) const if(is(T : Variant) || Variant.compatibleToGodot!T)
209 	{
210 		const Variant vv = what;
211 		return cast(bool)_godot_api.godot_array_has(&_godot_array, &vv._godot_variant);
212 	}
213 	
214 	uint hash() const
215 	{
216 		return _godot_api.godot_array_hash(&_godot_array);
217 	}
218 	
219 	void insert(T)(const size_t pos, T value) if(is(T : Variant) || Variant.compatibleToGodot!T)
220 	{
221 		Variant vv = value;
222 		_godot_api.godot_array_insert(&_godot_array, cast(int)pos, &vv._godot_variant);
223 	}
224 	
225 	void invert()
226 	{
227 		_godot_api.godot_array_invert(&_godot_array);
228 	}
229 	
230 	Variant popBack()
231 	{
232 		godot_variant v = _godot_api.godot_array_pop_back(&_godot_array);
233 		return cast(Variant)v;
234 	}
235 	
236 	Variant popFront()
237 	{
238 		godot_variant v = _godot_api.godot_array_pop_front(&_godot_array);
239 		return cast(Variant)v;
240 	}
241 	
242 	void pushBack(T)(T v) if(is(T : Variant) || Variant.compatibleToGodot!T)
243 	{
244 		Variant vv = v;
245 		_godot_api.godot_array_push_back(&_godot_array, &vv._godot_variant);
246 	}
247 	
248 	void pushFront(T)(T v) if(is(T : Variant) || Variant.compatibleToGodot!T)
249 	{
250 		Variant vv = v;
251 		_godot_api.godot_array_push_front(&_godot_array, &vv._godot_variant);
252 	}
253 	
254 	void remove(size_t idx)
255 	{
256 		_godot_api.godot_array_remove(&_godot_array, cast(int)idx);
257 	}
258 	
259 	size_t size() const
260 	{
261 		return _godot_api.godot_array_size(&_godot_array);
262 	}
263 	alias length = size; // D-style `length`
264 	
265 	void resize(size_t size)
266 	{
267 		_godot_api.godot_array_resize(&_godot_array, cast(int)size);
268 	}
269 	
270 	int rfind(T)(in T what, size_t from) const if(is(T : Variant) || Variant.compatibleToGodot!T)
271 	{
272 		const Variant vv = what;
273 		return _godot_api.godot_array_rfind(&_godot_array, &vv._godot_variant, cast(int)from);
274 	}
275 	
276 	void sort()
277 	{
278 		_godot_api.godot_array_sort(&_godot_array);
279 	}
280 	
281 	/+void sort_custom(godot.Object obj, in ref String func)
282 	{
283 		_godot_api.godot_array_sort_custom(&_godot_array, obj, &func._godot_string);
284 	}+/
285 	
286 	/// Allocate a new separate copy of the Array
287 	Array dup() const
288 	{
289 		Array ret = empty_array;
290 		size_t l = size();
291 		ret.resize(l);
292 		foreach(vi; 0..l)
293 		{
294 			ret[vi] = this[vi];
295 		}
296 		return ret;
297 	}
298 	
299 	~this()
300 	{
301 		_godot_api.godot_array_destroy(&_godot_array);
302 	}
303 }
304 
305 
306 
307