GCC Code Coverage Report


Directory: src/gate/
File: src/gate/arrays.hpp
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 627 652 96.2%
Functions: 697 1065 65.4%
Branches: 123 211 58.3%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 /** @file
30 * @brief Arrays and other linear sequential type field
31 * @ingroup gatecore_cpp
32 */
33
34 #ifndef GATE_ARRAYS_HPP_INCLUDED
35 #define GATE_ARRAYS_HPP_INCLUDED
36
37 #include "gate/gate_core_api.hpp"
38 #include "gate/arrays.h"
39
40 #include "gate/gatetypes.hpp"
41 #include "gate/memalloc.hpp"
42 #include "gate/results.hpp"
43 #include "gate/exceptions.hpp"
44 #include "gate/enumerators.hpp"
45 #include "gate/comparers.hpp"
46
47 namespace gate
48 {
49
50 /// @brief
51 class GATE_CORE_CPP_API GenericArray
52 {
53 public:
54 GenericArray() noexcept;
55 GenericArray(GenericArray const& src) noexcept;
56 GenericArray(gate_array_t const& src) noexcept;
57 GenericArray& operator=(GenericArray const& src) noexcept;
58 ~GenericArray() noexcept;
59 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
60 GenericArray(GenericArray&& src) noexcept;
61 GenericArray& operator=(GenericArray&& src) noexcept;
62 #endif
63
64 void swap(GenericArray& other) noexcept;
65 gate_array_t const* c_impl() const noexcept;
66 gate_array_t* c_impl() noexcept;
67
68 bool_t empty() const noexcept;
69 size_t length() const noexcept;
70 size_t size() const noexcept;
71 bool_t contains(size_t index) const noexcept;
72 void const* getItemPtr(size_t index) const noexcept;
73 size_t find(gate_comparer_t comparer, void const* compareWith, size_t startAt = 0) const noexcept;
74
75 GenericArray subset(size_t index, size_t length) const;
76 GenericArray copy() const;
77
78 protected:
79 gate_array_t impl;
80
81 protected:
82 static void check_outofmem_nullptr(void const* ptr);
83
84 };
85
86
87 /// @brief
88 /// @tparam T
89 template <class T>
90 class GATE_CORE_CPP_TEMPLATE_API Array : public GenericArray
91 {
92 public:
93 typedef T item_t;
94 typedef Array<T> self_t;
95 typedef item_t const* iterator;
96 typedef item_t const* const_iterator;
97
98 public:
99 class reverse_iterator
100 {
101 private:
102 item_t const* ptr;
103
104 public:
105 48 reverse_iterator(item_t const* tptr) : ptr(tptr) {}
106 26 item_t const& operator*() { return *this->ptr; }
107 8 item_t const* operator->() { return this->ptr; }
108 28 reverse_iterator& operator++()
109 {
110 28 --this->ptr;
111 28 return *this;
112 }
113 18 reverse_iterator operator++(int)
114 {
115
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
18 reverse_iterator ret(this->ptr--);
116 18 return ret;
117 }
118 18 reverse_iterator& operator--()
119 {
120 18 ++this->ptr;
121 18 return *this;
122 }
123 18 reverse_iterator operator--(int)
124 {
125
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
18 reverse_iterator ret(this->ptr++);
126 18 return ret;
127 }
128 1 bool operator==(reverse_iterator const& that) const { return this->ptr == that.ptr; }
129 10 bool operator!=(reverse_iterator const& that) const { return this->ptr != that.ptr; }
130 };
131 typedef reverse_iterator const_reverse_iterator;
132
133 386 Array() noexcept
134 386 {
135 386 gate_array_t* tmp = gate_array_create_static(&this->impl, NULL, sizeof(item_t), 0);
136 #ifdef GATE_DEBUG_MODE
137 386 check_outofmem_nullptr(tmp);
138 #else
139 (void)tmp;
140 #endif
141 386 }
142 11 Array(item_t const* items, size_t count)
143 11 {
144
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 gate_arraylist_t arrlist = gate_arraylist_create(sizeof(item_t), items, count, &TypeFunctions<item_t>::copyConstruct, &TypeFunctions<item_t>::destruct);
145
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 check_outofmem_nullptr(arrlist.ptr);
146
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 gate_array_t* result = gate_array_create(&this->impl, arrlist);
147
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 gate_arraylist_release(&arrlist);
148
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 check_outofmem_nullptr(result);
149 11 }
150 3 Array(self_t const& src) noexcept
151 3 {
152 3 gate_array_t* const tmp = gate_array_duplicate(&this->impl, &src.impl);
153 #ifdef GATE_DEBUG_MODE
154 3 check_outofmem_nullptr(tmp);
155 #endif
156 (void)tmp;
157 3 }
158
159 1 Array(gate_array_t const& arr)
160 1 {
161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (arr.item_size != sizeof(item_t))
162 {
163 ✗ GATEXX_RAISE_ERROR(results::IncorrectType);
164 }
165
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 gate_arraylist_t arrlist = gate_arraylist_create(sizeof(item_t),
166 gate_array_get(&arr, 0), gate_array_length(&arr),
167 &TypeFunctions<item_t>::copyConstruct, &TypeFunctions<item_t>::destruct);
168
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 check_outofmem_nullptr(arrlist.ptr);
169
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_array_t* result = gate_array_create(&this->impl, arrlist);
170
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 gate_arraylist_release(&arrlist);
171
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 check_outofmem_nullptr(result);
172 1 }
173 423 ~Array() noexcept
174 {
175 423 }
176
177 4 static self_t createStatic(item_t const* items, size_t count) noexcept
178 {
179 4 self_t ret;
180 4 gate_array_t* const tmp = gate_array_create_static(&ret.impl, items, sizeof(item_t), count);
181 #ifdef GATE_DEBUG_MODE
182 4 check_outofmem_nullptr(tmp);
183 #endif
184 (void)tmp;
185 4 return ret;
186 }
187
188 #if !defined(GATE_COMPILER_SUPPORTS_CPP_ARRAY_SIZE_DEDUCTION)
189 template <class A>
190 static self_t createStaticFrom(A fixed_array) noexcept
191 {
192 return self_t::createStatic(&fixed_array[0], sizeof(fixed_array) / sizeof(fixed_array[0]));
193 }
194 #else
195 template <unsigned N>
196 1 static self_t createStaticFrom(item_t const (&items)[N]) noexcept
197 {
198 1 return self_t::createStatic(&items[0], N);
199 }
200 #endif
201
202 239 static self_t createFrom(gate_array_t& arr)
203 {
204
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 142 times.
239 if (arr.item_size != sizeof(item_t))
205 {
206 4 GATEXX_RAISE_ERROR(results::IncorrectType);
207 }
208 235 self_t ret;
209
1/2
✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
235 gate_mem_copy(&ret.impl, &arr, sizeof(arr));
210
1/2
✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
235 gate_mem_clear(&arr, sizeof(arr));
211 235 return ret;
212 }
213
214 117 void swap(self_t& that) noexcept
215 {
216 117 GenericArray::swap(that);
217 117 }
218
219 1 self_t& operator=(self_t const& src) noexcept
220 {
221 1 Array that(src);
222 1 this->swap(that);
223 1 return *this;
224 }
225
226 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
227 1 Array(self_t&& src) noexcept
228 1 : GenericArray(gate::moveRef(src))
229 {
230 1 }
231
232 58 self_t& operator=(self_t&& that) noexcept
233 {
234 58 self_t tmp;
235 58 that.swap(tmp);
236 58 this->swap(tmp);
237 58 return *this;
238 }
239 #endif
240
241 2089 item_t const* getItemPtr(size_t ndx) const noexcept
242 {
243 2089 item_t const* ptr = static_cast<item_t const*>(GenericArray::getItemPtr(ndx));
244 2089 return ptr;
245 }
246
247 2070 item_t const& at(size_t ndx) const noexcept
248 {
249 2070 item_t const* ptr = this->getItemPtr(ndx);
250 #ifdef GATE_DEBUG_MODE
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1052 times.
2070 if (ptr == NULL)
252 {
253 ✗ gate::panic(results::OutOfBounds, "Array::at()");
254 }
255 #endif
256 2070 return *ptr;
257 }
258
259 typedef Enumerator<item_t const> enumerator_t;
260
261 23 enumerator_t enumerate() const noexcept
262 {
263 gate_enumerator_t enumerator;
264 23 gate_enumerator_t* const tmp = gate_array_enumerate(&this->impl, &enumerator);
265 #ifdef GATE_DEBUG_MODE
266 23 check_outofmem_nullptr(tmp);
267 #endif
268 (void)tmp;
269 23 return enumerator_t(enumerator);
270 }
271
272 2048 item_t const& operator[](size_t ndx) const noexcept
273 {
274 2048 return this->at(ndx);
275 }
276
277 1 self_t subset(size_t offset, size_t count) const
278 {
279
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 GenericArray arr = GenericArray::subset(offset, count);
280
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 self_t ret = self_t::createFrom(*arr.c_impl());
281 2 return ret;
282 }
283
284 1 self_t copy() const
285 {
286
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 GenericArray arr = GenericArray::copy();
287
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 self_t ret = self_t::createFrom(*arr.c_impl());
288 2 return ret;
289 }
290
291 56 const_iterator begin() const noexcept { return (item_t const*)this->impl.data_ptr; }
292 22 const_iterator end() const noexcept { return this->begin() + this->impl.item_count; }
293 1 const_iterator cbegin() const noexcept { return this->begin(); }
294 1 const_iterator cend() const noexcept { return this->end(); }
295
296 6 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(this->begin() - 1); }
297 6 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(this->begin() + this->impl.item_count - 1); }
298 1 const_reverse_iterator crbegin() const noexcept { return this->rbegin(); }
299 1 const_reverse_iterator crend() const noexcept { return this->rend(); }
300 };
301
302 /// @brief
303 /// @tparam T
304 /// @param arr
305 /// @return
306 template <class T>
307 Enumerator<T const> enumerate(Array<T> const& arr) noexcept
308 {
309 return arr.enumerate();
310 }
311
312
313 class GATE_CORE_CPP_API GenericArrayList
314 {
315 public:
316 GenericArrayList() noexcept;
317 GenericArrayList(size_t itemSize, void const* source, size_t sourceLength, gate_mem_copyctor_t cctor, gate_mem_dtor_t dtor);
318 GenericArrayList(gate_arraylist_t al);
319 GenericArrayList(GenericArrayList const& src);
320 GenericArrayList& operator=(GenericArrayList const& src);
321 ~GenericArrayList() noexcept;
322
323 gate_arraylist_t& c_impl();
324 gate_arraylist_t const& c_impl() const;
325 bool_t isNull() const noexcept;
326 void swap(GenericArrayList& that) noexcept;
327
328 size_t itemSize() const noexcept;
329 size_t length() const noexcept;
330 bool_t empty() const noexcept;
331
332 void* add(void const* ptrItem);
333 void* add(void const* ptrItem, size_t repeatCount);
334 void* insertAt(size_t index, void const* ptrItem);
335 VoidResult removeAt(size_t index) noexcept;
336 void clear() noexcept;
337 void* getItemPtr(size_t index) noexcept;
338 void const* getItemPtr(size_t index) const noexcept;
339 bool_t contains(size_t index) const noexcept;
340
341 GenericArrayList copy() const;
342 GenericArray toArray() const;
343
344 protected:
345 gate_arraylist_t impl;
346
347 protected:
348 static void check_outofmem_nullptr(void const* ptr);
349 };
350
351
352 /// @brief
353 /// @tparam T
354 template <class T>
355 class GATE_CORE_CPP_TEMPLATE_API ArrayList : public GenericArrayList
356 {
357 public:
358 typedef T item_t;
359 typedef T* iterator;
360 typedef T const* const_iterator;
361 typedef ArrayList<T> self_t;
362
363 class reverse_iterator
364 {
365 private:
366 item_t* ptr;
367
368 public:
369 12 reverse_iterator(T* tptr) : ptr(tptr) {}
370 24 item_t& operator*() { return *this->ptr; }
371 4 item_t* operator->() { return this->ptr; }
372 18 reverse_iterator& operator++()
373 {
374 18 --this->ptr;
375 18 return *this;
376 }
377 1 reverse_iterator operator++(int)
378 {
379
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 reverse_iterator ret(this->ptr--);
380 1 return ret;
381 }
382 1 reverse_iterator& operator--()
383 {
384 1 ++this->ptr;
385 1 return *this;
386 }
387 1 reverse_iterator operator--(int)
388 {
389
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 reverse_iterator ret(this->ptr++);
390 1 return ret;
391 }
392 1 bool operator==(reverse_iterator const& that) const { return this->ptr == that.ptr; }
393 12 bool operator!=(reverse_iterator const& that) const { return this->ptr != that.ptr; }
394 };
395
396 class const_reverse_iterator
397 {
398 private:
399 item_t const* ptr;
400
401 public:
402 32 const_reverse_iterator(item_t const* tptr) : ptr(tptr) {}
403 4 item_t const& operator*() const { return *this->ptr; }
404 4 item_t const* operator->() const { return this->ptr; }
405 4 const_reverse_iterator& operator++()
406 {
407 4 --this->ptr;
408 4 return *this;
409 }
410 4 const_reverse_iterator operator++(int)
411 {
412
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
4 const_reverse_iterator ret(this->ptr--);
413 4 return ret;
414 }
415 4 const_reverse_iterator& operator--()
416 {
417 4 ++this->ptr;
418 4 return *this;
419 }
420 8 const_reverse_iterator operator--(int)
421 {
422
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
8 const_reverse_iterator ret(this->ptr++);
423 8 return ret;
424 }
425 1 bool operator==(const_reverse_iterator const& that) const { return this->ptr == that.ptr; }
426 5 bool operator!=(const_reverse_iterator const& that) const { return this->ptr != that.ptr; }
427 };
428
429 public:
430 286 ArrayList(size_t prealloc = 0)
431 286 : GenericArrayList(sizeof(item_t), NULL, prealloc, &TypeFunctions<item_t>::copyConstruct, &TypeFunctions<item_t>::destruct)
432 {
433 286 }
434
435 3 ArrayList(item_t const* items, size_t count)
436 3 : GenericArrayList(sizeof(item_t), items, count, &TypeFunctions<item_t>::copyConstruct, &TypeFunctions<item_t>::destruct)
437 {
438 3 }
439
440 2 ArrayList(Array<item_t> const& copyFrom)
441 2 {
442 2 size_t const length = copyFrom.length();
443 2 item_t const* const first = copyFrom.getItemPtr(0);
444
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 this->impl = gate_arraylist_create(sizeof(item_t), first, length, &TypeFunctions<item_t>::copyConstruct, &TypeFunctions<item_t>::destruct);
445
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 check_outofmem_nullptr(this->impl.ptr);
446 2 }
447
448 2 ArrayList(Enumerator<item_t const> enumerator)
449 2 {
450
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 self_t arr;
451
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
10 for (; enumerator.valid(); enumerator.next())
452 {
453
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 arr.add(*enumerator);
454 }
455 2 this->swap(arr);
456 2 }
457
458 1 ArrayList(self_t const& src) noexcept
459 1 : GenericArrayList(src.impl)
460 {
461 1 gate_arraylist_retain(&this->impl);
462 1 }
463
464 300 ~ArrayList() noexcept
465 {
466 300 }
467
468 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
469 ✗ ArrayList(self_t&& that) noexcept
470 ✗ : GenericArrayList(that.impl)
471 {
472 ✗ Mem::clear(that.impl);
473 ✗ }
474
475 1 self_t& operator=(self_t&& that) noexcept
476 {
477 1 this->swap(that);
478 1 gate_arraylist_release(&that.impl);
479 1 return *this;
480 }
481 #endif
482
483 3 self_t copy() const
484 {
485
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 GenericArrayList gal = GenericArrayList::copy();
486
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 self_t ret;
487 3 GenericArrayList& retref = ret;
488 3 retref.swap(gal);
489 6 return ret;
490 }
491
492 1 void constructItem(item_t* ptr_uninitialized_item)
493 {
494 1 size_t sz = gate_arraylist_create_item(this->impl, ptr_uninitialized_item, sizeof(item_t));
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sz == 0)
496 {
497 ✗ GATEXX_RAISE_ERROR(results::OutOfMemory);
498 }
499 1 }
500
501 1 void constructItem(size_t index, item_t* ptr_uninitialized_item)
502 {
503 1 size_t sz = gate_arraylist_get_value(this->impl, index, ptr_uninitialized_item, sizeof(item_t));
504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sz == 0)
505 {
506 ✗ GATEXX_RAISE_ERROR(results::OutOfMemory);
507 }
508 1 }
509
510 8 void swap(self_t& that) noexcept
511 {
512 8 GenericArrayList& ref = *this;
513 8 ref.swap(that);
514 8 }
515
516 1 self_t& operator=(self_t const& src) noexcept
517 {
518 1 GenericArrayList::operator=(src);
519 1 return *this;
520 }
521
522 6 iterator begin() noexcept
523 {
524 6 size_t const len = this->length();
525 6 void* ptr = NULL;
526
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if (len != 0)
527 {
528 5 ptr = gate_arraylist_get(this->impl, 0);
529 }
530 6 return static_cast<iterator>(ptr);
531 }
532
533 7 iterator end() noexcept
534 {
535 7 size_t const len = this->length();
536 7 void* ptr = NULL;
537
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
7 if (len != 0)
538 {
539 4 ptr = gate_arraylist_get(this->impl, 0);
540 4 ptr = ((char*)ptr + gate_arraylist_itemsize(this->impl) * len);
541 }
542 7 return static_cast<iterator>(ptr);
543 }
544
545 2 const_iterator begin() const noexcept
546 {
547 2 size_t const len = this->length();
548 2 void const* ptr = NULL;
549
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (len != 0)
550 {
551 1 ptr = gate_arraylist_get(this->impl, 0);
552 }
553 2 return static_cast<const_iterator>(ptr);
554 }
555
556 4 const_iterator end() const noexcept
557 {
558 4 size_t const len = this->length();
559 4 char const* ptr = NULL;
560
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (len != 0)
561 {
562 1 ptr = (char const*)gate_arraylist_get(this->impl, 0);
563 1 ptr += gate_arraylist_itemsize(this->impl) * len;
564 }
565 4 return reinterpret_cast<const_iterator>(ptr);
566 }
567
568 1 const_iterator cbegin() const noexcept
569 {
570 1 return this->begin();
571 }
572
573 1 const_iterator cend() const noexcept
574 {
575 1 return this->end();
576 }
577
578 4 reverse_iterator rbegin() noexcept
579 {
580 4 size_t const len = this->length();
581 4 char* ptr = NULL;
582
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if (len != 0)
583 {
584 4 ptr = (char*)gate_arraylist_get(this->impl, len);
585 4 ptr -= gate_arraylist_itemsize(this->impl);
586 }
587 4 return reverse_iterator(static_cast<item_t*>(static_cast<void*>(ptr)));
588 }
589
590 4 reverse_iterator rend() noexcept
591 {
592 4 size_t const len = this->length();
593 4 char* ptr = NULL;
594
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 if (len != 0)
595 {
596 4 ptr = (char*)gate_arraylist_get(this->impl, 0);
597 4 ptr -= gate_arraylist_itemsize(this->impl);
598 }
599 4 return reverse_iterator(static_cast<item_t*>(static_cast<void*>(ptr)));
600 ;
601 }
602
603 4 const_reverse_iterator rbegin() const noexcept
604 {
605 4 size_t const len = this->length();
606 4 char const* ptr = NULL;
607
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
4 if (len != 0)
608 {
609 2 ptr = (char const*)gate_arraylist_get(this->impl, len);
610 2 ptr -= gate_arraylist_itemsize(this->impl);
611 }
612 4 return const_reverse_iterator(static_cast<item_t const*>(static_cast<void const*>(ptr)));
613 }
614
615 4 const_reverse_iterator rend() const noexcept
616 {
617 4 size_t const len = this->length();
618 4 char const* ptr = NULL;
619
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
4 if (len != 0)
620 {
621 2 ptr = (char const*)gate_arraylist_get(this->impl, 0);
622 2 ptr -= gate_arraylist_itemsize(this->impl);
623 }
624 4 return const_reverse_iterator(static_cast<item_t const*>(static_cast<void const*>(ptr)));
625 ;
626 }
627
628 4 const_reverse_iterator crbegin() const noexcept
629 {
630 4 return this->rbegin();
631 }
632
633 4 const_reverse_iterator crend() const noexcept
634 {
635 4 return this->rend();
636 }
637
638 2732 iterator add(item_t const& item)
639 {
640 2732 iterator ret = static_cast<iterator>(GenericArrayList::add(&item));
641 2732 check_outofmem_nullptr(ret);
642 2732 return ret;
643 }
644
645 7 VoidResult tryAdd(item_t const& item) noexcept
646 {
647 7 void* rawptr = GenericArrayList::add(&item);
648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (NULL == rawptr)
649 {
650 ✗ return makeErrResult(results::OutOfMemory);
651 }
652 else
653 {
654 7 return makeOk();
655 }
656 }
657
658 3 iterator add(item_t const& item, size_t repeatCount)
659 {
660 3 iterator ret = static_cast<iterator>(GenericArrayList::add(&item, repeatCount));
661 3 check_outofmem_nullptr(ret);
662 3 return ret;
663 }
664
665 template <class ITER>
666 16 void addItems(ITER begin, ITER end)
667 {
668
3/3
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
16 while (begin != end)
669 {
670
2/3
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
13 this->add(item_t(*begin));
671 13 ++begin;
672 }
673 3 }
674
675 48 iterator insertAt(size_t index, item_t const& item)
676 {
677 48 iterator ret = static_cast<iterator>(GenericArrayList::insertAt(index, &item));
678 48 check_outofmem_nullptr(ret);
679 48 return ret;
680 }
681
682 1 VoidResult remove(iterator iter) noexcept
683 {
684 1 iterator const first = this->begin();
685 1 size_t const index = static_cast<size_t>(iter - first);
686 1 return this->removeAt(index);
687 }
688
689 6 item_t const* getItemPtr(size_t index) const noexcept
690 {
691 6 void const* ptr = GenericArrayList::getItemPtr(index);
692 6 return static_cast<item_t const*>(ptr);
693 }
694
695 6 iterator get(size_t index) noexcept
696 {
697 6 void* const ptr = GenericArrayList::getItemPtr(index);
698
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (ptr == NULL)
699 {
700 2 return this->end();
701 }
702 4 return static_cast<iterator>(ptr);
703 }
704
705 4 const_iterator get(size_t index) const noexcept
706 {
707 4 void const* const ptr = GenericArrayList::getItemPtr(index);
708
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (ptr == NULL)
709 {
710 1 return this->end();
711 }
712 3 return static_cast<const_iterator>(ptr);
713 }
714
715 1058 item_t& at(size_t index) noexcept
716 {
717 1058 void* ptr = GenericArrayList::getItemPtr(index);
718 #ifdef GATE_DEBUG_MODE
719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1054 times.
1058 if (ptr == NULL)
720 {
721 ✗ panic(results::OutOfBounds, "ArrayList::at()");
722 }
723 #endif
724 1058 return *static_cast<item_t*>(ptr);
725 }
726
727 2 item_t const& at(size_t index) const noexcept
728 {
729 2 void const* ptr = GenericArrayList::getItemPtr(index);
730 #ifdef GATE_DEBUG_MODE
731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ptr == NULL)
732 {
733 ✗ panic(results::OutOfBounds, "ArrayList::at()");
734 }
735 #endif
736 2 return *static_cast<item_t const*>(ptr);
737 }
738
739 1046 item_t& operator[](size_t index) noexcept
740 {
741 1046 return this->at(index);
742 }
743 1 item_t const& operator[](size_t index) const noexcept
744 {
745 1 return this->at(index);
746 }
747
748 1038 self_t& push(item_t const& item)
749 {
750 1038 this->add(item);
751 1038 return *this;
752 }
753
754 4 self_t& pop(item_t& item)
755 {
756
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 if (!this->contains(0))
757 {
758 1 GATEXX_RAISE_ERROR(results::NotAvailable);
759 }
760 3 item = this->at(0);
761 3 this->removeAt(0);
762 3 return *this;
763 }
764
765 1038 self_t& operator<<(item_t const& item)
766 {
767 1038 return this->push(item);
768 }
769
770 3 self_t& operator>>(item_t& item)
771 {
772 3 return this->pop(item);
773 }
774
775 typedef Enumerator<item_t const> enumerator_t;
776
777 2 enumerator_t enumerate() const
778 {
779 gate_enumerator_t enumerator;
780
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 check_outofmem_nullptr(gate_arraylist_enumerate(this->impl, &enumerator));
781 4 return enumerator_t(enumerator);
782 }
783
784 157 Array<item_t> toArray() const
785 {
786
1/2
✓ Branch 1 taken 65 times.
✗ Branch 2 not taken.
314 GenericArray arr = GenericArrayList::toArray();
787 157 gate_array_t* ptrArr = arr.c_impl();
788
2/2
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 2 times.
157 Array<item_t> ret = Array<item_t>::createFrom(*ptrArr);
789 306 return ret;
790 }
791
792 template <class FROM>
793 10 void importFrom(gate_arraylist_t arr)
794 {
795 FROM const* ptr;
796 10 size_t length = gate_arraylist_length(arr);
797
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 10 times.
58 for (size_t index = 0; index != length; ++index)
798 {
799 48 ptr = (FROM const*)gate_arraylist_get(arr, index);
800
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (ptr)
801 {
802
1/3
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
48 this->add(item_t(*ptr));
803 }
804 }
805 10 }
806
807 template <class TO>
808 1 size_t exportTo(gate_arraylist_t arr) const
809 {
810 1 size_t countedExports = 0;
811
812
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (sizeof(TO) != gate_arraylist_itemsize(arr))
813 {
814 ✗ GATEXX_RAISE_ERROR(results::IncorrectType);
815 }
816 else
817 {
818 1 size_t len = this->length();
819
820
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (size_t index = 0; index != len; ++index)
821 {
822 3 item_t const* ptr = this->get(index);
823 3 TO const* ptr_native = (TO const*)ptr;
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!ptr_native)
825 {
826 ✗ continue;
827 }
828
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (NULL != gate_arraylist_add(arr, ptr))
829 {
830 3 ++countedExports;
831 }
832 }
833 }
834
835 1 return countedExports;
836 }
837
838 template <class COMPARER>
839 6 void sort(COMPARER comparer, bool descending = false)
840 {
841
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
6 if (this->length() < 2)
842 {
843 ✗ return;
844 }
845 6 item_t* endPtr = this->end();
846 6 item_t* lastPtr = endPtr - 1;
847
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 3 times.
26 for (item_t* current = this->begin(); current != lastPtr; ++current)
848 {
849
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 10 times.
66 for (item_t* next = current + 1; next != endPtr; ++next)
850 {
851 46 int result = comparer(*next, *current);
852
7/8
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
46 if ((!descending && (result < 0)) || (descending && (result > 0)))
853 {
854 36 gate::swapRefs(*next, *current);
855 }
856 }
857 }
858 }
859
860 1 void sort()
861 {
862
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->sort(DefaultComparer<item_t>());
863 1 }
864 };
865
866
867
868 /// @brief
869 /// @tparam T
870 template <class T>
871 class SlotList
872 {
873 public:
874 typedef T item_t;
875 typedef SlotList<T> self_t;
876
877 private:
878 gate_slotlist_t impl;
879
880 138 static void check_outofmem_nullptr(void const* ptr)
881 {
882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
138 if (NULL == ptr)
883 {
884 ✗ GATEXX_RAISE_ERROR(results::OutOfMemory);
885 }
886 138 }
887
888 public:
889 class const_iterator
890 {
891 friend class SlotList<T>;
892
893 protected:
894 gate_slotlist_t const* sl;
895 gate_slotlist_iterator_t iter;
896 item_t* item;
897
898 public:
899 104 const_iterator(gate_slotlist_t const* s, gate_slotlist_iterator_t it, item_t* ptr) noexcept
900 104 : sl(s), iter(it), item(ptr)
901 {
902 104 }
903
904 104 ~const_iterator() noexcept
905 {
906 104 }
907
908 32 item_t const* get() const noexcept
909 {
910 32 return this->item;
911 }
912
913 31 item_t const& operator*() const
914 {
915 31 return *this->get();
916 }
917 1 item_t const* operator->() const noexcept
918 {
919 1 return this->get();
920 }
921
922 32 const_iterator& operator++() noexcept
923 {
924 32 this->item = static_cast<item_t*>(gate_slotlist_next(this->sl, &this->iter));
925 32 return *this;
926 }
927 const_iterator operator++(int) noexcept
928 {
929 const_iterator that(*this);
930 this->item = static_cast<item_t*>(gate_slotlist_next(this->sl, &this->iter));
931 return that;
932 }
933
934 bool_t operator==(const_iterator const& that) const noexcept
935 {
936 return (this->sl == that.sl) && (this->item == that.item);
937 }
938
939 81 bool_t operator!=(const_iterator const& that) const noexcept
940 {
941
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
81 return (this->item != that.item) || (this->sl != that.sl);
942 }
943 };
944
945 class iterator : public const_iterator
946 {
947 friend class SlotList<T>;
948
949 public:
950 11 iterator(gate_slotlist_t const* s, gate_slotlist_iterator_t it, item_t* ptr) noexcept
951 11 : const_iterator(s, it, ptr)
952 {
953 11 }
954
955 4 item_t* get() const noexcept
956 {
957 4 return this->item;
958 }
959
960 4 item_t& operator*() const
961 {
962 4 return *this->get();
963 }
964 item_t* operator->() const noexcept
965 {
966 return this->get();
967 }
968 };
969
970 friend class const_iterator;
971 friend class iterator;
972
973 85 SlotList() noexcept
974 {
975 85 check_outofmem_nullptr(gate_slotlist_create(
976 &this->impl, sizeof(item_t),
977 &TypeFunctions<item_t>::copyConstruct,
978 &TypeFunctions<item_t>::destruct));
979 85 }
980 3 SlotList(self_t const& src)
981 {
982 3 check_outofmem_nullptr(gate_slotlist_create_copy(&this->impl, &src.impl));
983 3 }
984 88 ~SlotList() noexcept
985 {
986 88 gate_slotlist_destroy(&this->impl);
987 88 }
988 2 void swap(self_t& that) noexcept
989 {
990 2 gate::swapRefsNoExcept(this->impl, that.impl);
991 2 }
992 1 self_t& operator=(self_t const& src)
993 {
994
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &src)
995 {
996
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 self_t that(src);
997 1 this->swap(that);
998 }
999 1 return *this;
1000 }
1001
1002 1 gate_slotlist_t const* c_impl() const noexcept
1003 {
1004 1 return &this->impl;
1005 }
1006
1007 2 void optimize() noexcept
1008 {
1009 2 gate_slotlist_optimize(&this->impl);
1010 2 }
1011
1012 30 item_t& add(item_t const& src)
1013 {
1014 30 void* ptr = gate_slotlist_add(&this->impl, &src);
1015 30 check_outofmem_nullptr(ptr);
1016 30 return *static_cast<item_t*>(ptr);
1017 }
1018
1019 1 item_t& insertAt(size_t index, item_t const& src)
1020 {
1021 1 void* ptr = gate_slotlist_insert_at(&this->impl, index, &src);
1022 1 check_outofmem_nullptr(ptr);
1023 1 return *static_cast<item_t*>(ptr);
1024 }
1025
1026 1 item_t* getItem(iterator const& iter) noexcept
1027 {
1028 1 return static_cast<item_t*>(gate_slotlist_get(&this->impl, &iter.iter));
1029 }
1030
1031 1 item_t const* getItem(const_iterator const& iter) noexcept
1032 {
1033 1 return static_cast<item_t const*>(gate_slotlist_get(&this->impl, &iter.iter));
1034 }
1035
1036 8 item_t* getPtr(size_t index) noexcept
1037 {
1038 8 item_t* ptr = static_cast<item_t*>(gate_slotlist_at(&this->impl, index));
1039 8 return ptr;
1040 }
1041 7 item_t const* getPtr(size_t index) const noexcept
1042 {
1043 7 item_t const* ptr = static_cast<item_t const*>(gate_slotlist_at(&this->impl, index));
1044 7 return ptr;
1045 }
1046
1047 5 bool_t contains(size_t index) const noexcept
1048 {
1049 5 item_t const* ptr = this->getPtr(index);
1050 5 return ptr != NULL;
1051 }
1052
1053 5 item_t& get(size_t index) noexcept
1054 {
1055 5 item_t* const ptr = this->getPtr(index);
1056 #ifdef GATE_DEBUG_MODE
1057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ptr == NULL)
1058 {
1059 ✗ panic(results::OutOfBounds, "SlotList::get()");
1060 }
1061 #endif
1062 5 return *ptr;
1063 }
1064 1 item_t const& get(size_t index) const
1065 {
1066 1 item_t const* const ptr = this->getPtr(index);
1067 #ifdef GATE_DEBUG_MODE
1068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ptr == NULL)
1069 {
1070 ✗ panic(results::OutOfBounds, "SlotList::get()");
1071 }
1072 #endif
1073 1 return *ptr;
1074 }
1075
1076 1 void clear() noexcept
1077 {
1078 1 gate_slotlist_clear(&this->impl);
1079 1 }
1080
1081 6 size_t length() const noexcept
1082 {
1083 6 return gate_slotlist_length(&this->impl);
1084 }
1085 1 size_t capacity() const noexcept
1086 {
1087 1 return gate_slotlist_capacity(&this->impl);
1088 }
1089 61 const_iterator cend() const noexcept
1090 {
1091 61 return const_iterator(&this->impl, gate_slotlist_capacity(&this->impl), NULL);
1092 }
1093 43 const_iterator cbegin() const noexcept
1094 {
1095 gate_slotlist_iterator_t it;
1096 43 void* const ptr = gate_slotlist_first(&this->impl, &it);
1097
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
43 if (ptr == NULL)
1098 {
1099 14 return this->cend();
1100 }
1101 29 return const_iterator(&this->impl, it, static_cast<item_t*>(ptr));
1102 }
1103 5 iterator end() noexcept
1104 {
1105 5 return iterator(&this->impl, gate_slotlist_capacity(&this->impl), NULL);
1106 }
1107 6 iterator begin() noexcept
1108 {
1109 gate_slotlist_iterator_t it;
1110 6 void* const ptr = gate_slotlist_first(&this->impl, &it);
1111
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (ptr == NULL)
1112 {
1113 ✗ return this->end();
1114 }
1115 6 return iterator(&this->impl, it, static_cast<item_t*>(ptr));
1116 }
1117
1118 42 const_iterator begin() const
1119 {
1120 42 return this->cbegin();
1121 }
1122 34 const_iterator end() const
1123 {
1124 34 return this->cend();
1125 }
1126
1127 1 const_iterator getIterator(size_t ndx) const
1128 {
1129 1 return const_iterator(&this->impl, ndx, static_cast<item_t*>(gate_slotlist_at(&this->impl, ndx)));
1130 }
1131
1132 4 bool_t remove(const_iterator const& it)
1133 {
1134 4 return gate_slotlist_remove(&this->impl, &it.iter);
1135 }
1136
1137 1 bool_t removeAt(size_t index)
1138 {
1139 1 return gate_slotlist_remove_at(&this->impl, index);
1140 }
1141
1142 1 Enumerator<item_t const> enumerate() const noexcept
1143 {
1144 gate_enumerator_t e;
1145 1 gate_enumerator_t* ptr = gate_slotlist_enumerate(&this->impl, &e);
1146 #ifdef GATE_DEBUG_MODE
1147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ptr)
1148 {
1149 ✗ panic(results::NullPointer, "SlotList::enumerator");
1150 }
1151 #endif
1152 (void)ptr;
1153 1 return Enumerator<item_t const>(e);
1154 }
1155 };
1156
1157
1158
1159 /// @brief
1160 /// @tparam T
1161 template <class T>
1162 class LinkedList
1163 {
1164 public:
1165 typedef T item_t;
1166 typedef LinkedList<T> self_t;
1167
1168 class iterator
1169 {
1170 protected:
1171 gate_linkedentry_t* ptr_entry;
1172
1173 public:
1174 24 iterator(gate_linkedentry_t* entry) noexcept : ptr_entry(entry) {}
1175 8 iterator(iterator const& src) noexcept : ptr_entry(src.ptr_entry) {}
1176 1 iterator& operator=(iterator const& src) noexcept
1177 {
1178 1 this->ptr_entry = src.ptr_entry;
1179 1 return *this;
1180 }
1181 32 ~iterator() noexcept {}
1182
1183 5 gate_linkedentry_t* c_impl() const noexcept { return this->ptr_entry; }
1184
1185 35 item_t* getPtr() const noexcept
1186 {
1187
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 13 times.
35 return this->ptr_entry ? static_cast<item_t*>(this->ptr_entry->data) : NULL;
1188 }
1189 9 item_t& get() const noexcept
1190 {
1191 9 item_t* const ptr = this->getPtr();
1192 #ifdef GATE_DEBUG_MODE
1193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!ptr)
1194 {
1195 ✗ panic(results::NullPointer, "LinkedList::iterator::get");
1196 }
1197 #endif
1198 9 return *ptr;
1199 }
1200
1201 9 item_t& operator*() const noexcept { return this->get(); }
1202 item_t* operator->() const noexcept { return this->getPtr(); }
1203
1204 7 bool operator==(iterator const& src) const { return this->getPtr() == src.getPtr(); }
1205 6 bool operator!=(iterator const& src) const { return this->getPtr() != src.getPtr(); }
1206 3 iterator& operator++()
1207 {
1208 3 this->ptr_entry = gate_linkedlist_next(this->ptr_entry);
1209 3 return *this;
1210 }
1211 1 iterator operator++(int)
1212 {
1213 1 iterator tmp(*this);
1214
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ++(*this);
1215 1 return tmp;
1216 }
1217 2 iterator& operator--()
1218 {
1219 2 this->ptr_entry = gate_linkedlist_previous(this->ptr_entry);
1220 2 return *this;
1221 }
1222 1 iterator operator--(int)
1223 {
1224 1 iterator tmp(*this);
1225
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 --(*this);
1226 1 return tmp;
1227 }
1228 };
1229
1230 class const_iterator
1231 {
1232 protected:
1233 gate_linkedentry_t const* ptr_entry;
1234
1235 public:
1236 14 const_iterator(gate_linkedentry_t const* entry) noexcept : ptr_entry(entry) {}
1237 4 const_iterator(const_iterator const& src) noexcept : ptr_entry(src.ptr_entry) {}
1238 1 const_iterator& operator=(const_iterator const& src) noexcept
1239 {
1240 1 this->ptr_entry = src.ptr_entry;
1241 1 return *this;
1242 }
1243 18 ~const_iterator() noexcept {}
1244
1245 gate_linkedentry_t const* c_impl() const noexcept { return this->ptr_entry; }
1246
1247 31 item_t const* getPtr() const noexcept
1248 {
1249
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 12 times.
31 return this->ptr_entry ? static_cast<item_t const*>(this->ptr_entry->data) : NULL;
1250 }
1251 9 item_t const& get() const noexcept
1252 {
1253 9 item_t const* const ptr = this->getPtr();
1254 #ifdef GATE_DEBUG_MODE
1255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (!ptr)
1256 {
1257 ✗ panic(results::NullPointer, "LinkedList::const_iterator::get");
1258 }
1259 #endif
1260 9 return *ptr;
1261 }
1262
1263 item_t const* operator->() const noexcept { return this->getPtr(); }
1264 9 item_t const& operator*() const noexcept { return this->get(); }
1265
1266 5 bool operator==(const_iterator const& src) const { return this->getPtr() == src.getPtr(); }
1267 6 bool operator!=(const_iterator const& src) const { return this->getPtr() != src.getPtr(); }
1268 6 const_iterator& operator++()
1269 {
1270 6 this->ptr_entry = gate_linkedlist_next(this->ptr_entry);
1271 6 return *this;
1272 }
1273 1 const_iterator operator++(int)
1274 {
1275 1 const_iterator tmp(*this);
1276
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ++(*this);
1277 1 return tmp;
1278 }
1279 2 const_iterator& operator--()
1280 {
1281 2 this->ptr_entry = gate_linkedlist_previous(this->ptr_entry);
1282 2 return *this;
1283 }
1284 1 const_iterator operator--(int)
1285 {
1286 1 const_iterator tmp(*this);
1287
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 --(*this);
1288 1 return tmp;
1289 }
1290 };
1291
1292 class reverse_iterator : public iterator
1293 {
1294 public:
1295 13 reverse_iterator(gate_linkedentry_t* entry) noexcept : iterator(entry) {}
1296 2 reverse_iterator(reverse_iterator const& src) noexcept : iterator(src) {}
1297 reverse_iterator& operator=(reverse_iterator const& src) noexcept
1298 {
1299 this->ptr_entry = src.ptr_entry;
1300 return *this;
1301 }
1302
1303 2 reverse_iterator& operator--()
1304 {
1305 2 this->ptr_entry = gate_linkedlist_next(this->ptr_entry);
1306 2 return *this;
1307 }
1308 1 reverse_iterator operator--(int)
1309 {
1310 1 reverse_iterator tmp(*this);
1311
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 --(*this);
1312 1 return tmp;
1313 }
1314 3 reverse_iterator& operator++()
1315 {
1316 3 this->ptr_entry = gate_linkedlist_previous(this->ptr_entry);
1317 3 return *this;
1318 }
1319 1 reverse_iterator operator++(int)
1320 {
1321 1 reverse_iterator tmp(*this);
1322
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ++(*this);
1323 1 return tmp;
1324 }
1325 };
1326
1327 class const_reverse_iterator : public const_iterator
1328 {
1329 public:
1330 6 const_reverse_iterator(gate_linkedentry_t const* entry) noexcept : const_iterator(entry) {}
1331 2 const_reverse_iterator(const_reverse_iterator const& src) noexcept : const_iterator(src) {}
1332 const_reverse_iterator& operator=(const_reverse_iterator const& src) noexcept
1333 {
1334 this->ptr_entry = src.ptr_entry;
1335 return *this;
1336 }
1337
1338 2 const_reverse_iterator& operator--()
1339 {
1340 2 this->ptr_entry = gate_linkedlist_next(this->ptr_entry);
1341 2 return *this;
1342 }
1343 1 const_reverse_iterator operator--(int)
1344 {
1345 1 const_reverse_iterator tmp(*this);
1346
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 --(*this);
1347 1 return tmp;
1348 }
1349 3 const_reverse_iterator& operator++()
1350 {
1351 3 this->ptr_entry = gate_linkedlist_previous(this->ptr_entry);
1352 3 return *this;
1353 }
1354 1 const_reverse_iterator operator++(int)
1355 {
1356 1 const_reverse_iterator tmp(*this);
1357
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ++(*this);
1358 1 return tmp;
1359 }
1360 };
1361
1362 private:
1363 gate_linkedlist_t impl;
1364
1365 public:
1366 1 LinkedList() noexcept
1367 {
1368 1 result_t ret = gate_linkedlist_create(&this->impl, sizeof(T), &TypeFunctions<T>::copyConstruct, &TypeFunctions<T>::destruct);
1369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATEXX_CHECK_ERROR(ret);
1370 1 }
1371 3 LinkedList(self_t const& src)
1372 {
1373 3 result_t ret = gate_linkedlist_create(&this->impl, sizeof(T), &TypeFunctions<T>::copyConstruct, &TypeFunctions<T>::destruct);
1374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATEXX_CHECK_ERROR(ret);
1375
1376 3 gate_linkedentry_t* entry = gate_linkedlist_first(&src.impl);
1377
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 while (entry != NULL)
1378 {
1379
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (NULL == gate_linkedlist_add(&this->impl, entry->data))
1380 {
1381 ✗ gate_linkedlist_destroy(&this->impl);
1382 ✗ GATEXX_RAISE_ERROR(results::OutOfMemory);
1383 }
1384 6 entry = gate_linkedlist_next(entry);
1385 }
1386 3 }
1387 1 void swap(self_t& that) noexcept
1388 {
1389 1 gate::swapRefsNoExcept(this->impl, that.impl);
1390 1 }
1391 1 self_t& operator=(self_t const& src)
1392 {
1393
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &src)
1394 {
1395
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 self_t that(src);
1396 1 this->swap(that);
1397 }
1398 1 return *this;
1399 }
1400 4 ~LinkedList() noexcept
1401 {
1402 4 gate_linkedlist_destroy(&this->impl);
1403 4 }
1404
1405 3 iterator add(item_t const& item) noexcept
1406 {
1407 3 gate_linkedentry_t* ptr_entry = gate_linkedlist_add(&this->impl, &item);
1408 3 return iterator(ptr_entry);
1409 }
1410
1411 1 iterator insert(iterator insertAt, item_t const& item) noexcept
1412 {
1413 1 gate_linkedentry_t* ptr_entry = gate_linkedlist_insert(&this->impl, insertAt.c_impl(), &item);
1414 1 return iterator(ptr_entry);
1415 }
1416
1417 4 VoidResult remove(iterator iter) noexcept
1418 {
1419 4 result_t result = gate_linkedlist_remove(&this->impl, iter.c_impl());
1420 4 return makeResult(result);
1421 }
1422
1423 5 bool_t empty() const noexcept
1424 {
1425 5 return gate_linkedlist_empty(&this->impl);
1426 }
1427
1428 3 iterator begin() noexcept
1429 {
1430 3 gate_linkedentry_t* ptr = gate_linkedlist_first(&this->impl);
1431 3 return iterator(ptr);
1432 }
1433 4 iterator end() noexcept
1434 {
1435 4 return iterator(NULL);
1436 }
1437 3 const_iterator cbegin() const noexcept
1438 {
1439 3 gate_linkedentry_t const* ptr = gate_linkedlist_first(&this->impl);
1440 3 return const_iterator(ptr);
1441 }
1442 5 const_iterator cend() const noexcept
1443 {
1444 5 return const_iterator(NULL);
1445 }
1446 1 const_iterator begin() const noexcept { return this->cbegin(); }
1447 const_iterator end() const noexcept { return this->cend(); }
1448
1449 6 reverse_iterator rbegin() noexcept
1450 {
1451 6 gate_linkedentry_t* const ptr = gate_linkedlist_last(&this->impl);
1452 6 return reverse_iterator(ptr);
1453 }
1454 7 reverse_iterator rend() noexcept
1455 {
1456 7 return reverse_iterator(NULL);
1457 }
1458 2 const_reverse_iterator crbegin() const noexcept
1459 {
1460 2 gate_linkedentry_t const* const ptr = gate_linkedlist_last(&this->impl);
1461 2 return const_reverse_iterator(ptr);
1462 }
1463 4 const_reverse_iterator crend() const noexcept
1464 {
1465 4 return const_reverse_iterator(NULL);
1466 }
1467 const_reverse_iterator rbegin() const noexcept { return this->crbegin(); }
1468 const_reverse_iterator rend() const noexcept { return this->crend(); }
1469
1470 3 iterator push(item_t const& item) noexcept
1471 {
1472 3 return this->add(item);
1473 }
1474 3 item_t pop()
1475 {
1476 3 reverse_iterator iter = this->rbegin();
1477
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 if (iter == this->rend())
1478 {
1479 ✗ GATEXX_RAISE_ERROR(results::NotAvailable);
1480 }
1481 3 item_t ret = *iter;
1482 3 this->remove(iter);
1483 6 return ret;
1484 }
1485
1486 1 Enumerator<item_t const> enumerate() const noexcept
1487 {
1488 gate_enumerator_t e;
1489 1 gate_enumerator_t* tmp = gate_linkedlist_enumerate(&this->impl, &e);
1490 #ifdef GATE_DEBUG_MODE
1491
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tmp)
1492 {
1493 ✗ panic(results::NullPointer, "LinkedList::enumerate");
1494 }
1495 #else
1496 (void)tmp;
1497 #endif
1498 1 return Enumerator<item_t const>(e);
1499 }
1500
1501 3 self_t& operator<<(item_t const& item)
1502 {
1503 3 this->push(item);
1504 3 return *this;
1505 }
1506 3 self_t& operator>>(item_t& item)
1507 {
1508 3 item = this->pop();
1509 3 return *this;
1510 }
1511 };
1512
1513 } // end of namespace gate
1514
1515 #endif
1516