GCC Code Coverage Report


Directory: src/gate/
File: src/gate/arrays.hpp
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 570 613 93.0%
Functions: 639 1012 63.1%
Branches: 117 203 57.6%

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