join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
variant.hpp
Go to the documentation of this file.
1
25#ifndef __JOIN_VARIANT_HPP__
26#define __JOIN_VARIANT_HPP__
27
28#pragma GCC diagnostic push
29#pragma GCC diagnostic ignored "-Weffc++"
30
31// libjoin.
32#include <join/traits.hpp>
33
34// C++.
35#include <algorithm>
36#include <typeinfo>
37
38namespace join
39{
40 namespace details
41 {
45 template <typename... Ts>
47 {
48 static constexpr bool value = std::is_default_constructible <find_element_t <0, Ts...>>::value;
49 };
50
54 template <typename... Ts>
56 {
57 };
58
62 template <typename Last>
63 struct VariantHelper <Last>
64 {
70 inline static void destroy (std::size_t /*index*/, void* data)
71 {
72 reinterpret_cast <Last *> (data)->~Last ();
73 }
74
81 inline static void copy (std::size_t /*oldIndex*/, const void* oldData, void* newData)
82 {
83 new (newData) Last (*reinterpret_cast <const Last *> (oldData));
84 }
85
92 inline static void move (std::size_t /*oldIndex*/, void* oldData, void* newData)
93 {
94 new (newData) Last (std::move (*reinterpret_cast <Last *> (oldData)));
95 }
96
104 inline static bool equal (std::size_t /*index*/, const void* data, const void* otherData)
105 {
106 return *reinterpret_cast <const Last *> (data) == *reinterpret_cast <const Last *> (otherData);
107 }
108
116 template <typename T = Last, typename std::enable_if_t <!std::is_null_pointer <T>::value>* = nullptr>
117 inline static bool lower (std::size_t /*index*/, const void* data, const void* otherData)
118 {
119 return *reinterpret_cast <const Last *> (data) < *reinterpret_cast <const Last *> (otherData);
120 }
121
129 template <typename T = Last, typename std::enable_if_t <std::is_null_pointer <T>::value>* = nullptr>
130 inline static bool lower (std::size_t /*index*/, const void* /*data*/, const void* /*otherData*/)
131 {
132 return false;
133 }
134 };
135
139 template <typename First, typename... Ts>
140 struct VariantHelper <First, Ts...>
141 {
147 inline static void destroy (std::size_t index, void* data)
148 {
149 if (index == sizeof... (Ts))
150 {
151 reinterpret_cast <First *> (data)->~First ();
152 }
153 else
154 {
155 VariantHelper <Ts...>::destroy (index, data);
156 }
157 }
158
165 inline static void copy (std::size_t oldIndex, const void* oldData, void* newData)
166 {
167 if (oldIndex == sizeof... (Ts))
168 {
169 new (newData) First (*reinterpret_cast <const First *> (oldData));
170 }
171 else
172 {
173 VariantHelper <Ts...>::copy (oldIndex, oldData, newData);
174 }
175 }
176
183 inline static void move (std::size_t oldIndex, void* oldData, void* newData)
184 {
185 if (oldIndex == sizeof... (Ts))
186 {
187 new (newData) First (std::move (*reinterpret_cast <First *> (oldData)));
188 }
189 else
190 {
191 VariantHelper <Ts...>::move (oldIndex, oldData, newData);
192 }
193 }
194
202 inline static bool equal (std::size_t index, const void* data, const void* otherData)
203 {
204 if (index == sizeof... (Ts))
205 {
206 return *reinterpret_cast <const First *> (data) == *reinterpret_cast <const First *> (otherData);
207 }
208 else
209 {
210 return VariantHelper <Ts...>::equal (index, data, otherData);
211 }
212 }
213
221 template <typename T = First, typename std::enable_if_t <!std::is_null_pointer <T>::value>* = nullptr>
222 inline static bool lower (std::size_t index, const void* data, const void* otherData)
223 {
224 if (index == sizeof... (Ts))
225 {
226 return *reinterpret_cast <const First *> (data) < *reinterpret_cast <const First *> (otherData);
227 }
228 else
229 {
230 return VariantHelper <Ts...>::lower (index, data, otherData);
231 }
232 }
233
241 template <typename T = First, typename std::enable_if_t <std::is_null_pointer <T>::value>* = nullptr>
242 inline static bool lower (std::size_t index, const void* data, const void* otherData)
243 {
244 if (index == sizeof... (Ts))
245 {
246 return false;
247 }
248 else
249 {
250 return VariantHelper <Ts...>::lower (index, data, otherData);
251 }
252 }
253 };
254
258 template <typename... Ts>
260 {
264 constexpr VariantStorage () noexcept
266 {
267 }
268
273 constexpr VariantStorage (const VariantStorage& other)
274 : _which (other._which)
275 {
276 VariantHelper <Ts...>::copy (other._which, other.storage (), storage ());
277 }
278
283 constexpr VariantStorage (VariantStorage&& other) noexcept
284 : _which (other._which)
285 {
286 VariantHelper <Ts...>::move (other._which, other.storage (), storage ());
287 }
288
293 template <std::size_t I, typename... Args>
294 constexpr explicit VariantStorage (in_place_index_t <I>, Args&&... args)
295 : _which (sizeof... (Ts) - I - 1)
296 {
297 new (storage ()) find_element_t <I, Ts...> (std::forward <Args> (args)...);
298 }
299
304 {
305 VariantHelper <Ts...>::destroy (_which, storage ());
306 }
307
313 constexpr VariantStorage& operator= (const VariantStorage& other)
314 {
315 VariantHelper <Ts...>::destroy (_which, storage ());
316 VariantHelper <Ts...>::copy (other._which, other.storage (), storage ());
317 _which = other._which;
318 return *this;
319 }
320
326 constexpr VariantStorage& operator= (VariantStorage&& other) noexcept
327 {
328 VariantHelper <Ts...>::destroy (_which, storage ());
329 VariantHelper <Ts...>::move (other._which, other.storage (), storage ());
330 _which = other._which;
331 return *this;
332 }
333
338 constexpr void* storage ()
339 {
340 return static_cast <void *> (std::addressof (_data));
341 }
342
347 constexpr const void* storage () const
348 {
349 return static_cast <const void *> (std::addressof (_data));
350 }
351
353 typename std::aligned_union <std::max ({sizeof (Ts)...}), Ts...>::type _data;
354
356 std::size_t _which = sizeof... (Ts) - 1;
357 };
358 }
359
363 template <typename... Ts>
365 : private details::VariantStorage <Ts...>,
366 private EnableDefault <
367 details::is_first_default_constructible <Ts...>::value,
368 Variant <Ts...>>,
369 private std::_Enable_copy_move <
370 are_copy_constructible <Ts...>::value,
371 are_copy_assignable <Ts...>::value,
372 are_move_constructible <Ts...>::value,
373 are_move_assignable <Ts...>::value,
374 Variant <Ts...>>
375 {
376 public:
377 static_assert (0 < sizeof... (Ts),
378 "Variant must have at least one alternative");
379 static_assert (all <!std::is_void <Ts>::value...>::value,
380 "Variant must have no void alternative");
381 static_assert (all <!std::is_array <Ts>::value...>::value,
382 "Variant must have no array alternative.");
383 static_assert (all <!std::is_reference <Ts>::value...>::value,
384 "Variant must have no reference alternative");
385
387 using DefaultEnabler = EnableDefault <
389 Variant <Ts...>>;
390
394 constexpr Variant () = default;
395
400 constexpr Variant (const Variant&) = default;
401
406 constexpr Variant (Variant&&) = default;
407
412 template <typename T, typename Match = match_t <T&&, Ts...>,
413 typename = std::enable_if_t <is_unique <Match, Ts...>::value
414 && std::is_constructible <Match, T&&>::value>>
415 constexpr Variant (T&& t) noexcept
416 : Variant (in_place_index_t <find_index <Match, Ts...>::value> {}, std::forward <T> (t))
417 {
418 }
419
424 template <typename T, typename... Args,
425 typename = std::enable_if_t <is_unique <T, Ts...>::value
426 && std::is_constructible <T, Args&&...>::value>>
427 constexpr explicit Variant (in_place_type_t <T>, Args&&... args)
428 : Variant (in_place_index_t <find_index <T, Ts...>::value> {}, std::forward <Args> (args)...)
429 {
430 }
431
436 template <typename T, typename Up, typename... Args,
437 typename = std::enable_if_t <is_unique <T, Ts...>::value
438 && std::is_constructible <T, std::initializer_list <Up>&, Args&&...>::value>>
439 constexpr explicit Variant (in_place_type_t <T>, std::initializer_list <Up> il, Args&&... args)
440 : Variant (in_place_index_t <find_index <T, Ts...>::value> {}, il, std::forward <Args> (args)...)
441 {
442 }
443
448 template <std::size_t I, typename... Args,
449 typename = std::enable_if_t <std::is_constructible <
450 find_element_t <I, Ts...>, Args&&...>::value>>
451 constexpr explicit Variant (in_place_index_t <I>, Args&&... args)
452 : Base (in_place_index_t <I> {}, std::forward <Args> (args)...),
453 DefaultEnabler (EnableDefaultTag {})
454 {
455 }
456
461 template <std::size_t I, typename Up, typename... Args,
462 typename = std::enable_if_t <std::is_constructible <
463 find_element_t <I, Ts...>, std::initializer_list <Up>&, Args&&...>::value>>
464 constexpr explicit Variant (in_place_index_t <I>, std::initializer_list <Up> il, Args&&... args)
465 : Base (in_place_index_t <I> {}, il, std::forward <Args> (args)...),
466 DefaultEnabler (EnableDefaultTag {})
467 {
468 }
469
473 virtual ~Variant () = default;
474
480 constexpr Variant& operator= (const Variant& other) = default;
481
487 constexpr Variant& operator= (Variant&& other) = default;
488
494 template <typename T, typename Match = match_t <T&&, Ts...>>
495 constexpr std::enable_if_t <is_unique <Match, Ts...>::value
496 && std::is_constructible <Match, T&&>::value, Variant&>
497 operator= (T&& t) noexcept
498 {
499 set <find_index <Match, Ts...>::value> (std::forward <T> (t));
500 return *this;
501 }
502
507 template <typename T>
508 constexpr std::enable_if_t <is_unique <T, Ts...>::value, bool>
509 is () const
510 {
511 return (index () == find_index <T, Ts...>::value);
512 }
513
518 template <std::size_t I>
519 constexpr std::enable_if_t <is_index <I, Ts...>::value, bool>
520 is () const
521 {
522 return (index () == I);
523 }
524
529 template <typename T, typename... Args>
530 constexpr std::enable_if_t <is_unique <T, Ts...>::value
531 && std::is_constructible <T, Args&&...>::value, T&>
532 set (Args&& ...args)
533 {
534 return set <find_index <T, Ts...>::value> (std::forward <Args> (args)...);
535 }
536
541 template <typename T, typename Up, typename... Args>
542 constexpr std::enable_if_t <is_unique <T, Ts...>::value
543 && std::is_constructible <T, std::initializer_list <Up>&, Args&&...>::value, T&>
544 set (std::initializer_list <Up> il, Args&&... args)
545 {
546 return set <find_index <T, Ts...>::value> (il, std::forward <Args> (args)...);
547 }
548
553 template <std::size_t I, typename... Args>
554 constexpr std::enable_if_t <std::is_constructible <
555 find_element_t <I, Ts...>, Args&&...>::value, find_element_t <I, Ts...>&>
556 set (Args&& ...args)
557 {
558 Variant tmp (in_place_index_t <I> {}, std::forward <Args> (args)...);
559 *this = std::move (tmp);
560 return get <I> ();
561 }
562
567 template <std::size_t I, class Up, class... Args>
568 constexpr std::enable_if_t <
569 std::is_constructible <find_element_t <I, Ts...>,
570 std::initializer_list <Up>&, Args&&...>::value, find_element_t <I, Ts...>&>
571 set (std::initializer_list <Up> il, Args&&... args)
572 {
573 Variant tmp (in_place_index_t <I> {}, il, std::forward <Args> (args)...);
574 *this = std::move (tmp);
575 return get <I> ();
576 }
577
582 template <typename T>
583 constexpr std::enable_if_t <is_unique <T, Ts...>::value, T&>
585 {
586 if (index () != find_index <T, Ts...>::value)
587 {
588 throw std::bad_cast ();
589 }
590 return *reinterpret_cast <T*> (this->storage ());
591 }
592
597 template <typename T>
598 constexpr std::enable_if_t <is_unique <T, Ts...>::value, const T&>
599 get () const
600 {
601 if (index () != find_index <T, Ts...>::value)
602 {
603 throw std::bad_cast ();
604 }
605 return *reinterpret_cast <const T*> (this->storage ());
606 }
607
612 template <std::size_t I>
613 constexpr std::enable_if_t <is_index <I, Ts...>::value, find_element_t <I, Ts...>&>
615 {
616 if (index () != I)
617 {
618 throw std::bad_cast ();
619 }
620 return *reinterpret_cast <find_element_t <I, Ts...>*> (this->storage ());
621 }
622
627 template <std::size_t I>
628 constexpr std::enable_if_t <is_index <I, Ts...>::value, const find_element_t <I, Ts...>&>
629 get () const
630 {
631 if (index () != I)
632 {
633 throw std::bad_cast ();
634 }
635 return *reinterpret_cast <const find_element_t <I, Ts...>*> (this->storage ());
636 }
637
642 template <typename T>
643 constexpr std::enable_if_t <is_unique <T, Ts...>::value, T*>
645 {
646 if (index () != find_index <T, Ts...>::value)
647 {
648 return nullptr;
649 }
650 return reinterpret_cast <T*> (this->storage ());
651 }
652
657 template <typename T>
658 constexpr std::enable_if_t <is_unique <T, Ts...>::value, const T*>
659 getIf () const
660 {
661 if (index () != find_index <T, Ts...>::value)
662 {
663 return nullptr;
664 }
665 return reinterpret_cast <const T*> (this->storage ());
666 }
667
672 template <std::size_t I>
673 constexpr std::enable_if_t <
674 is_index <I, Ts...>::value, find_element_t <I, Ts...>*>
676 {
677 if (index () != I)
678 {
679 return nullptr;
680 }
681 return reinterpret_cast <find_element_t <I, Ts...>*> (this->storage ());
682 }
683
688 template <std::size_t I>
689 constexpr std::enable_if_t <
690 is_index <I, Ts...>::value, const find_element_t <I, Ts...>*>
691 getIf () const
692 {
693 if (index () != I)
694 {
695 return nullptr;
696 }
697 return reinterpret_cast <const find_element_t <I, Ts...>*> (this->storage ());
698 }
699
704 constexpr std::size_t index () const noexcept
705 {
706 return sizeof... (Ts) - this->_which - 1;
707 }
708
709 protected:
715 constexpr bool equal (const Variant& rhs) const
716 {
717 if (index () != rhs.index ())
718 {
719 return false;
720 }
721 return details::VariantHelper <Ts...>::equal (this->_which, this->storage (), rhs.storage ());
722 }
723
729 constexpr bool lower (const Variant& rhs) const
730 {
731 if (index () < rhs.index ())
732 {
733 return true;
734 }
735 if (index () > rhs.index ())
736 {
737 return false;
738 }
739 return details::VariantHelper <Ts...>::lower (this->_which, this->storage (), rhs.storage ());
740 }
741
742 // friendship with equal operator.
743 template <typename... _Ts>
744 friend constexpr bool operator== (const Variant <_Ts...>& lhs, const Variant <_Ts...>& rhs);
745
746 // friendship with lower operator.
747 template <typename... _Ts>
748 friend constexpr bool operator< (const Variant <_Ts...>& lhs, const Variant <_Ts...>& rhs);
749 };
750
757 template <typename... Ts>
758 constexpr bool operator== (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
759 {
760 return lhs.equal (rhs);
761 }
762
769 template <typename... Ts>
770 constexpr bool operator!= (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
771 {
772 return !(lhs == rhs);
773 }
774
781 template <typename... Ts>
782 constexpr bool operator< (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
783 {
784 return lhs.lower (rhs);
785 }
786
793 template <typename... Ts>
794 constexpr bool operator> (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
795 {
796 return rhs < lhs;
797 }
798
805 template <typename... Ts>
806 constexpr bool operator<= (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
807 {
808 return !(rhs < lhs);
809 }
810
817 template <typename... Ts>
818 constexpr bool operator>= (const Variant <Ts...>& lhs, const Variant <Ts...>& rhs)
819 {
820 return !(lhs < rhs);
821 }
822}
823
824#pragma GCC diagnostic pop
825
826#endif
variant class.
Definition variant.hpp:375
constexpr std::enable_if_t< is_unique< T, Ts... >::value, const T * > getIf() const
get the variable value address of the object type identified by type.
Definition variant.hpp:659
constexpr std::enable_if_t< is_unique< T, Ts... >::value &&std::is_constructible< T, std::initializer_list< Up > &, Args &&... >::value, T & > set(std::initializer_list< Up > il, Args &&... args)
set the variable type of the object identified by type and assign it a value.
Definition variant.hpp:544
constexpr std::enable_if_t< is_index< I, Ts... >::value, const find_element_t< I, Ts... > * > getIf() const
get the variable value address of the object type identified by index.
Definition variant.hpp:691
constexpr Variant(T &&t) noexcept
constructs a Variant holding the alternative selected by overload resolution.
Definition variant.hpp:415
constexpr bool lower(const Variant &rhs) const
check if lower than.
Definition variant.hpp:729
constexpr Variant(Variant &&)=default
move constructor.
EnableDefault< details::is_first_default_constructible< Ts... >::value, Variant< Ts... > > DefaultEnabler
Definition variant.hpp:387
constexpr Variant(in_place_type_t< T >, Args &&... args)
constructs a Variant with the specified alternative T.
Definition variant.hpp:427
constexpr std::enable_if_t< is_unique< T, Ts... >::value, T & > get()
get the variable value of the object type identified by type.
Definition variant.hpp:584
constexpr Variant(const Variant &)=default
copy constructor.
constexpr Variant(in_place_index_t< I >, Args &&... args)
constructs a variant with the alternative T specified by the index I.
Definition variant.hpp:451
friend constexpr bool operator==(const Variant< _Ts... > &lhs, const Variant< _Ts... > &rhs)
constexpr std::enable_if_t< is_unique< T, Ts... >::value, const T & > get() const
get the variable value of the object type identified by type.
Definition variant.hpp:599
constexpr std::size_t index() const noexcept
return the index of the alternative that is currently held by the variant.
Definition variant.hpp:704
constexpr std::enable_if_t< is_unique< T, Ts... >::value, bool > is() const
check that the member type in use is the same than the one specified.
Definition variant.hpp:509
constexpr Variant()=default
default constructor.
constexpr std::enable_if_t< is_unique< T, Ts... >::value, T * > getIf()
get the variable value address of the object type identified by type.
Definition variant.hpp:644
constexpr std::enable_if_t< std::is_constructible< find_element_t< I, Ts... >, Args &&... >::value, find_element_t< I, Ts... > & > set(Args &&...args)
set the variable type of the object identified by index and assign it a value.
Definition variant.hpp:556
constexpr Variant(in_place_index_t< I >, std::initializer_list< Up > il, Args &&... args)
constructs a variant with the alternative T specified by the index I.
Definition variant.hpp:464
constexpr std::enable_if_t< std::is_constructible< find_element_t< I, Ts... >, std::initializer_list< Up > &, Args &&... >::value, find_element_t< I, Ts... > & > set(std::initializer_list< Up > il, Args &&... args)
set the variable type of the object identified by index and assign it a value.
Definition variant.hpp:571
constexpr std::enable_if_t< is_index< I, Ts... >::value, find_element_t< I, Ts... > & > get()
get the variable value of the object type identified by index.
Definition variant.hpp:614
constexpr std::enable_if_t< is_index< I, Ts... >::value, bool > is() const
check that the index in use is the same than the one specified.
Definition variant.hpp:520
constexpr Variant & operator=(const Variant &other)=default
copy assignment.
constexpr std::enable_if_t< is_index< I, Ts... >::value, find_element_t< I, Ts... > * > getIf()
get the variable value address of the object type identified by index.
Definition variant.hpp:675
constexpr std::enable_if_t< is_unique< T, Ts... >::value &&std::is_constructible< T, Args &&... >::value, T & > set(Args &&...args)
set the variable type of the object identified by type and assign it a value.
Definition variant.hpp:532
virtual ~Variant()=default
destroy the Variant instance.
friend constexpr bool operator<(const Variant< _Ts... > &lhs, const Variant< _Ts... > &rhs)
constexpr Variant(in_place_type_t< T >, std::initializer_list< Up > il, Args &&... args)
constructs a Variant with the specified alternative T.
Definition variant.hpp:439
constexpr bool equal(const Variant &rhs) const
check if equal.
Definition variant.hpp:715
constexpr std::enable_if_t< is_index< I, Ts... >::value, const find_element_t< I, Ts... > & > get() const
get the variable value of the object type identified by index.
Definition variant.hpp:629
Definition acceptor.hpp:32
bool operator<(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoint is lower.
Definition endpoint.hpp:207
bool operator>(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoint is greater.
Definition endpoint.hpp:219
bool operator!=(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoints are not equal.
Definition endpoint.hpp:195
bool operator>=(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoint is greater or equal.
Definition endpoint.hpp:243
bool operator<=(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoint is lower or equal.
Definition endpoint.hpp:231
typename find_element< I, Ts... >::type find_element_t
get element type in a parameter pack according its position.
Definition traits.hpp:157
typename std::result_of_t< overload< Ts... >(T)>::type match_t
find a type that match one of the alternatives of a parameter pack.
Definition traits.hpp:117
bool operator==(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoints are equal.
Definition endpoint.hpp:183
static bool equal(std::size_t index, const void *data, const void *otherData)
external routine to compare if one object is equal to an other of same type.
Definition variant.hpp:202
static bool lower(std::size_t index, const void *data, const void *otherData)
external routine to compare if one object is lower than an other of the same type.
Definition variant.hpp:222
static void copy(std::size_t oldIndex, const void *oldData, void *newData)
external routine to copy one object to an other.
Definition variant.hpp:165
static void destroy(std::size_t index, void *data)
external routine to destroy the object.
Definition variant.hpp:147
static void move(std::size_t oldIndex, void *oldData, void *newData)
external routine to move one object to an other.
Definition variant.hpp:183
static void destroy(std::size_t, void *data)
external routine to destroy the object.
Definition variant.hpp:70
static bool equal(std::size_t, const void *data, const void *otherData)
external routine to compare if one object is equal to an other of same type.
Definition variant.hpp:104
static void copy(std::size_t, const void *oldData, void *newData)
external routine to copy one object to an other.
Definition variant.hpp:81
static void move(std::size_t, void *oldData, void *newData)
external routine to move one object to an other.
Definition variant.hpp:92
static bool lower(std::size_t, const void *, const void *)
external routine to compare if one object is lower than an other of the same type.
Definition variant.hpp:130
static bool lower(std::size_t, const void *data, const void *otherData)
external routine to compare if one object is lower than an other of the same type.
Definition variant.hpp:117
helper class for variant creation/deletion.
Definition variant.hpp:56
helper class representing a variant storage in order to be able to disable default/copy/move construc...
Definition variant.hpp:260
~VariantStorage()
destroy the VariantStorage instance.
Definition variant.hpp:303
constexpr void * storage()
get storage address.
Definition variant.hpp:338
constexpr VariantStorage(in_place_index_t< I >, Args &&... args)
constructs a variant storage with the alternative T specified by the index I.
Definition variant.hpp:294
constexpr VariantStorage() noexcept
default constructor.
Definition variant.hpp:264
constexpr VariantStorage & operator=(const VariantStorage &other)
copy assignment.
Definition variant.hpp:313
constexpr VariantStorage(const VariantStorage &other)
copy constructor.
Definition variant.hpp:273
constexpr VariantStorage(VariantStorage &&other) noexcept
move constructor.
Definition variant.hpp:283
std::aligned_union< std::max({sizeof(Ts)...}), Ts... >::type _data
aligned storage.
Definition variant.hpp:353
constexpr const void * storage() const
get storage address.
Definition variant.hpp:347
std::size_t _which
index of the alternative that is currently held by the variant.
Definition variant.hpp:356
check that first alternative is default constructible.
Definition variant.hpp:47
static constexpr bool value
Definition variant.hpp:48
get element position in a parameter pack according its type.
Definition traits.hpp:124
disambiguation tag to indicate that the contained object should be constructed in-place.
Definition traits.hpp:57