GCC Code Coverage Report


Directory: src/gate/
File: src/gate/arrays.hpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 594 635 93.5%
Functions: 514 1095 46.9%
Branches: 102 173 59.0%

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