25#ifndef JOIN_CORE_VARIANT_HPP
26#define JOIN_CORE_VARIANT_HPP
45 template <
typename... Ts>
54 template <
typename... Ts>
64 static void copy (std::size_t which,
const void* src,
void* dst)
66 static const CopyFunc table[] = {©Impl<Ts>...};
67 table[which](src, dst);
76 static void move (std::size_t which,
void* src,
void* dst)
78 static const MoveFunc table[] = {&moveImpl<Ts>...};
79 table[which](src, dst);
87 static void destroy (std::size_t which,
void* data)
89 static const DestroyFunc table[] = {&destroyImpl<Ts>...};
100 static bool equal (std::size_t which,
const void* a,
const void* b)
102 static const EqualFunc table[] = {&equalImpl<Ts>...};
103 return table[which](a, b);
113 static bool lower (std::size_t which,
const void* a,
const void* b)
115 static const LowerFunc table[] = {&lowerImpl<Ts>...};
116 return table[which](a, b);
121 using CopyFunc = void (*) (
const void*,
void*);
124 using MoveFunc = void (*) (
void*,
void*);
127 using DestroyFunc = void (*) (
void*);
130 using EqualFunc = bool (*) (
const void*,
const void*);
133 using LowerFunc = bool (*) (
const void*,
const void*);
141 template <
typename T>
142 static void copyImpl (
const void* src,
void* dst)
144 new (dst) T (*
reinterpret_cast<const T*
> (src));
153 template <
typename T>
154 static void moveImpl (
void* src,
void* dst)
156 new (dst) T (std::move (*
reinterpret_cast<T*
> (src)));
164 template <
typename T>
165 static void destroyImpl (
void* data)
167 reinterpret_cast<T*
> (data)->~T ();
177 template <
typename T>
178 static bool equalImpl (
const void* a,
const void* b)
180 return *
reinterpret_cast<const T*
> (a) == *
reinterpret_cast<const T*
> (b);
190 template <
typename T>
191 static typename std::enable_if<!std::is_null_pointer<T>::value,
bool>::type lowerDispatch (
const void* a,
194 return *
reinterpret_cast<const T*
> (a) < *
reinterpret_cast<const T*
> (b);
202 template <
typename T>
203 static typename std::enable_if<std::is_null_pointer<T>::value,
bool>::type lowerDispatch (
const void*,
216 template <
typename T>
217 static bool lowerImpl (
const void* a,
const void* b)
219 return lowerDispatch<T> (a, b);
227 template <
typename... Ts>
262 template <std::size_t I,
typename... Args>
306 return static_cast<void*
> (std::addressof (
_data));
315 return static_cast<const void*
> (std::addressof (
_data));
324 alignas (Ts...)
unsigned char tmp[std::max ({
sizeof (Ts)...})];
331 std::swap (
_which, other._which);
335 alignas (Ts...)
unsigned char _data[std::max ({
sizeof (Ts)...})];
345 template <
typename... Ts>
348 private EnableDefault<details::is_first_default_constructible<Ts...>::value, Variant<Ts...>>,
349 private std::_Enable_copy_move<are_copy_constructible<Ts...>::value, are_copy_assignable<Ts...>::value,
350 are_move_constructible<Ts...>::value, are_move_assignable<Ts...>::value,
354 static_assert (0 <
sizeof...(Ts),
"Variant must have at least one alternative");
355 static_assert (all<!std::is_void<Ts>::value...>::value,
"Variant must have no void alternative");
356 static_assert (all<!std::is_array<Ts>::value...>::value,
"Variant must have no array alternative.");
357 static_assert (all<!std::is_reference<Ts>::value...>::value,
"Variant must have no reference alternative");
384 typename T,
typename Match =
match_t<T&&, Ts...>,
385 typename = std::enable_if_t<is_unique<Match, Ts...>::value && std::is_constructible<Match, T&&>::value>>
395 template <
typename T,
typename... Args,
396 typename = std::enable_if_t<is_unique<T, Ts...>::value && std::is_constructible<T, Args&&...>::value>>
406 template <
typename T,
typename Up,
typename... Args,
407 typename = std::enable_if_t<is_unique<T, Ts...>::value &&
408 std::is_constructible<T, std::initializer_list<Up>&, Args&&...>::value>>
418 template <std::size_t I,
typename... Args,
419 typename = std::enable_if_t<std::is_constructible<
find_element_t<I, Ts...>, Args&&...>::value>>
430 template <std::size_t I,
typename Up,
typename... Args,
431 typename = std::enable_if_t<
432 std::is_constructible<
find_element_t<I, Ts...>, std::initializer_list<Up>&, Args&&...>::value>>
463 template <
typename T,
typename Match =
match_t<T&&, Ts...>>
464 constexpr std::enable_if_t<is_unique<Match, Ts...>::value && std::is_constructible<Match, T&&>::value,
Variant&>
475 template <
typename T>
476 constexpr std::enable_if_t<is_unique<T, Ts...>::value,
bool>
is ()
const
485 template <std::
size_t I>
486 constexpr std::enable_if_t<is_index<I, Ts...>::value,
bool>
is ()
const
488 return (
index () == I);
495 template <
typename T,
typename... Args>
496 constexpr std::enable_if_t<is_unique<T, Ts...>::value && std::is_constructible<T, Args&&...>::value, T&>
set (
499 return set<
find_index<T, Ts...>::value> (std::forward<Args> (args)...);
506 template <
typename T,
typename Up,
typename... Args>
507 constexpr std::enable_if_t<
508 is_unique<T, Ts...>::value && std::is_constructible<T, std::initializer_list<Up>&, Args&&...>::value, T&>
509 set (std::initializer_list<Up> il, Args&&... args)
511 return set<
find_index<T, Ts...>::value> (il, std::forward<Args> (args)...);
518 template <std::size_t I,
typename... Args>
519 constexpr std::enable_if_t<std::is_constructible<
find_element_t<I, Ts...>, Args&&...>::value,
524 *
this = std::move (tmp);
532 template <std::size_t I,
class Up,
class... Args>
533 constexpr std::enable_if_t<
534 std::is_constructible<
find_element_t<I, Ts...>, std::initializer_list<Up>&, Args&&...>::value,
536 set (std::initializer_list<Up> il, Args&&... args)
539 *
this = std::move (tmp);
547 template <
typename T>
548 constexpr std::enable_if_t<is_unique<T, Ts...>::value, T&>
get ()
552 throw std::bad_cast ();
554 return *
reinterpret_cast<T*
> (this->
storage ());
561 template <
typename T>
562 constexpr std::enable_if_t<is_unique<T, Ts...>::value,
const T&>
get ()
const
566 throw std::bad_cast ();
568 return *
reinterpret_cast<const T*
> (this->
storage ());
575 template <std::
size_t I>
580 throw std::bad_cast ();
589 template <std::
size_t I>
590 constexpr std::enable_if_t<is_index<I, Ts...>::value,
const find_element_t<I, Ts...>&>
get ()
const
594 throw std::bad_cast ();
603 template <
typename T>
604 constexpr std::enable_if_t<is_unique<T, Ts...>::value, T*>
getIf ()
610 return reinterpret_cast<T*
> (this->
storage ());
617 template <
typename T>
618 constexpr std::enable_if_t<is_unique<T, Ts...>::value,
const T*>
getIf ()
const
624 return reinterpret_cast<const T*
> (this->
storage ());
631 template <std::
size_t I>
645 template <std::
size_t I>
659 constexpr std::size_t
index () const noexcept
707 template <
typename... _Ts>
711 template <
typename... _Ts>
721 template <
typename... Ts>
724 return lhs.
equal (rhs);
733 template <
typename... Ts>
736 return !(lhs == rhs);
745 template <
typename... Ts>
748 return lhs.
lower (rhs);
757 template <
typename... Ts>
769 template <
typename... Ts>
781 template <
typename... Ts>
792 template <
typename... Ts>
variant class.
Definition variant.hpp:352
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:618
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:509
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:646
EnableDefault< details::is_first_default_constructible< Ts... >::value, Variant< Ts... > > DefaultEnabler
Definition variant.hpp:360
constexpr bool lower(const Variant &rhs) const
check if lower than.
Definition variant.hpp:693
constexpr Variant(Variant &&)=default
move constructor.
constexpr Variant(in_place_type_t< T >, Args &&... args)
constructs a Variant with the specified alternative T.
Definition variant.hpp:397
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:548
constexpr Variant(const Variant &)=default
copy constructor.
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:496
constexpr Variant(in_place_index_t< I >, Args &&... args)
constructs a variant with the alternative T specified by the index I.
Definition variant.hpp:420
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:562
constexpr std::size_t index() const noexcept
return the index of the alternative that is currently held by the variant.
Definition variant.hpp:659
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:476
~Variant()=default
destroy the Variant instance.
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:604
constexpr Variant(T &&t)
constructs a Variant holding the alternative selected by overload resolution.
Definition variant.hpp:386
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:433
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:536
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:576
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:486
void swap(Variant &other) noexcept
swap this variant with another.
Definition variant.hpp:668
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:521
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:632
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:409
constexpr bool equal(const Variant &rhs) const
check if equal.
Definition variant.hpp:679
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:590
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
Type & swap(Type &val)
swaps byte orders.
Definition utils.hpp:184
bool operator!=(const BasicUnixEndpoint< Protocol > &a, const BasicUnixEndpoint< Protocol > &b) noexcept
compare if endpoints are not equal.
Definition endpoint.hpp:195
typename find_element< I, Ts... >::type find_element_t
get element type in a parameter pack according its position.
Definition traits.hpp:158
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 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
helper class for variant operations using jump tables for O(1) dispatch.
Definition variant.hpp:56
static bool lower(std::size_t which, const void *a, const void *b)
compare if one object is lower than another of the same alternative.
Definition variant.hpp:113
static void copy(std::size_t which, const void *src, void *dst)
copy one object to another.
Definition variant.hpp:64
static bool equal(std::size_t which, const void *a, const void *b)
compare if two objects of the same alternative are equal.
Definition variant.hpp:100
static void destroy(std::size_t which, void *data)
destroy the currently active object.
Definition variant.hpp:87
static void move(std::size_t which, void *src, void *dst)
move one object to another.
Definition variant.hpp:76
helper class representing a variant storage in order to be able to disable default/copy/move construc...
Definition variant.hpp:229
constexpr VariantStorage()
default constructor.
Definition variant.hpp:233
~VariantStorage()
destroy the VariantStorage instance.
Definition variant.hpp:272
constexpr void * storage()
get storage address.
Definition variant.hpp:304
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:263
void swap(VariantStorage &other) noexcept
swap this storage with other.
Definition variant.hpp:322
constexpr VariantStorage & operator=(const VariantStorage &other)
copy assignment.
Definition variant.hpp:282
constexpr VariantStorage(const VariantStorage &other)
copy constructor.
Definition variant.hpp:242
constexpr VariantStorage(VariantStorage &&other) noexcept
move constructor.
Definition variant.hpp:252
unsigned char _data[std::max({sizeof(Ts)...})]
aligned storage.
Definition variant.hpp:335
constexpr const void * storage() const
get storage address.
Definition variant.hpp:313
std::size_t _which
index of the alternative that is currently held by the variant.
Definition variant.hpp:338
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
disambiguation tag to indicate that the contained object should be constructed in-place.
Definition traits.hpp:48