7#include <aws/common/assert.h>
18 namespace VariantDetail
22 return (
a <
b) ?
b :
a;
25 namespace ParameterPackSize
58 return std::is_same<T, Last>::value ?
curIndex : -1;
74 return std::is_same<T, Last>::value;
93#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
100 std::tuple<typename std::add_pointer<Ts>::type...>
as_tuple;
103 template <IndexT Index,
typename First,
typename Second,
typename...
Rest>
111 template <IndexT Index,
typename Last>
void InitTuple(
char *storage)
113 Last *value =
reinterpret_cast<Last *
>(storage);
114 std::get<Index>(as_tuple) = value;
121 template <std::size_t Index,
typename...
Ts>
class VariantAlternative;
132 template <
typename OtherT>
133 using EnableIfOtherIsThisVariantAlternative =
typename std::
134 enable_if<VariantDetail::Checker::HasType<typename std::decay<OtherT>::type,
Ts...>::value,
int>::type;
150 m_index = other.m_index;
151 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveConstructor());
157 m_index = other.m_index;
158 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveConstructor());
161 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
Variant(
const T &
val)
165 "This variant does not have such alternative T.");
167 sizeof(
T) <= STORAGE_SIZE,
168 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
170 using PlainT =
typename std::decay<T>::type;
176 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
Variant(
T &&
val)
180 "This variant does not have such alternative T.");
182 sizeof(
T) <= STORAGE_SIZE,
183 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
185 using PlainT =
typename std::decay<T>::type;
186 new (m_storage)
PlainT(std::forward<T>(
val));
196 "This variant does not have such alternative T.");
198 sizeof(
T) <= STORAGE_SIZE,
199 "Attempting to instantiate a Variant with a type bigger than all alternatives.");
201 using PlainT =
typename std::decay<T>::type;
202 new (m_storage)
PlainT(std::forward<Args>(
args)...);
212 if (m_index != other.m_index)
215 m_index = other.m_index;
216 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveConstructor());
220 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveAssigner());
231 if (m_index != other.m_index)
234 m_index = other.m_index;
235 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveConstructor());
239 VisitorUtil<0, Ts...>::VisitBinary(
this, std::move(other), CopyMoveAssigner());
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.");
258 using PlainT =
typename std::decay<T>::type;
259 new (m_storage)
PlainT(std::forward<Args>(
args)...);
263 T *value =
reinterpret_cast<T *
>(m_storage);
267 template <std::size_t Index,
typename...
Args>
270 static_assert(Index <
AlternativeCount,
"Unknown alternative index to emplace");
271 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
276 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
bool holds_alternative()
const
283 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T &
get()
286 T *value =
reinterpret_cast<T *
>(m_storage);
290 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
T *
get_if()
294 T *value =
reinterpret_cast<T *
>(m_storage);
303 template <std::
size_t Index>
auto get() ->
typename ThisVariantAlternative<Index>::type &
305 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
307 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
313 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T &
get()
const
316 const T *value =
reinterpret_cast<const T *
>(m_storage);
320 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
const T *
get_if()
const
324 T *value =
reinterpret_cast<T *
>(m_storage);
335 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
337 using AlternativeT =
typename ThisVariantAlternative<Index>::type;
345 template <std::
size_t Index>
347 typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
351 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
364 template <std::
size_t Index>
366 typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
370 static_assert(Index <
AlternativeCount,
"Unknown alternative index to get");
383 std::size_t
index()
const {
return m_index; }
389 return VisitorUtil<0, Ts...>::Visit(
this, std::forward<VisitorT>(
visitor));
397#if defined(AWS_CRT_ENABLE_VARIANT_DEBUG)
398 VariantDetail::VariantDebug::VariantDebugBrowser<
Ts...>
browser = m_storage;
401 template <
size_t Index>
constexpr bool holds_alternative()
const {
return Index == m_index; }
405 template <
typename AlternativeT>
void operator()(
AlternativeT &&value)
const
408 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
421 struct CopyMoveConstructor
425 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
426 new (&value)
PlaintT(std::move<AlternativeT>(other));
429 template <
typename AlternativeT,
typename ConstAlternativeT>
432 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
434 typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
435 static_assert(std::is_same<PlaintT, PlaintOtherT>::value,
"Incompatible types");
441 struct CopyMoveAssigner
445 value = std::move(other);
448 template <
typename AlternativeT,
typename ConstAlternativeT>
451 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
453 typename std::remove_const<typename std::remove_reference<AlternativeT>::type>::type;
454 static_assert(std::is_same<PlaintT, PlaintOtherT>::value,
"Incompatible types");
460 template <
IndexT Index,
typename...
Args>
struct VisitorUtil;
467 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
469 if (Index ==
pThis->m_index)
482 template <
typename VisitorStruct>
485 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
487 if (Index ==
pThis->m_index)
500 template <
typename VisitorStruct>
503 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
505 if (Index ==
pThis->m_index)
520 template <IndexT Index,
typename Last>
struct VisitorUtil<Index,
Last>
524 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
526 if (Index ==
pThis->m_index)
538 template <
typename VisitorStruct>
541 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
543 if (Index ==
pThis->m_index)
555 template <
typename VisitorStruct>
558 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
560 if (Index ==
pThis->m_index)
580 using type =
typename std::tuple_element<Index, std::tuple<
Ts...>>
::type;
589 constexpr static const std::size_t Value = T::AlternativeCount;
VariantAlternative(const Variant< Ts... > &)
Definition Variant.h:582
typename std::tuple_element< Index, std::tuple< Ts... > >::type type
Definition Variant.h:580
VariantAlternative(const Variant< Ts... > *)
Definition Variant.h:584
Variant & operator=(Variant &&other)
Definition Variant.h:226
Variant(Aws::Crt::InPlaceTypeT< T >, Args &&...args)
Definition Variant.h:192
~Variant()
Definition Variant.h:385
void Visit(VisitorT &&visitor)
Definition Variant.h:387
auto get() const -> const typename ThisVariantAlternative< Index >::type &
Definition Variant.h:333
auto emplace(Args &&...args) -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:268
auto get_if() const -> ConstRawAlternativePointerT< Index >
Definition Variant.h:368
T * get_if()
Definition Variant.h:290
const T & get() const
Definition Variant.h:313
const T * get_if() const
Definition Variant.h:320
auto get() -> typename ThisVariantAlternative< Index >::type &
Definition Variant.h:303
typename std::add_pointer< typename ThisVariantAlternative< Index >::type >::type RawAlternativePointerT
Definition Variant.h:347
Variant(Variant &&other)
Definition Variant.h:154
Variant(const Variant &other)
Definition Variant.h:147
Variant(const T &val)
Definition Variant.h:161
T & emplace(Args &&...args)
Definition Variant.h:247
T & get()
Definition Variant.h:283
std::size_t index() const
Definition Variant.h:383
auto get_if() -> RawAlternativePointerT< Index >
Definition Variant.h:349
static constexpr std::size_t AlternativeCount
Definition Variant.h:138
typename std::add_pointer< typename std::add_const< typename ThisVariantAlternative< Index >::type >::type >::type ConstRawAlternativePointerT
Definition Variant.h:366
Variant(T &&val)
Definition Variant.h:176
bool holds_alternative() const
Definition Variant.h:276
Variant()
Definition Variant.h:140
Variant & operator=(const Variant &other)
Definition Variant.h:207
VariantDetail::Index::VariantIndex IndexT
Definition Variant.h:137
constexpr bool ContainsType()
Definition Variant.h:72
constexpr VariantIndex GetIndexOf(VariantIndex curIndex=0)
Definition Variant.h:56
short VariantIndex
Definition Variant.h:54
constexpr std::size_t AlignAsPack(std::size_t curMax=0)
Definition Variant.h:40
constexpr std::size_t GetMaxSizeOf(std::size_t curMax=0)
Definition Variant.h:28
constexpr const T & ConstExprMax(const T &a, const T &b)
Definition Variant.h:20
std::unique_ptr< T, std::function< void(T *)> > ScopedResource
Definition Types.h:163
Definition Allocator.h:11
static const bool value
Definition Variant.h:90