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;
200 AWS_FATAL_ASSERT(other.m_index != -1);
201 m_index = other.m_index;
202 VisitorUtil<0, Ts...>::VisitBinary(
this, other, CopyMoveConstructor());
207 AWS_FATAL_ASSERT(other.m_index != -1);
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;
224 new (m_storage) PlainT(val);
226 AWS_ASSERT(m_index != -1);
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));
243 AWS_ASSERT(m_index != -1);
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)...);
259 AWS_ASSERT(m_index != -1);
266 AWS_FATAL_ASSERT(other.m_index != -1);
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());
285 AWS_FATAL_ASSERT(other.m_index != -1);
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());
301 template <
typename T,
typename... Args, EnableIfOtherIsThisVariantAlternative<T> = 1>
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)...);
316 AWS_ASSERT(m_index != -1);
318 T *value =
reinterpret_cast<T *
>(m_storage);
322 template <std::size_t
Index,
typename... Args>
328 return emplace<AlternativeT, Args...>(std::forward<Args>(args)...);
331 template <
typename T, EnableIfOtherIsThisVariantAlternative<T> = 1>
bool holds_alternative()
const
333 AWS_ASSERT(m_index != -1);
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);
363 AlternativeT *ret =
reinterpret_cast<AlternativeT *
>(m_storage);
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);
388 template <std::
size_t Index>
auto get() const -> const typename ThisVariantAlternative<
Index>::type &
391 AWS_ASSERT(
Index == m_index);
393 const AlternativeT *ret =
reinterpret_cast<const AlternativeT *
>(m_storage);
400 template <std::
size_t Index>
402 typename std::add_pointer<typename ThisVariantAlternative<Index>::type>::type;
410 AlternativePtrT value =
reinterpret_cast<AlternativePtrT
>(m_storage);
419 template <std::
size_t Index>
421 typename std::add_const<typename ThisVariantAlternative<Index>::type>::type>::type;
429 AlternativePtrT value =
reinterpret_cast<AlternativePtrT
>(m_storage);
438 std::size_t
index()
const {
return m_index; }
442 template <
typename VisitorT>
void Visit(VisitorT &&visitor)
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;
460 template <
typename AlternativeT>
void operator()(AlternativeT &&value)
const
463 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
470 AWS_FATAL_ASSERT(m_index != -1);
476 struct CopyMoveConstructor
478 template <
typename AlternativeT>
void operator()(AlternativeT &&value, AlternativeT &&other)
const
480 using PlaintT =
typename std::remove_reference<AlternativeT>::type;
481 new (&value) PlaintT(std::move<AlternativeT>(other));
484 template <
typename AlternativeT,
typename ConstAlternativeT>
485 void operator()(AlternativeT &&value, ConstAlternativeT &other)
const
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");
492 new (&value) PlaintT(other);
496 struct CopyMoveAssigner
498 template <
typename AlternativeT>
void operator()(AlternativeT &&value, AlternativeT &&other)
const
500 value = std::move(other);
503 template <
typename AlternativeT,
typename ConstAlternativeT>
504 void operator()(AlternativeT &&value, ConstAlternativeT &other)
const
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;
517 template <
IndexT Index,
typename First,
typename Second,
typename... Rest>
518 struct VisitorUtil<Index, First, Second, Rest...>
520 template <
typename VisitorStruct>
static void Visit(
VariantImpl *pThis, VisitorStruct &&visitor)
522 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
524 if (Index == pThis->m_index)
527 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
532 VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>
::Visit(
533 pThis, std::forward<VisitorStruct>(visitor));
537 template <
typename VisitorStruct>
538 static void VisitBinary(
539 VariantImpl<Ts...> *pThis,
540 VariantImpl<Ts...> &&other,
541 VisitorStruct &&visitor)
543 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
545 if (Index == pThis->m_index)
548 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
549 visitor(*value, other.get<AlternativeT>());
553 VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
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,
562 VisitorStruct &&visitor)
564 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
566 if (Index == pThis->m_index)
569 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
570 const AlternativeT &otherValue = other.get<AlternativeT>();
571 visitor(*value, otherValue);
575 VisitorUtil<static_cast<IndexT>(Index + 1), Second, Rest...>::VisitBinary(
576 pThis, other, std::forward<VisitorStruct>(visitor));
581 template <IndexT Index,
typename Last>
struct VisitorUtil<Index, Last>
583 template <
typename VisitorStruct>
static void Visit(
VariantImpl *pThis, VisitorStruct &&visitor)
585 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
587 if (Index == pThis->m_index)
590 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
595 AWS_FATAL_ASSERT(!
"Unknown variant alternative to visit!");
599 template <
typename VisitorStruct>
600 static void VisitBinary(
601 VariantImpl<Ts...> *pThis,
602 VariantImpl<Ts...> &&other,
603 VisitorStruct &&visitor)
605 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
607 if (Index == pThis->m_index)
610 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
611 visitor(*value, other.get<AlternativeT>());
615 AWS_FATAL_ASSERT(!
"Unknown variant alternative to visit!");
619 template <
typename VisitorStruct>
620 static void VisitBinary(
621 VariantImpl<Ts...> *pThis,
622 const VariantImpl<Ts...> &other,
623 VisitorStruct &&visitor)
625 static_assert(Index <
AlternativeCount,
"Attempting to visit unknown Index Type");
627 if (Index == pThis->m_index)
630 AlternativeT *value =
reinterpret_cast<AlternativeT *
>(pThis->m_storage);
631 const AlternativeT &otherValue = other.get<AlternativeT>();
632 visitor(*value, otherValue);
636 AWS_FATAL_ASSERT(!
"Unknown variant alternative to visit!");