25#ifndef __JOIN_VARIANT_HPP__
26#define __JOIN_VARIANT_HPP__
28#pragma GCC diagnostic push
29#pragma GCC diagnostic ignored "-Weffc++"
45 template <
typename... Ts>
54 template <
typename... Ts>
62 template <
typename Last>
70 inline static void destroy (std::size_t ,
void* data)
72 reinterpret_cast <Last *
> (data)->~Last ();
81 inline static void copy (std::size_t ,
const void* oldData,
void* newData)
83 new (newData) Last (*
reinterpret_cast <const Last *
> (oldData));
92 inline static void move (std::size_t ,
void* oldData,
void* newData)
94 new (newData) Last (std::move (*
reinterpret_cast <Last *
> (oldData)));
104 inline static bool equal (std::size_t ,
const void* data,
const void* otherData)
106 return *
reinterpret_cast <const Last *
> (data) == *
reinterpret_cast <const Last *
> (otherData);
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 ,
const void* data,
const void* otherData)
119 return *
reinterpret_cast <const Last *
> (data) < *
reinterpret_cast <const Last *
> (otherData);
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 ,
const void* ,
const void* )
139 template <
typename First,
typename... Ts>
147 inline static void destroy (std::size_t index,
void* data)
149 if (index ==
sizeof... (Ts))
151 reinterpret_cast <First *
> (data)->~First ();
165 inline static void copy (std::size_t oldIndex,
const void* oldData,
void* newData)
167 if (oldIndex ==
sizeof... (Ts))
169 new (newData) First (*
reinterpret_cast <const First *
> (oldData));
183 inline static void move (std::size_t oldIndex,
void* oldData,
void* newData)
185 if (oldIndex ==
sizeof... (Ts))
187 new (newData) First (std::move (*
reinterpret_cast <First *
> (oldData)));
202 inline static bool equal (std::size_t index,
const void* data,
const void* otherData)
204 if (index ==
sizeof... (Ts))
206 return *
reinterpret_cast <const First *
> (data) == *
reinterpret_cast <const First *
> (otherData);
210 return VariantHelper <Ts...>::equal (index, data, otherData);
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)
224 if (index ==
sizeof... (Ts))
226 return *
reinterpret_cast <const First *
> (data) < *
reinterpret_cast <const First *
> (otherData);
230 return VariantHelper <Ts...>::lower (index, data, otherData);
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)
244 if (index ==
sizeof... (Ts))
250 return VariantHelper <Ts...>::lower (index, data, otherData);
258 template <
typename... Ts>
293 template <std::size_t I,
typename... Args>
295 :
_which (sizeof... (Ts) - I - 1)
340 return static_cast <void *
> (std::addressof (
_data));
349 return static_cast <const void *
> (std::addressof (
_data));
353 typename std::aligned_union <std::max ({
sizeof (Ts)...}), Ts...>::type
_data;
363 template <
typename... Ts>
366 private EnableDefault <
367 details::is_first_default_constructible <Ts...>::value,
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,
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");
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>>
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)
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)
448 template <std::size_t I,
typename... Args,
449 typename = std::enable_if_t <std::is_constructible <
451 constexpr explicit Variant (in_place_index_t <I>, Args&&... args)
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)
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&>
499 set <
find_index <Match, Ts...>::value> (std::forward <T> (t));
507 template <
typename T>
508 constexpr std::enable_if_t <is_unique <T, Ts...>::value,
bool>
511 return (
index () == find_index <T, Ts...>::value);
518 template <std::
size_t I>
519 constexpr std::enable_if_t <is_index <I, Ts...>::value,
bool>
522 return (
index () == I);
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&>
534 return set <
find_index <T, Ts...>::value> (std::forward <Args> (args)...);
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)
546 return set <
find_index <T, Ts...>::value> (il, std::forward <Args> (args)...);
553 template <std::size_t I,
typename... Args>
554 constexpr std::enable_if_t <std::is_constructible <
558 Variant tmp (in_place_index_t <I> {}, std::forward <Args> (args)...);
559 *
this = std::move (tmp);
567 template <std::size_t I,
class Up,
class... Args>
568 constexpr std::enable_if_t <
570 std::initializer_list <Up>&, Args&&...>::value,
find_element_t <I, Ts...>&>
571 set (std::initializer_list <Up> il, Args&&... args)
573 Variant tmp (in_place_index_t <I> {}, il, std::forward <Args> (args)...);
574 *
this = std::move (tmp);
582 template <
typename T>
583 constexpr std::enable_if_t <is_unique <T, Ts...>::value, T&>
586 if (
index () != find_index <T, Ts...>::value)
588 throw std::bad_cast ();
590 return *
reinterpret_cast <T*
> (this->
storage ());
597 template <
typename T>
598 constexpr std::enable_if_t <is_unique <T, Ts...>::value,
const T&>
601 if (
index () != find_index <T, Ts...>::value)
603 throw std::bad_cast ();
605 return *
reinterpret_cast <const T*
> (this->
storage ());
612 template <std::
size_t I>
613 constexpr std::enable_if_t <is_index <I, Ts...>::value,
find_element_t <I, Ts...>&>
618 throw std::bad_cast ();
627 template <std::
size_t I>
628 constexpr std::enable_if_t <is_index <I, Ts...>::value,
const find_element_t <I, Ts...>&>
633 throw std::bad_cast ();
642 template <
typename T>
643 constexpr std::enable_if_t <is_unique <T, Ts...>::value, T*>
646 if (
index () != find_index <T, Ts...>::value)
650 return reinterpret_cast <T*
> (this->
storage ());
657 template <
typename T>
658 constexpr std::enable_if_t <is_unique <T, Ts...>::value,
const T*>
661 if (
index () != find_index <T, Ts...>::value)
665 return reinterpret_cast <const T*
> (this->
storage ());
672 template <std::
size_t I>
673 constexpr std::enable_if_t <
688 template <std::
size_t I>
689 constexpr std::enable_if_t <
704 constexpr std::size_t
index () const noexcept
706 return sizeof... (Ts) - this->
_which - 1;
743 template <
typename... _Ts>
747 template <
typename... _Ts>
757 template <
typename... Ts>
758 constexpr bool operator== (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
760 return lhs.
equal (rhs);
769 template <
typename... Ts>
770 constexpr bool operator!= (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
772 return !(lhs == rhs);
781 template <
typename... Ts>
782 constexpr bool operator< (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
784 return lhs.
lower (rhs);
793 template <
typename... Ts>
794 constexpr bool operator> (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
805 template <
typename... Ts>
806 constexpr bool operator<= (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
817 template <
typename... Ts>
818 constexpr bool operator>= (
const Variant <Ts...>& lhs,
const Variant <Ts...>& rhs)
824#pragma GCC diagnostic pop
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