7#include <aws/common/assert.h>
19 namespace VariantDetail
23 return (
a <
b) ?
b :
a;
26 namespace ParameterPackSize
59 return std::is_same<T, Last>::value ?
curIndex : -1;
75 return std::is_same<T, Last>::value;
94#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
101 std::tuple<typename std::add_pointer<Ts>::type...>
as_tuple;
104 template <IndexT Index,
typename First,
typename Second,
typename...
Rest>
112 template <IndexT Index,
typename Last>
void InitTuple(
char *storage)
114 Last *value =
reinterpret_cast<Last *
>(storage);
115 std::get<Index>(as_tuple) = value;
175 template <
typename OtherT>
176 using EnableIfOtherIsThisVariantAlternative =
typename std::enable_if<
184 std::is_nothrow_default_constructible<FirstAlternative>::value;
187 std::is_nothrow_constructible<FirstAlternative>::value;
201 m_index = other.m_index;
202 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveConstructor());
208 m_index = other.m_index;
209 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveConstructor());
212 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
214 std::is_nothrow_constructible<typename std::decay<T>::type,
decltype(
val)>::value)
218 "This variant does not have such alternative T.");
220 sizeof(
T) <= STORAGE_SIZE,
221 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
223 using PlainT =
typename std::decay<T>::type;
229 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
231 std::is_nothrow_constructible<typename std::decay<T>::type,
decltype(
val)>::value)
235 "This variant does not have such alternative T.");
237 sizeof(
T) <= STORAGE_SIZE,
238 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
240 using PlainT =
typename std::decay<T>::type;
241 new (m_storage)
PlainT(std::forward<T>(
val));
251 "This variant does not have such alternative T.");
253 sizeof(
T) <= STORAGE_SIZE,
254 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
256 using PlainT =
typename std::decay<T>::type;
257 new (m_storage)
PlainT(std::forward<Args>(
args)...);
267 if (m_index != other.m_index)
270 m_index = other.m_index;
271 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveConstructor());
275 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveAssigner());
286 if (m_index != other.m_index)
289 m_index = other.m_index;
290 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveConstructor());
294 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveAssigner());
306 "This variant does not have such alternative T.");
308 sizeof(
T) <= STORAGE_SIZE,
309 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
313 using PlainT =
typename std::decay<T>::type;
314 new (m_storage)
PlainT(std::forward<Args>(
args)...);
318 T *value =
reinterpret_cast<T *
>(m_storage);
322 template <std::size_t Index,
typename...
Args>
325 static_assert(Index <
AlternativeCount,
"Unknown alternative index to emplace");
326 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
331 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
bool holds_alternative()
const
338 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T &
get()
341 T *value =
reinterpret_cast<T *
>(m_storage);
345 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T *
get_if()
349 T *value =
reinterpret_cast<T *
>(m_storage);
358 template <std::
size_t Index>
auto get() ->
typename ThisVariantAlternative<Index>::type &
360 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
362 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
368 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T &
get()
const
371 const T *value =
reinterpret_cast<const T *
>(m_storage);
375 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T *
get_if()
const
379 T *value =
reinterpret_cast<T *
>(m_storage);
390 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
392 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
400 template <std::
size_t Index>
402 typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
406 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
419 template <std::
size_t Index>
421 typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
425 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
438 std::size_t
index()
const {
return m_index; }
444 return VisitorUtil<0, Ts...>::Visit(
this, std::forward<VisitorT>(
visitor));
452#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
453 VariantDetail::VariantDebug::VariantDebugBrowser<
Ts...>
browser = m_storage;
456 template <
size_t Index>
constexpr bool holds_alternative()
const {
return Index == m_index; }
460 template <
typename AlternativeT>
void operator()(
AlternativeT &&value)
const
463 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
476 struct CopyMoveConstructor
480 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
481 new (&value)
PlaintT(std::move<AlternativeT>(other));
484 template <
typename AlternativeT,
typename ConstAlternativeT>
487 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
489 typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
490 static_assert(std::is_same<PlaintT, PlaintOtherT>::value,
"Incompatible types");
496 struct CopyMoveAssigner
500 value = std::move(other);
503 template <
typename AlternativeT,
typename ConstAlternativeT>
506 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
508 typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
509 static_assert(std::is_same<PlaintT, PlaintOtherT>::value,
"Incompatible types");
515 template <
IndexT Index,
typename...
Args>
struct VisitorUtil;
522 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
524 if (Index ==
pThis->m_index)
537 template <
typename VisitorStruct>
538 static void VisitBinary(
539 VariantImpl<Ts...> *
pThis,
540 VariantImpl<Ts...> &&other,
543 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
545 if (Index ==
pThis->m_index)
554 pThis, std::forward<VariantImpl<Ts...>>(other), std::forward<VisitorStruct>(
visitor));
558 template <
typename VisitorStruct>
559 static void VisitBinary(
560 VariantImpl<Ts...> *
pThis,
561 const VariantImpl<Ts...> &other,
564 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
566 if (Index ==
pThis->m_index)
581 template <IndexT Index,
typename Last>
struct VisitorUtil<Index,
Last>
585 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
587 if (Index ==
pThis->m_index)
599 template <
typename VisitorStruct>
600 static void VisitBinary(
601 VariantImpl<Ts...> *
pThis,
602 VariantImpl<Ts...> &&other,
605 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
607 if (Index ==
pThis->m_index)
619 template <
typename VisitorStruct>
620 static void VisitBinary(
621 VariantImpl<Ts...> *
pThis,
622 const VariantImpl<Ts...> &other,
625 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
627 if (Index ==
pThis->m_index)
647 using type =
typename std::tuple_element<Index, std::tuple<
Ts...>>
::type;
656 constexpr static const std::size_t Value = T::AlternativeCount;
665 template <
typename...
Ts>
678 template <
typename OtherT>
679 using EnableIfOtherIsThisVariantAlternative =
typename std::
680 enable_if<VariantDetail::Checker::HasType<typename std::decay<OtherT>::type,
Ts...>::value,
int>::type;
682 static constexpr bool isFirstAlternativeNothrowDefaultConstructible =
691 typename std::enable_if<std::is_default_constructible<T>::value,
bool>::type =
true>
698 typename std::enable_if<!std::is_default_constructible<T>::value,
bool>::type =
true>
701 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
703 std::is_nothrow_constructible<typename std::decay<T>::type,
decltype(
val)>::value)
708 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
709 Variant(
T &&
val)
noexcept(std::is_nothrow_constructible<typename std::decay<T>::type,
decltype(
val)>::value)
710 : m_variant(std::forward<T>(
val))
714 template <
typename T,
typename...
Args>
723 return m_variant.template
emplace<T>(std::forward<Args>(
args)...);
726 template <std::size_t Index,
typename...
Args>
732 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
bool holds_alternative()
const
737 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T &
get()
739 return m_variant.template
get<T>();
742 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T *
get_if()
752 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T &
get()
const
754 return m_variant.template
get<T>();
757 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T *
get_if()
const
767 template <std::
size_t Index>
769 typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
776 template <std::
size_t Index>
778 typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
CopyableVariant(CopyableVariant &&)=default
CopyableVariant()=default
CopyableVariant & operator=(const CopyableVariant &)=delete
CopyableVariant(const CopyableVariant &)=delete
CopyableVariant & operator=(CopyableVariant &&)=default
CopyableVariant(const CopyableVariant &other)=default
CopyableVariant()=default
CopyableVariant & operator=(const CopyableVariant &other)=default
CopyableVariant & operator=(CopyableVariant &&)=default
CopyableVariant(CopyableVariant &&)=default
MovableVariant(MovableVariant &&)=delete
MovableVariant & operator=(MovableVariant &&)=delete
MovableVariant(const MovableVariant &)=default
MovableVariant & operator=(const MovableVariant &)=default
MovableVariant & operator=(const MovableVariant &)=default
MovableVariant(MovableVariant &&other)=default
MovableVariant(const MovableVariant &)=default
MovableVariant & operator=(MovableVariant &&other)=default
VariantAlternative(const VariantImpl< Ts... > *)
Definition Variant.h:651
VariantAlternative(const VariantImpl< Ts... > &)
Definition Variant.h:649
typename std::tuple_element< Index, std::tuple< Ts... > >::type type
Definition Variant.h:647
static constexpr std::size_t AlternativeCount
Definition Variant.h:190
VariantImpl(const VariantImpl &other)
Definition Variant.h:198
typename std::add_pointer< typename ThisVariantAlternative< Index >::type >::type RawAlternativePointerT
Definition Variant.h:402
auto get() -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:358
T & get()
Definition Variant.h:338
VariantImpl() noexcept(isFirstAlternativeNothrowDefaultConstructible)
Definition Variant.h:192
auto get_if() -> RawAlternativePointerT< Index >
Definition Variant.h:404
void Visit(VisitorT &&visitor)
Definition Variant.h:442
auto get_if() const -> ConstRawAlternativePointerT< Index >
Definition Variant.h:423
const T & get() const
Definition Variant.h:368
VariantImpl & operator=(VariantImpl &&other)
Definition Variant.h:281
VariantImpl & operator=(const VariantImpl &other)
Definition Variant.h:262
auto emplace(Args &&...args) -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:323
VariantDetail::Index::VariantIndex IndexT
Definition Variant.h:189
VariantImpl(const T &val) noexcept(std::is_nothrow_constructible< typename std::decay< T >::type, decltype(val)>::value)
Definition Variant.h:213
bool holds_alternative() const
Definition Variant.h:331
const T * get_if() const
Definition Variant.h:375
T & emplace(Args &&...args)
Definition Variant.h:302
std::size_t index() const
Definition Variant.h:438
typename ThisVariantAlternative< 0 >::type FirstAlternative
Definition Variant.h:181
static constexpr bool isFirstAlternativeNothrowDefaultConstructible
Definition Variant.h:183
VariantImpl(T &&val) noexcept(std::is_nothrow_constructible< typename std::decay< T >::type, decltype(val)>::value)
Definition Variant.h:230
T * get_if()
Definition Variant.h:345
static constexpr bool isFirstAlternativeDefaultConstructible
Definition Variant.h:186
auto get() const -> const typename ThisVariantAlternative< Index >::type &
Definition Variant.h:388
typename std::add_pointer< typename std::add_const< typename ThisVariantAlternative< Index >::type >::type >::type ConstRawAlternativePointerT
Definition Variant.h:421
~VariantImpl()
Definition Variant.h:440
VariantImpl(Aws::Crt::InPlaceTypeT< T >, Args &&...args)
Definition Variant.h:247
VariantImpl(VariantImpl &&other)
Definition Variant.h:205
void Visit(VisitorT &&visitor)
Definition Variant.h:787
auto get() const -> const typename ThisVariantAlternative< Index >::type &
Definition Variant.h:762
Variant(Aws::Crt::InPlaceTypeT< T > ipt, Args &&...args)
Definition Variant.h:715
auto emplace(Args &&...args) -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:727
auto get_if() const -> ConstRawAlternativePointerT< Index >
Definition Variant.h:780
T * get_if()
Definition Variant.h:742
const T & get() const
Definition Variant.h:752
const T * get_if() const
Definition Variant.h:757
auto get() -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:747
Variant(const T &val) noexcept(std::is_nothrow_constructible< typename std::decay< T >::type, decltype(val)>::value)
Definition Variant.h:702
typename std::add_pointer< typename ThisVariantAlternative< Index >::type >::type RawAlternativePointerT
Definition Variant.h:769
T & emplace(Args &&...args)
Definition Variant.h:721
Variant(T &&val) noexcept(std::is_nothrow_constructible< typename std::decay< T >::type, decltype(val)>::value)
Definition Variant.h:709
T & get()
Definition Variant.h:737
std::size_t index() const
Definition Variant.h:785
auto get_if() -> RawAlternativePointerT< Index >
Definition Variant.h:771
static constexpr std::size_t AlternativeCount
Definition Variant.h:687
typename std::add_pointer< typename std::add_const< typename ThisVariantAlternative< Index >::type >::type >::type ConstRawAlternativePointerT
Definition Variant.h:778
Variant() noexcept(isFirstAlternativeNothrowDefaultConstructible)
Definition Variant.h:692
bool holds_alternative() const
Definition Variant.h:732
VariantDetail::Index::VariantIndex IndexT
Definition Variant.h:686
constexpr bool ContainsType()
Definition Variant.h:73
constexpr VariantIndex GetIndexOf(VariantIndex curIndex=0)
Definition Variant.h:57
short VariantIndex
Definition Variant.h:55
constexpr std::size_t AlignAsPack(std::size_t curMax=0)
Definition Variant.h:41
constexpr std::size_t GetMaxSizeOf(std::size_t curMax=0)
Definition Variant.h:29
constexpr const T & ConstExprMax(const T &a, const T &b)
Definition Variant.h:21
std::unique_ptr< T, std::function< void(T *)> > ScopedResource
Definition Types.h:163
Definition Allocator.h:11
Definition StringView.h:862
static const bool value
Definition Variant.h:91