GCC Code Coverage Report


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