GCC Code Coverage Report


Directory: src/gate/
File: src/gate/wrappers.hpp
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 256 322 79.5%
Functions: 100 185 54.1%
Branches: 45 84 53.6%

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 Wrappers and smart pointer objects
31 * @ingroup gatecore_cpp
32 */
33
34 #ifndef GATE_WRAPPERS_HPP_INCLUDED
35 #define GATE_WRAPPERS_HPP_INCLUDED
36
37 #include "gate/gate_core_api.hpp"
38 #include "gate/wrappers.h"
39 #include "gate/atomics.h"
40 #include "gate/gatetypes.hpp"
41 #include "gate/results.hpp"
42 #include "gate/exceptions.hpp"
43 #include "gate/memalloc.hpp"
44 #include "gate/delegates.hpp"
45 #include <typeinfo>
46
47 namespace gate
48 {
49
50 /// @brief
51 /// @tparam T
52 template<class T>
53 class GATE_CORE_CPP_API Ptr : public SafeBoolBase< Ptr<T> >
54 {
55 public:
56 typedef Ptr<T> self_t;
57 typedef T value_t;
58 typedef T const* const_ptr_t;
59 typedef T* ptr_t;
60 typedef T const& const_ref_t;
61 typedef T& ref_t;
62
63
64 private:
65 ptr_t ptr;
66
67 public:
68
69 52 Ptr(ptr_t newInstance = NULL) noexcept
70 52 : ptr(newInstance)
71 {
72 52 }
73 54 void reset(ptr_t newInstance = NULL) noexcept
74 {
75
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 19 times.
54 delete this->ptr;
76 54 this->ptr = newInstance;
77 54 }
78 52 ~Ptr() noexcept
79 {
80 52 this->reset();
81 52 }
82 void swap(self_t& that) noexcept
83 {
84 gate::swapRefsNoExcept(this->ptr, that.ptr);
85 }
86 27 ptr_t release() noexcept
87 {
88 27 ptr_t tmp = this->ptr;
89 27 this->ptr = NULL;
90 27 return tmp;
91 }
92 48 ptr_t get() const noexcept
93 {
94 48 return this->ptr;
95 }
96 const_ptr_t operator->() const noexcept
97 {
98 GATE_DEBUG_ASSERT(this->hasValue());
99 return this->get();
100 }
101 9 ptr_t operator->() noexcept
102 {
103 9 GATE_DEBUG_ASSERT(this->hasValue());
104 9 return this->get();
105 }
106 const_ref_t operator*() const noexcept
107 {
108 GATE_DEBUG_ASSERT(this->hasValue());
109 return *this->get();
110 }
111 1 ref_t operator*() noexcept
112 {
113 1 GATE_DEBUG_ASSERT(this->hasValue());
114 1 return *this->get();
115 }
116
117 4 bool_t empty() const noexcept
118 {
119 4 return this->ptr == NULL;
120 }
121 12 bool_t hasValue() const noexcept
122 {
123 12 return this->ptr != NULL;
124 }
125
126 2 self_t const& andThen(Delegate1<value_t&> const& callback) const
127 {
128
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (this->ptr != NULL)
129 {
130 1 callback.invoke(*this->ptr);
131 }
132 2 return *this;
133 }
134 2 self_t const& orElse(Delegate0 const& callback) const
135 {
136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (this->ptr == NULL)
137 {
138 1 callback.invoke();
139 }
140 2 return *this;
141 }
142 2 self_t const& orThrow() const
143 {
144
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (this->ptr == NULL)
145 {
146 1 GATEXX_RAISE_ERROR(results::NullPointer);
147 }
148 1 return *this;
149 }
150
151 ref_t value() noexcept
152 {
153 GATE_DEBUG_ASSERT(this->ptr != NULL);
154 return *this->ptr;
155 }
156 const_ref_t value() const noexcept
157 {
158 GATE_DEBUG_ASSERT(this->ptr != NULL);
159 return *this->ptr;
160 }
161
162 const_ref_t value(const_ref_t defaultValue) const
163 {
164 if (this->ptr)
165 {
166 return defaultValue;
167 }
168 else
169 {
170 return *this->ptr;
171 }
172 }
173
174 bool_t operator!() const noexcept
175 {
176 return this->empty();
177 }
178
179
180 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
181 Ptr(self_t&& src) noexcept
182 : ptr(src.ptr)
183 {
184 src.ptr = NULL;
185 }
186 self_t& operator=(self_t&& src) noexcept
187 {
188 if (this != &src)
189 {
190 this->reset(src.ptr);
191 src.ptr = NULL;
192 }
193 return *this;
194 }
195 private: // new compilers will see copy-ctor and op= private
196 Ptr(self_t const& src) noexcept;
197 self_t& operator=(self_t const& src) noexcept;
198 public:
199 #else
200 Ptr(self_t const& src) noexcept
201 : ptr(src.ptr)
202 {
203 // dirty hack for old compilers: swap on copy-construction
204 const_cast<self_t&>(src).ptr = NULL;
205 }
206 self_t& operator=(self_t const& src) noexcept
207 {
208 if (this != &src)
209 {
210 // dirty hack for old compilers: transfer ownership on assignment
211 this->reset(src.ptr);
212 const_cast<self_t&>(src).ptr = NULL;
213 }
214 return *this;
215 }
216 #endif
217 };
218
219
220 /// @brief
221 /// @tparam T
222 template<class T>
223 class GATE_CORE_CPP_API Optional : public SafeBoolBase<Optional<T> >
224 {
225 public:
226 typedef T value_t;
227 typedef T* ptr_t;
228 typedef T const* const_ptr_t;
229 typedef T& ref_t;
230 typedef T const& const_ref_t;
231 typedef Optional<T> self_t;
232 private:
233 union
234 {
235 gate_c_maxalign_t dummy;
236 char buffer[sizeof(value_t)];
237 };
238
239 ptr_t ptr; // points to initialized value in buffer, or NULL if empty
240 public:
241 8 Optional()
242 8 : ptr(0)
243 {
244 8 Mem::clear(&this->buffer[0], sizeof(this->buffer));
245 8 }
246
247 17 void reset() noexcept
248 {
249
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 11 times.
17 if (this->ptr)
250 {
251 6 this->ptr->~T();
252 6 this->ptr = NULL;
253 }
254 17 }
255
256 self_t& create()
257 {
258 this->reset();
259 ptr_t p = reinterpret_cast<ptr_t>(&this->buffer[0]);
260 constructType(p);
261 this->ptr = p;
262 return *this;
263 }
264 6 self_t& create(const_ref_t src)
265 {
266 6 this->reset();
267 6 ptr_t p = reinterpret_cast<ptr_t>(&this->buffer[0]);
268 6 copyConstructType(p, src);
269 6 this->ptr = p;
270 6 return *this;
271 }
272
273 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
274 template<class A1> void emplace(A1&& a1)
275 {
276 this->reset();
277 new (&buffer[0]) T(forwardRef<A1>(a1));
278 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
279 }
280 template<class A1, class A2> void emplace(A1&& a1, A2&& a2)
281 {
282 this->reset();
283 new (&buffer[0]) T(forwardRef<A1>(a1), forwardRef<A2>(a2));
284 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
285 }
286 template<class A1, class A2, class A3> void emplace(A1&& a1, A2&& a2, A3&& a3)
287 {
288 this->reset();
289 new (&buffer[0]) T(forwardRef<A1>(a1), forwardRef<A2>(a2), forwardRef<A3>(a3));
290 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
291 }
292 template<class A1, class A2, class A3, class A4> void emplace(A1&& a1, A2&& a2, A3&& a3, A4&& a4)
293 {
294 this->reset();
295 new (&buffer[0]) T(forwardRef<A1>(a1), forwardRef<A2>(a2), forwardRef<A3>(a3), forwardRef<A4>(a4));
296 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
297 }
298 template<class A1, class A2, class A3, class A4, class A5> void emplace(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5)
299 {
300 this->reset();
301 new (&buffer[0]) T(forwardRef<A1>(a1), forwardRef<A2>(a2), forwardRef<A3>(a3), forwardRef<A4>(a4), forwardRef<A5>(a5));
302 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
303 }
304 template<class A1, class A2, class A3, class A4, class A5, class A6> void emplace(A1&& a1, A2&& a2, A3&& a3, A4&& a4, A5&& a5, A6&& a6)
305 {
306 this->reset();
307 new (&buffer[0]) T(forwardRef<A1>(a1), forwardRef<A2>(a2), forwardRef<A3>(a3), forwardRef<A4>(a4), forwardRef<A5>(a5), forwardRef<A6>(a6));
308 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
309 }
310 #else
311 template<class A1> void emplace(A1& a1)
312 {
313 this->reset();
314 new (&buffer[0]) T(a1);
315 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
316 }
317 template<class A1, class A2> void emplace(A1& a1, A2& a2)
318 {
319 this->reset();
320 new (&buffer[0]) T(a1, a2);
321 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
322 }
323 template<class A1, class A2, class A3> void emplace(A1& a1, A2& a2, A3& a3)
324 {
325 this->reset();
326 new (&buffer[0]) T(a1, a2, a3);
327 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
328 }
329 template<class A1, class A2, class A3, class A4> void emplace(A1& a1, A2& a2, A3& a3, A4& a4)
330 {
331 this->reset();
332 new (&buffer[0]) T(a1, a2, a3, a4);
333 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
334 }
335 template<class A1, class A2, class A3, class A4, class A5> void emplace(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5)
336 {
337 this->reset();
338 new (&buffer[0]) T(a1, a2, a3, a4, a5);
339 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
340 }
341 template<class A1, class A2, class A3, class A4, class A5, class A6> void emplace(A1& a1, A2& a2, A3& a3, A4& a4, A5& a5, A6& a6)
342 {
343 this->reset();
344 new (&buffer[0]) T(a1, a2, a3, a4, a5, a6);
345 this->ptr = reinterpret_cast<T*>(&this->buffer[0]);
346 }
347 #endif
348
349 7 ptr_t get() const noexcept
350 {
351 7 return this->ptr;
352 }
353
354 7 bool_t empty() const noexcept
355 {
356 7 return this->ptr == NULL;
357 }
358
359 5 bool_t hasValue() const noexcept
360 {
361 5 return this->ptr != NULL;
362 }
363
364 1 ref_t value() noexcept
365 {
366 1 GATE_DEBUG_ASSERT(this->ptr != NULL);
367 1 return *this->ptr;
368 }
369
370 const_ref_t value() const noexcept
371 {
372 GATE_DEBUG_ASSERT(this->ptr != NULL);
373 return *this->ptr;
374 }
375
376 1 const_ref_t value(const_ref_t defaultValue) const
377 {
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (this->ptr == NULL)
379 {
380 return defaultValue;
381 }
382 else
383 {
384 1 return *this->ptr;
385 }
386 }
387
388 ptr_t operator->() noexcept
389 {
390 GATE_DEBUG_ASSERT(this->hasValue());
391 return this->get();
392 }
393 const_ptr_t operator->() const noexcept
394 {
395 GATE_DEBUG_ASSERT(this->hasValue());
396 return this->get();
397 }
398 3 ref_t operator*() noexcept
399 {
400 3 GATE_DEBUG_ASSERT(this->hasValue());
401 3 return *this->get();
402 }
403 const_ref_t operator*() const noexcept
404 {
405 GATE_DEBUG_ASSERT(this->hasValue());
406 return *this->get();
407 }
408
409 4 self_t const& andThen(Delegate1<value_t&> const& callback) const
410 {
411
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (this->ptr != NULL)
412 {
413 2 callback.invoke(*this->ptr);
414 }
415 4 return *this;
416 }
417 4 self_t const& orElse(Delegate0 const& callback) const
418 {
419
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (this->ptr == NULL)
420 {
421 2 callback.invoke();
422 }
423 4 return *this;
424 }
425 2 self_t const& orThrow() const
426 {
427
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (this->ptr == NULL)
428 {
429 1 GATEXX_RAISE_ERROR(results::NullPointer);
430 }
431 1 return *this;
432 }
433
434 bool_t operator!() const noexcept
435 {
436 return this->empty();
437 }
438
439 8 ~Optional() noexcept
440 {
441 8 this->reset();
442 8 }
443
444 Optional(self_t const& src)
445 : ptr(0)
446 {
447 gate_mem_clear(&this->buffer[0], sizeof(this->buffer));
448
449 if (!src.empty())
450 {
451 this->create(*src.get());
452 }
453 }
454
455 Optional(const_ref_t native_src)
456 : ptr(0)
457 {
458 gate_mem_clear(&this->buffer[0], sizeof(this->buffer));
459 this->create(native_src);
460 }
461
462 2 self_t& operator=(self_t const& src)
463 {
464
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (this != &src)
465 {
466 2 this->reset();
467
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (!src.empty())
468 {
469 2 this->create(*src.get());
470 }
471 }
472 2 return *this;
473 }
474 };
475
476 /// @brief
477 /// @tparam T
478 /// @tparam E
479 template<class T, class E>
480 class GATE_CORE_CPP_API Expected
481 {
482 public:
483 typedef T value_t;
484 typedef T* ptr_t;
485 typedef T const* const_ptr_t;
486 typedef T& ref_t;
487 typedef T const& const_ref_t;
488
489 typedef E error_t;
490 typedef Expected<value_t, error_t> self_t;
491
492 private:
493 union
494 {
495 gate_c_maxalign_t dummy;
496 char bufferValue[sizeof(value_t)];
497 char bufferError[sizeof(error_t)];
498 };
499 value_t* ptr; // pointer to expected value, or NULL if unexpected
500 #if defined(GATE_DEBUG_MODE)
501 error_t* ptrError; // pointer to unexpected value, or NULL if expected (just for debugging in IDEs)
502 #endif
503
504 2 void constructValue(value_t const& expectedValue)
505 {
506 2 ptr_t p = reinterpret_cast<ptr_t>(&this->bufferValue[0]);
507 2 copyConstructType(p, expectedValue);
508 2 this->ptr = p;
509 #if defined(GATE_DEBUG_MODE)
510 2 this->ptrError = NULL;
511 #endif
512 2 }
513 2 void constructError(error_t const& unexpectedValue)
514 {
515 2 error_t* p = reinterpret_cast<error_t*>(&this->bufferError[0]);
516 2 copyConstructType(p, unexpectedValue);
517 2 this->ptr = NULL;
518 #if defined(GATE_DEBUG_MODE)
519 2 this->ptrError = p;
520 #endif
521 2 }
522 4 void destruct() noexcept
523 {
524
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (this->ptr)
525 {
526 2 destructType(this->ptr);
527 2 this->ptr = NULL;
528 }
529 else
530 {
531 2 error_t* p = reinterpret_cast<error_t*>(&this->bufferError[0]);
532 2 destructType(p);
533 }
534 4 }
535
536 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
537 void moveConstruct(GATE_MOVEREF(self_t) src)
538 {
539 if (src.hasValue())
540 {
541 ptr_t p = reinterpret_cast<ptr_t>(&this->bufferValue[0]);
542 moveConstructType(p, src.value());
543 this->ptr = p;
544 #if defined(GATE_DEBUG_MODE)
545 this->ptrError = NULL;
546 #endif
547 }
548 else
549 {
550 error_t* p = reinterpret_cast<error_t*>(&this->bufferError[0]);
551 moveConstructType(p, src.error());
552 this->ptr = NULL;
553 #if defined(GATE_DEBUG_MODE)
554 this->ptrError = p;
555 #endif
556 }
557 }
558 #endif
559
560 public:
561 2 Expected(value_t const& expectedValue)
562 : dummy()
563 , ptr(NULL)
564 #if defined(GATE_DEBUG_MODE)
565 2 , ptrError(NULL)
566 #endif
567 {
568 2 constructValue(expectedValue);
569 2 }
570
571 2 Expected(error_t const& unexpectedValue)
572 : dummy()
573 , ptr(NULL)
574 #if defined(GATE_DEBUG_MODE)
575 2 , ptrError(NULL)
576 #endif
577 {
578 2 constructError(unexpectedValue);
579 2 }
580
581 Expected(self_t const& src)
582 {
583 if (src.hasValue())
584 {
585 constructValue(src.value());
586 }
587 else
588 {
589 constructError(src.error());
590 }
591 }
592
593 self_t& operator=(self_t const& src)
594 {
595 if (this != &src)
596 {
597 self_t backup(*this);
598 destruct();
599
600 try
601 {
602 if (src.hasValue())
603 {
604 constructValue(src.value());
605 }
606 else
607 {
608 constructError(src.error());
609 }
610 }
611 catch (...)
612 {
613 // try to restore backup:
614 if (backup.hasValue())
615 {
616 constructValue(backup.value());
617 }
618 else
619 {
620 constructError(backup.error());
621 }
622 throw;
623 }
624 }
625 return *this;
626 }
627
628 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
629 Expected(GATE_MOVEREF(self_t) src)
630 {
631 moveConstruct(moveRef(src));
632 }
633
634 self_t& operator=(GATE_MOVEREF(self_t) src)
635 {
636 if (this != &src)
637 {
638 destruct();
639 moveConstruct(moveRef(src));
640 }
641 return *this;
642 }
643 #endif
644
645 4 ~Expected() noexcept
646 {
647 4 this->destruct();
648 4 }
649
650 20 value_t* get() const noexcept
651 {
652 20 return this->ptr;
653 }
654
655 14 bool hasValue() const noexcept
656 {
657 14 return this->get() != NULL;
658 }
659 bool empty() const noexcept
660 {
661 return this->get() == NULL;
662 }
663
664 1 ref_t value() noexcept
665 {
666 1 return *this->get();
667 }
668 1 const_ref_t value() const noexcept
669 {
670 1 return *this->get();
671 }
672 2 const_ref_t value(const_ref_t defaultValue) const
673 {
674
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (this->hasValue())
675 {
676 1 return this->value();
677 }
678 else
679 {
680 1 return defaultValue;
681 }
682 }
683
684 3 error_t* getErrorPtr() const noexcept
685 {
686
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (this->hasValue())
687 {
688 1 return NULL;
689 }
690 else
691 {
692 2 return const_cast<error_t*>(reinterpret_cast<error_t const*>(&this->bufferError[0]));
693 }
694 }
695 1 error_t& error() noexcept
696 {
697 1 return *reinterpret_cast<error_t*>(&this->bufferError[0]);
698 }
699 error_t const& error() const noexcept
700 {
701 return *reinterpret_cast<error_t const*>(&this->bufferError[0]);
702 }
703
704 1 value_t* operator->() noexcept
705 {
706 1 GATE_DEBUG_ASSERT(this->hasValue());
707 1 return this->get();
708 }
709 value_t const* operator->() const noexcept
710 {
711 GATE_DEBUG_ASSERT(this->hasValue());
712 return this->get();
713 }
714
715 value_t& operator*() noexcept
716 {
717 GATE_DEBUG_ASSERT(this->hasValue());
718 return *this->get();
719 }
720 value_t const& operator*() const noexcept
721 {
722 GATE_DEBUG_ASSERT(this->hasValue());
723 return *this->get();
724 }
725
726 bool operator!() const noexcept
727 {
728 return this->empty();
729 }
730
731 2 self_t const& andThen(Delegate1<value_t&> const& callback) const
732 {
733
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (this->hasValue())
734 {
735 1 callback.invoke(*this->get());
736 }
737 2 return *this;
738 }
739 2 self_t const& orElse(Delegate1<error_t&> const& callback) const
740 {
741
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (!this->hasValue())
742 {
743 1 callback.invoke(*this->getErrorPtr());
744 }
745 2 return *this;
746 }
747 2 self_t const& orThrow() const
748 {
749
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 if (!this->hasValue())
750 {
751 1 GATEXX_RAISE_ERROR(results::NullPointer);
752 }
753 1 return *this;
754 }
755 };
756
757
758 /// @brief
759 class GATE_CORE_CPP_API WrapperBase
760 {
761 public:
762 static gate_wrapper_t* createCppWrapper(size_t typeSize, std::type_info const& typeInfo, gate_mem_dtor_t dtor);
763 };
764
765 template<class T>
766 class GATE_CORE_CPP_API Wrapper : public SafeBoolBase< Wrapper<T> >
767 {
768 public:
769 typedef T value_t;
770 typedef T* ptr_t;
771 typedef T const* const_ptr_t;
772 typedef T& ref_t;
773 typedef T const& const_ref_t;
774 typedef Wrapper<T> self_t;
775
776 private:
777 gate_wrapper_t* impl;
778 ptr_t ptr;
779
780 private:
781 2 static void destruct_external_cpp(void* ptr)
782 {
783 2 T* ptr_external = static_cast<T*>(ptr);
784
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 delete ptr_external;
785 2 }
786
787 public:
788 2 Wrapper()
789 2 : impl(NULL), ptr(NULL)
790 {
791 2 }
792 Wrapper(gate_wrapper_t* wrapper) noexcept
793 : impl(wrapper), ptr(NULL)
794 {
795 if (wrapper != NULL)
796 {
797 void* content_ptr = gate_memoryblock_get_content(wrapper);
798 this->ptr = static_cast<ptr_t>(content_ptr);
799 }
800 }
801 Wrapper(gate_wrapper_t* wrapper, T* ptr_content)
802 : impl(wrapper), ptr(ptr_content)
803 {
804 }
805 5 Wrapper(self_t const& src)
806 5 : impl(src.impl), ptr(src.ptr)
807 {
808
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (this->impl)
809 {
810 5 gate_object_retain(this->impl);
811 }
812 5 }
813 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
814 2 Wrapper(Ptr<T>&& src)
815 #else
816 Wrapper(Ptr<T>& src)
817 #endif
818 : impl(NULL),
819 2 ptr(NULL)
820 {
821 2 ptr_t local_ptr = src.get();
822 2 const std::type_info& ti = typeid(value_t);
823 2 this->impl = gate_wrapper_create(local_ptr, sizeof(value_t), ti.name(), &self_t::destruct_external_cpp, NULL);
824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (this->impl == NULL)
825 {
826 GATEXX_RAISE_ERROR(results::OutOfMemory);
827 }
828 else
829 {
830 2 void* content_ptr = gate_memoryblock_get_content(this->impl);
831 2 this->ptr = static_cast<ptr_t>(content_ptr);
832 2 src.release();
833 }
834 2 }
835
836 9 ~Wrapper() noexcept
837 {
838
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 if (this->impl)
839 {
840 7 gate_object_release(this->impl);
841 }
842 #if defined(GATE_DEBUG_MODE)
843 9 this->ptr = NULL;
844 9 this->impl = NULL;
845 #endif
846 9 }
847 1 void swap(self_t& that)
848 {
849 1 gate::swapRefs(this->impl, that.impl);
850 1 gate::swapRefs(this->ptr, that.ptr);
851 1 }
852 1 self_t& operator=(self_t const& src)
853 {
854
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &src)
855 {
856
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 self_t that(src);
857
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 this->swap(that);
858 }
859 1 return *this;
860 }
861 4 bool hasValue() const noexcept
862 {
863 4 return this->ptr != NULL;
864 }
865 3 bool empty() const noexcept
866 {
867 3 return this->ptr == NULL;
868 }
869 1 bool operator!() const noexcept
870 {
871 1 return this->ptr == NULL;
872 }
873
874 5 ptr_t get() const noexcept
875 {
876 5 return this->ptr;
877 }
878
879 2 ref_t value() noexcept
880 {
881 2 return *this->get();
882 }
883 const_ref_t value() const noexcept
884 {
885 return *this->get();
886 }
887
888 const_ref_t value(const_ref_t defaultValue) const
889 {
890 if (this->hasValue())
891 {
892 return *this->get();
893 }
894 else
895 {
896 return defaultValue;
897 }
898 }
899
900 void const* type() const noexcept
901 {
902 return gate_wrapper_get_type(this->impl);
903 }
904 bool equalsTypeOf(self_t const& that) const noexcept
905 {
906 return gate_wrapper_is_type(this->impl, that.getType());
907 }
908 2 size_t size() const noexcept
909 {
910 2 return sizeof(value_t);
911 }
912
913 self_t const& andThen(Delegate1<value_t&> const& callback) const
914 {
915 if (this->hasValue())
916 {
917 callback.invoke(*this->get());
918 }
919 return *this;
920 }
921 self_t const& orElse(Delegate0 const& callback) const
922 {
923 if (!this->hasValue())
924 {
925 callback.invoke();
926 }
927 return *this;
928 }
929 self_t const& orThrow() const
930 {
931 if (!this->hasValue())
932 {
933 GATEXX_RAISE_ERROR(results::NullPointer);
934 }
935 return *this;
936 }
937
938
939 1 ptr_t operator->() noexcept
940 {
941 1 GATE_DEBUG_ASSERT(this->hasValue());
942 1 return this->get();
943 }
944 const_ptr_t operator->() const noexcept
945 {
946 GATE_DEBUG_ASSERT(this->hasValue());
947 return this->get();
948 }
949 ref_t operator*() noexcept
950 {
951 GATE_DEBUG_ASSERT(this->hasValue());
952 return *this->get();
953 }
954 const_ref_t operator*() const noexcept
955 {
956 GATE_DEBUG_ASSERT(this->hasValue());
957 return *this->get();
958 }
959 bool operator==(self_t const& that) const noexcept
960 {
961 return (this->impl == that.impl);
962 }
963 bool operator!=(self_t const& that) const noexcept
964 {
965 return (this->impl != that.impl);
966 }
967 bool operator<(self_t const& that) const noexcept
968 {
969 return this->impl < that.impl;
970 }
971 bool operator<=(self_t const& that) const noexcept
972 {
973 return this->impl <= that.impl;
974 }
975 bool operator>(self_t const& that) const noexcept
976 {
977 return this->impl > that.impl;
978 }
979 bool operator>=(self_t const& that) const noexcept
980 {
981 return this->impl >= that.impl;
982 }
983
984
985 Wrapper(ptr_t ptr_external, gate_mem_dtor_t specialDestructor = NULL)
986 : impl(NULL), ptr(NULL)
987 {
988 void* content_ptr = NULL;
989 const std::type_info& ti = typeid(value_t);
990 this->impl = gate_wrapper_create(ptr_external, sizeof(value_t), ti.name(),
991 specialDestructor == NULL ? &self_t::destruct_external_cpp : specialDestructor,
992 NULL);
993 if (this->impl == NULL)
994 {
995 GATEXX_RAISE_ERROR(results::NullPointer);
996 }
997 else
998 {
999 content_ptr = gate_memoryblock_get_content(this->impl);
1000 }
1001 this->ptr = static_cast<ptr_t>(content_ptr);
1002 }
1003
1004 static self_t create(value_t const& src)
1005 {
1006 const std::type_info& ti = typeid(value_t);
1007 gate_wrapper_t* wrapper = gate_wrapper_create_new(
1008 sizeof(value_t), ti.name(),
1009 &TypeFunctions<value_t>::destruct);
1010 void* content_ptr = gate_memoryblock_get_content(wrapper);
1011 try
1012 {
1013 TypeFunctions<value_t>::copyConstruct(content_ptr, &src);
1014 }
1015 catch (...)
1016 {
1017 gate_mem_dealloc(wrapper);
1018 throw;
1019 }
1020 self_t ret;
1021 ret.impl = wrapper;
1022 ret.ptr = static_cast<ptr_t>(content_ptr);
1023 return ret;
1024 }
1025
1026 static self_t fromPtr(ptr_t ptr)
1027 {
1028 Ptr<T> ptrwrapper(ptr);
1029 self_t ret(gate::moveRef(ptrwrapper));
1030 return ret;
1031 }
1032
1033 template<class U> Wrapper<U> staticCastTo() const
1034 {
1035 Wrapper<U> ret(this->impl, static_cast<U*>(this->get()));
1036 if (this->impl)
1037 {
1038 gate_object_retain(this->impl);
1039 }
1040 return ret;
1041 }
1042
1043 template<class U> Wrapper<U> castTo() const
1044 {
1045 Wrapper<U> ret(this->impl, dynamic_cast<U*>(this->get()));
1046 if (this->impl)
1047 {
1048 gate_object_retain(this->impl);
1049 }
1050 return ret;
1051 }
1052 };
1053
1054 #if __cplusplus >= 201103
1055 template<class T>
1056 using Ref = Wrapper<T>;
1057
1058 #else
1059 // backwards compatibility with C++03/98
1060 template<class T>
1061 class Ref : public Wrapper<T>
1062 {
1063 public:
1064 typedef Wrapper<T> base_t;
1065 typedef Ref<T> self_t;
1066
1067 Ref()
1068 : base_t()
1069 {
1070 }
1071 Ref(self_t const& src)
1072 : base_t(src)
1073 {
1074 }
1075 Ref(base_t const& src)
1076 : base_t(src)
1077 {
1078 }
1079 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
1080 Ref(Ptr<T>&& src)
1081 #else
1082 Ref(Ptr<T>& src)
1083 #endif
1084 : base_t(gate::moveRef(src))
1085 {
1086 }
1087
1088 ~Ref() noexcept
1089 {
1090 }
1091 void swap(self_t& that)
1092 {
1093 base_t::swap(that);
1094 }
1095 self_t& operator=(self_t const& src)
1096 {
1097 if (this != &src)
1098 {
1099 self_t that(src);
1100 this->swap(that);
1101 }
1102 return *this;
1103 }
1104
1105 #if defined(GATE_COMPILER_SUPPORTS_CPP_MOVEREFS)
1106 self_t& operator=(Ptr<T>&& src)
1107 #else
1108 self_t& operator=(Ptr<T>& src)
1109 #endif
1110 {
1111 self_t that(gate::moveRef(src));
1112 this->swap(that);
1113 return *this;
1114 }
1115
1116 template<class U> Ref<U> staticCastTo() const
1117 {
1118 Wrapper<T> const& w = *this;
1119 Wrapper<U> u = w.staticCastTo<U>();
1120 return Ref<U>(u);
1121 }
1122
1123 template<class U> Ref<U> castTo()
1124 {
1125 Wrapper<T> const& w = *this;
1126 Wrapper<U> u = w.castTo<U>();
1127 return Ref<U>(u);
1128 }
1129
1130 };
1131
1132 #endif
1133
1134
1135 /// @brief
1136 class GATE_CORE_CPP_API Variant
1137 {
1138 protected:
1139 gate_variant_t* impl;
1140
1141 public:
1142 Variant(gate_variant_t* ptrVariant);
1143 Variant(Variant const& src);
1144 Variant& operator=(Variant const& src);
1145 ~Variant() noexcept;
1146
1147 gate_variant_t* c_impl() const;
1148
1149 size_t getSize() const;
1150 void const* getType() const;
1151
1152 1 template<class T> bool is() const noexcept
1153 {
1154 1 return (sizeof(T) == gate_variant_get_size(this->impl))
1155
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 && (&typeid(T) == gate_variant_get_type(this->impl));
1156 }
1157
1158 template<class T> T* get() noexcept
1159 {
1160 if (!this->is<T>())
1161 {
1162 return NULL;
1163 }
1164 return static_cast<T*>(gate_variant_get_content(this->impl));
1165 }
1166 template<class T> T const* get() const noexcept
1167 {
1168 if (!this->is<T>())
1169 {
1170 return NULL;
1171 }
1172 return static_cast<T const*>(gate_variant_get_content(this->impl));
1173 }
1174
1175 template<class T> T& value()
1176 {
1177 T* ptr = this->get<T>();
1178 if (!ptr)
1179 {
1180 GATEXX_RAISE_ERROR(results::IncorrectType);
1181 }
1182 return *ptr;
1183 }
1184 template<class T> T const& value() const
1185 {
1186 T const* ptr = this->get<T>();
1187 if (!ptr)
1188 {
1189 GATEXX_RAISE_ERROR(results::IncorrectType);
1190 }
1191 return *ptr;
1192 }
1193
1194 template<class T> void set(T const& value)
1195 {
1196 result_t result = gate_variant_set_content(this->impl, &value, sizeof(T), &typeid(T));
1197 GATEXX_CHECK_ERROR(result);
1198 }
1199 };
1200
1201
1202
1203 template<unsigned N>
1204 struct VariantNoneArg
1205 {
1206 };
1207
1208 /// @brief
1209 /// @tparam T0
1210 /// @tparam T1
1211 /// @tparam T2
1212 /// @tparam T3
1213 /// @tparam T4
1214 /// @tparam T5
1215 /// @tparam T6
1216 /// @tparam T7
1217 /// @tparam T8
1218 /// @tparam T9
1219 template<class T0,
1220 class T1 = VariantNoneArg<1>,
1221 class T2 = VariantNoneArg<2>,
1222 class T3 = VariantNoneArg<3>,
1223 class T4 = VariantNoneArg<4>,
1224 class T5 = VariantNoneArg<5>,
1225 class T6 = VariantNoneArg<6>,
1226 class T7 = VariantNoneArg<7>,
1227 class T8 = VariantNoneArg<8>,
1228 class T9 = VariantNoneArg<9>
1229 >
1230 class VariantType
1231 {
1232 public:
1233 typedef VariantType<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> self_t;
1234 private:
1235 size_t type_index;
1236 size_t type_size;
1237 std::type_info const* ptr_type;
1238 gate_mem_copyctor_t cctor;
1239 gate_mem_dtor_t dtor;
1240
1241 union
1242 {
1243 gate_c_maxalign_t alignment_dummy;
1244 char t0[sizeof(T0)];
1245 char t1[sizeof(T1)];
1246 char t2[sizeof(T2)];
1247 char t3[sizeof(T3)];
1248 char t4[sizeof(T4)];
1249 char t5[sizeof(T5)];
1250 char t6[sizeof(T6)];
1251 char t7[sizeof(T7)];
1252 char t8[sizeof(T8)];
1253 char t9[sizeof(T9)];
1254 } content;
1255
1256 2 template<class U> void copyConstruct(size_t index, U const& src)
1257 {
1258 2 this->type_index = index;
1259 2 this->type_size = sizeof(U);
1260 2 this->ptr_type = &typeid(U);
1261 2 this->cctor = &TypeFunctions<U>::copyConstruct;
1262 2 this->dtor = &TypeFunctions<U>::destruct;
1263 2 result_t result = this->cctor(&this->content, &src);
1264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 GATEXX_CHECK_ERROR(result);
1265 2 }
1266 1 void destruct()
1267 {
1268 1 this->dtor(&this->content);
1269 1 Mem::clear(this->content);
1270 1 }
1271 template<class U> self_t& assign(size_t index, U const& src)
1272 {
1273 this->destruct();
1274 this->copyConstruct(index, src);
1275 return *this;
1276 }
1277
1278 public:
1279
1280 VariantType() { this->copyConstruct(0, T0()); }
1281 VariantType(T0 const& t) { this->copyConstruct(0, t); }
1282 1 VariantType(T1 const& t) { this->copyConstruct(1, t); }
1283 VariantType(T2 const& t) { this->copyConstruct(2, t); }
1284 VariantType(T3 const& t) { this->copyConstruct(3, t); }
1285 VariantType(T4 const& t) { this->copyConstruct(4, t); }
1286 VariantType(T5 const& t) { this->copyConstruct(5, t); }
1287 VariantType(T6 const& t) { this->copyConstruct(6, t); }
1288 VariantType(T7 const& t) { this->copyConstruct(7, t); }
1289 VariantType(T8 const& t) { this->copyConstruct(8, t); }
1290 VariantType(T9 const& t) { this->copyConstruct(9, t); }
1291
1292 VariantType(self_t const& that)
1293 : type_index(that.type_index),
1294 type_size(that.type_size),
1295 ptr_type(that.ptr_type),
1296 cctor(that.cctor),
1297 dtor(that.dtor)
1298 {
1299 result_t result = this->cctor(&this->content, &that.content);
1300 GATEXX_CHECK_ERROR(result);
1301 }
1302
1303 self_t& operator=(self_t const& that)
1304 {
1305 if (this != &that)
1306 {
1307 this->destruct();
1308 this->type_index = that.type_index;
1309 this->type_size = that.type_size;
1310 this->ptr_type = that.ptr_type;
1311 this->cctor = that.cctor;
1312 this->dtor = that.dtor;
1313 result_t result = this->cctor(&this->content, &that.content);
1314 GATEXX_CHECK_ERROR(result);
1315 }
1316 return *this;
1317 }
1318
1319 self_t& operator=(T0 const& t) { return this->assign(0, t); }
1320 self_t& operator=(T1 const& t) { return this->assign(1, t); }
1321 self_t& operator=(T2 const& t) { return this->assign(2, t); }
1322 self_t& operator=(T3 const& t) { return this->assign(3, t); }
1323 self_t& operator=(T4 const& t) { return this->assign(4, t); }
1324 self_t& operator=(T5 const& t) { return this->assign(5, t); }
1325 self_t& operator=(T6 const& t) { return this->assign(6, t); }
1326 self_t& operator=(T7 const& t) { return this->assign(7, t); }
1327 self_t& operator=(T8 const& t) { return this->assign(8, t); }
1328 self_t& operator=(T9 const& t) { return this->assign(9, t); }
1329
1330 1 ~VariantType()
1331 {
1332 1 destruct();
1333 1 }
1334
1335 1 std::type_info const& getTypeInfo() const
1336 {
1337 1 return *this->ptr_type;
1338 }
1339 2 size_t size() const
1340 {
1341 2 return this->type_size;
1342 }
1343
1344 template<class U> bool is() const
1345 {
1346 return this->getTypeInfo() == typeid(U);
1347 }
1348
1349 template<class U> U* get()
1350 {
1351 if (this->is<U>())
1352 {
1353 return NULL;
1354
1355 }
1356 return reinterpret_cast<U*>(&this->content);
1357 }
1358 template<class U> U const* get() const
1359 {
1360 if (!this->is<U>())
1361 {
1362 return NULL;
1363
1364 }
1365 return reinterpret_cast<U const*>(&this->content);
1366 }
1367
1368 void* getContent()
1369 {
1370 return static_cast<void*>(&this->content);
1371 }
1372
1373 size_t getIndex() const
1374 {
1375 return this->type_index;
1376 }
1377
1378 template<class U> U& value()
1379 {
1380 if (!this->is<U>())
1381 {
1382 GATEXX_RAISE_ERROR(results::IncorrectType);
1383 }
1384 return *reinterpret_cast<U*>(&this->content);
1385 }
1386
1387 template<class U> U const& value() const
1388 {
1389 if (!this->is<U>())
1390 {
1391 GATEXX_RAISE_ERROR(results::IncorrectType);
1392 }
1393 return *reinterpret_cast<U const*>(&this->content);
1394 }
1395
1396 void set(std::type_info const* ti, void const* ptrContent)
1397 {
1398 if (ti == &typeid(T0)) { *this = *static_cast<T0 const*>(ptrContent); }
1399 else if (ti == &typeid(T1)) { *this = *static_cast<T1 const*>(ptrContent); }
1400 else if (ti == &typeid(T2)) { *this = *static_cast<T2 const*>(ptrContent); }
1401 else if (ti == &typeid(T3)) { *this = *static_cast<T3 const*>(ptrContent); }
1402 else if (ti == &typeid(T4)) { *this = *static_cast<T4 const*>(ptrContent); }
1403 else if (ti == &typeid(T5)) { *this = *static_cast<T5 const*>(ptrContent); }
1404 else if (ti == &typeid(T6)) { *this = *static_cast<T6 const*>(ptrContent); }
1405 else if (ti == &typeid(T7)) { *this = *static_cast<T7 const*>(ptrContent); }
1406 else if (ti == &typeid(T8)) { *this = *static_cast<T8 const*>(ptrContent); }
1407 else if (ti == &typeid(T9)) { *this = *static_cast<T9 const*>(ptrContent); }
1408 else { GATEXX_RAISE_ERROR(results::IncorrectType); }
1409 }
1410 template<class U> void set(U const& content)
1411 {
1412 this->set(&typeid(content), &content);
1413 }
1414 };
1415
1416
1417
1418
1419 /// @brief
1420 /// @tparam T0
1421 /// @tparam T1
1422 /// @tparam T2
1423 /// @tparam T3
1424 /// @tparam T4
1425 /// @tparam T5
1426 /// @tparam T6
1427 /// @tparam T7
1428 /// @tparam T8
1429 /// @tparam T9
1430 template<class T0,
1431 class T1 = VariantNoneArg<1>,
1432 class T2 = VariantNoneArg<2>,
1433 class T3 = VariantNoneArg<3>,
1434 class T4 = VariantNoneArg<4>,
1435 class T5 = VariantNoneArg<5>,
1436 class T6 = VariantNoneArg<6>,
1437 class T7 = VariantNoneArg<7>,
1438 class T8 = VariantNoneArg<8>,
1439 class T9 = VariantNoneArg<9>
1440 >
1441 class VariantFactory
1442 {
1443 public:
1444 typedef VariantFactory<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> self_t;
1445 typedef VariantType<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> variant_type_t;
1446
1447 private:
1448 struct VariantImpl : gate_variant_t
1449 {
1450 gate_variant_vtbl_t vtbl_impl;
1451 gate_atomic_int_t ref_counter;
1452
1453 variant_type_t var;
1454 };
1455
1456 static char const* get_interface_name_impl(void* obj)
1457 {
1458 return GATE_INTERFACE_NAME_VARIANT;
1459 }
1460 1 static void release_impl(void* obj)
1461 {
1462 1 VariantImpl* self = (VariantImpl*)obj;
1463
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_atomic_int_dec(&self->ref_counter) == 0)
1464 {
1465 1 destructType(&self->var);
1466 1 gate_mem_dealloc(self);
1467 }
1468 1 }
1469 static int retain_impl(void* obj)
1470 {
1471 VariantImpl* self = (VariantImpl*)obj;
1472 return gate_atomic_int_inc(&self->ref_counter);
1473 }
1474 2 static gate_size_t get_size_impl(void* obj)
1475 {
1476 2 VariantImpl* self = (VariantImpl*)obj;
1477 2 return self->var.size();
1478 }
1479 static void* get_content_impl(void* obj)
1480 {
1481 VariantImpl* self = (VariantImpl*)obj;
1482 return self->var.getContent();
1483 }
1484 1 static void const* get_type_impl(void* obj)
1485 {
1486 1 VariantImpl* self = (VariantImpl*)obj;
1487 1 return &self->var.getTypeInfo();
1488 }
1489 static gate_bool_t is_type_impl(void* obj, void const* compare_with)
1490 {
1491 VariantImpl* self = (VariantImpl*)obj;
1492 std::type_info const* ptrType = static_cast<std::type_info const*>(compare_with);
1493 return &self->var.getTypeInfo() == ptrType;
1494 }
1495 static gate_result_t set_content_impl(void* obj, void const* ptr_content, gate_size_t size, void const* ptr_type)
1496 {
1497 VariantImpl* self = (VariantImpl*)obj;
1498 (void)size;
1499 self->var.set(static_cast<std::type_info const*>(ptr_type), ptr_content);
1500 return GATE_RESULT_NOTSUPPORTED;
1501 }
1502
1503 template<class V>
1504 1 static VariantImpl* createImpl(V const& value)
1505 {
1506 1 VariantImpl* ptr = static_cast<VariantImpl*>(gate_mem_alloc(sizeof(VariantImpl)));
1507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!ptr)
1508 {
1509 return NULL;
1510 }
1511 1 ptr->vtbl = &ptr->vtbl_impl;
1512 1 gate_atomic_int_init(&ptr->ref_counter, 1);
1513
1514 1 ptr->vtbl_impl.get_interface_name = &get_interface_name_impl;
1515 1 ptr->vtbl_impl.release = &release_impl;
1516 1 ptr->vtbl_impl.retain = &retain_impl;
1517 1 ptr->vtbl_impl.get_size = &get_size_impl;
1518 1 ptr->vtbl_impl.get_content = &get_content_impl;
1519 1 ptr->vtbl_impl.get_type = &get_type_impl;
1520 1 ptr->vtbl_impl.is_type = &is_type_impl;
1521 1 ptr->vtbl_impl.set_content = &set_content_impl;
1522
1523 try
1524 {
1525
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 new(&ptr->var) variant_type_t(value);
1526 }
1527 catch (...)
1528 {
1529 gate_mem_dealloc(ptr);
1530 throw;
1531 }
1532 1 return ptr;
1533 }
1534
1535 public:
1536
1537 static Variant create(T0 const& value) { return Variant(self_t::createImpl(value)); }
1538 1 static Variant create(T1 const& value) { return Variant(self_t::createImpl(value)); }
1539 static Variant create(T2 const& value) { return Variant(self_t::createImpl(value)); }
1540 static Variant create(T3 const& value) { return Variant(self_t::createImpl(value)); }
1541 static Variant create(T4 const& value) { return Variant(self_t::createImpl(value)); }
1542 static Variant create(T5 const& value) { return Variant(self_t::createImpl(value)); }
1543 static Variant create(T6 const& value) { return Variant(self_t::createImpl(value)); }
1544 static Variant create(T7 const& value) { return Variant(self_t::createImpl(value)); }
1545 static Variant create(T8 const& value) { return Variant(self_t::createImpl(value)); }
1546 static Variant create(T9 const& value) { return Variant(self_t::createImpl(value)); }
1547 };
1548
1549
1550 } // end of namespace gate
1551
1552 #endif
1553