12#include "_detail/variant_helper.hpp"
40template <
size_t I,
class T>
50 static_assert(Detail::NoneIs<std::is_void<TS>::value...>,
"CVB: void types are not allowed");
51 static_assert(Detail::NoneIs<std::is_reference<TS>::value...>,
"CVB: reference types are not allowed");
52 static_assert(Detail::NoneIs<std::is_const<TS>::value...>,
"CVB: const types are not allowed");
53 static_assert(Detail::NoneIs<std::is_volatile<TS>::value...>,
"CVB: volatile types are not allowed");
55# pragma region friend access
56 template <
size_t I,
class... ETS>
58 template <
size_t I,
class... ETS>
60 template <
size_t I,
class... ETS>
62 template <
class... ETS>
64 template <
class... ETS>
68 static const constexpr size_t StorageSize = Detail::Max<
sizeof(TS)...>;
69 static const constexpr size_t StorageAlignment = Detail::Max<
alignof(TS)...>;
78 void delete_if_valid()
noexcept;
83 const constexpr auto exactIndex = Detail::IndexOf<T, TS...>;
84 const constexpr auto newIndex = exactIndex !=
variant_npos ? exactIndex : Detail::IndexOfAssignable<T, TS...>;
85 static_assert(newIndex !=
variant_npos,
"CVB: assigned type not compatible to alternatives list");
87 using NewT = Detail::TypeAt<newIndex, TS...>;
90 new(&data_) NewT(std::forward<T>(value));
101 new(&data_) Detail::TypeAt<0, TS...>{};
143 template <class T, typename std::enable_if<!std::is_same<T, variant &>::value,
int>::type = 0>
147 set(std::forward<T>(value));
161 template <class T, typename std::enable_if<!std::is_same<T, variant &>::value,
int>::type = 0>
164 set(std::forward<T>(value));
176 template <
size_t I,
class... ARGS>
186 template <
class T,
class... ARGS>
189 const constexpr auto newIndex = Detail::IndexOf<T, TS...>;
190 static_assert(newIndex !=
variant_npos,
"CVB: assigned type not in alternatives list");
192 return emplace<newIndex>(std::forward<ARGS>(args)...);
198 size_t index() const noexcept {
return index_; }
215#pragma region monostate
254#pragma region variant_alternative
256template <
size_t I,
class... TS>
259 using type = Detail::TypeAt<I, TS...>;
262template <
size_t I,
class T>
265template <
size_t I,
class T>
266struct variant_alternative<I, const T> : variant_alternative<I, typename std::remove_reference<T>::type> {};
268template <
size_t I,
class T>
269struct variant_alternative<I, volatile T> : variant_alternative<I, typename std::remove_reference<T>::type> {};
271template <
size_t I,
class T>
272struct variant_alternative<I, const volatile T> : variant_alternative<I, typename std::remove_reference<T>::type> {};
277template <
size_t I,
class T>
282#pragma region variant_size
291template <
class... TS>
301struct variant_size<volatile T> : variant_size<typename std::remove_reference<T>::type> {};
304struct variant_size<const volatile T> : variant_size<typename std::remove_reference<T>::type> {};
327template <
size_t I,
class... TS>
330 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
338template <
size_t I,
class... TS>
341 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
349template <
size_t I,
class... TS>
352 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
373template <
class T,
class... TS>
376 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
377 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
379 return get<index>(var);
383template <
class T,
class... TS>
386 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
387 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
389 return get<index>(var);
393template <
class T,
class... TS>
396 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
397 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
399 return get<index>(std::move(var));
404#pragma region get_if<I>
416template <
size_t I,
class... TS>
419 if(!pvar || pvar->index() != I)
422 return &get<I>(*pvar);
426template <
size_t I,
class... TS>
429 if(!pvar || pvar->index() != I)
432 return &get<I>(*pvar);
437#pragma region get_if<I>
449template <
class T,
class... TS>
452 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
453 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
455 return get_if<index>(pvar);
459template <
class T,
class... TS>
462 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
463 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
465 return get_if<index>(pvar);
470#pragma region holds_alternative
480template <
class T,
class... TS>
483 static_assert(Detail::Contains<T, TS...>,
"CVB: alternative is not contained in variant.");
484 return var.index() == Detail::IndexOf<T, TS...>;
491#pragma region VisitHelper
497template <
class T,
size_t COUNT,
size_t I = 0>
500 template <
class VISITOR,
class VARIANT>
501 T operator()(VISITOR &&visitor, VARIANT &&var)
const
504 return visitor(get<I>(std::forward<VARIANT>(var)));
506 return VisitHelper1<T, COUNT, I + 1>{}(std::forward<VISITOR>(visitor), std::forward<VARIANT>(var));
510template <
class T,
size_t COUNT>
511struct VisitHelper1<T, COUNT, COUNT>
513 template <
class VISITOR,
class VARIANT>
514 T operator()(VISITOR &&, VARIANT &&)
const
516 throw bad_variant_access{};
535template <
class VISITOR,
class VARIANT>
536auto visit(VISITOR &&visitor, VARIANT &&var) ->
decltype(visitor(get<0>(var)))
538 using RESULT =
decltype(visitor(get<0>(var)));
539 using HELPER = Detail::VisitHelper1<RESULT, variant_alternatives_size_v<VARIANT>>;
541 return HELPER{}(std::forward<VISITOR>(visitor), std::forward<VARIANT>(var));
546#pragma region comparison operators
558template <
class... TS>
575template <
class... TS>
578 return !(lhs == rhs);
594template <
class... TS>
601 || (lhs.
index() == rhs.
index() && visit(Detail::VariantLess{&lhs.data_}, rhs))
613template <
class... TS>
628template <
class... TS>
643template <
class... TS>
651#pragma region variant copy
653template <
class... TS>
657 visit(Detail::VariantCopier{&data_}, rhs);
660template <
class... TS>
666 visit(Detail::VariantCopier{&data_}, rhs);
675#pragma region variant move
677template <
class... TS>
681 visit(Detail::VariantMover{&data_}, std::move(rhs));
682 rhs.delete_if_valid();
685template <
class... TS>
691 visit(Detail::VariantMover{&data_}, std::move(rhs));
693 rhs.delete_if_valid();
701#pragma region variant swap
703template <
class... TS>
708 auto old = std::move(*
this);
709 *
this = std::move(other);
710 other = std::move(old);
715#pragma region variant::delete_if_valid
718template <
class... TS>
721 if(!valueless_by_exception())
723 visit(Detail::VariantDestructor{}, *
this);
730#pragma region variant::emplace<I>
732template <
class... TS>
733template <
size_t I,
class... ARGS>
736 using NewT = Detail::TypeAt<I, TS...>;
739 auto result =
new(&data_) NewT(std::forward<ARGS>(args)...);
756 template <
class... TS>
Error when accessing not set alternative.
Definition: variant.hpp:26
bad_variant_access()=default
Default ctor.
This class is a replacement for C++17 std::variant.
Definition: variant.hpp:49
variant & operator=(const variant &rhs)
Copy operator.
Definition: variant.hpp:661
size_t index() const noexcept
Gets the zero-based index of the alternative held by this instance.
Definition: variant.hpp:198
bool valueless_by_exception() const noexcept
Returns false only if this instance holds a value.
Definition: variant.hpp:212
variant() noexcept
Default ctor creating a variant with default value of the first alternative type.
Definition: variant.hpp:98
variant(T &&value)
Ctor from an object of supported type T.
Definition: variant.hpp:144
std::add_pointer< constvariant_alternative_t< I, variant< TS... > > >::type get_if(const variant< TS... > *pvar) noexcept
Tries to get the value of the given variant pointer pvar as the alternative with index I.
Definition: variant.hpp:417
variant_alternative< I, variant< TS... > >::type & emplace(ARGS &&... args)
Emplaces an object as alternative at index I.
Definition: variant.hpp:734
std::add_pointer< constT >::type get_if(const variant< TS... > *pvar) noexcept
Tries to get the value of the given variant pointer pvar as the alternative with type T.
Definition: variant.hpp:450
auto visit(VISITOR &&visitor, VARIANT &&var) -> decltype(visitor(get< 0 >(var)))
Visits the given variant var. Cvb::Shims::visit can only visit one variant (not multiple like std::vi...
Definition: variant.hpp:536
~variant() noexcept
Destructor.
Definition: variant.hpp:105
void swap(variant &other)
Swaps the content of this variant with the other one.
Definition: variant.hpp:704
const variant_alternative_t< I, variant< TS... > > & get(const variant< TS... > &var)
Gets the value of the given variant var as the alternative with index I.
Definition: variant.hpp:328
bool holds_alternative(const variant< TS... > &var) noexcept
Gets whether the variant var holds an instance of type T.
Definition: variant.hpp:481
const T & get(const variant< TS... > &var)
Gets the value of the given variant var as the alternative with type T.
Definition: variant.hpp:374
T & emplace(ARGS &&... args)
Emplaces an object as a type T.
Definition: variant.hpp:187
static const constexpr size_t variant_npos
Returned by variant::index() on invalid state.
Definition: variant.hpp:33
typename variant_alternative< I, T >::type variant_alternative_t
Helper type alias for Shims::variant_alternative.
Definition: variant.hpp:278
std::add_pointer< variant_alternative_t< I, variant< TS... > > >::type get_if(variant< TS... > *pvar) noexcept
Definition: variant.hpp:427
variant_alternative_t< I, variant< TS... > > & get(variant< TS... > &var)
Definition: variant.hpp:339
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
Unit type intended for use as a well-behaved empty alternative in variant.
Definition: variant.hpp:226
constexpr bool operator>=(monostate, monostate) noexcept
Definition: variant.hpp:242
constexpr bool operator!=(monostate, monostate) noexcept
Definition: variant.hpp:250
constexpr bool operator<(monostate, monostate) noexcept
Definition: variant.hpp:230
constexpr bool operator==(monostate, monostate) noexcept
Definition: variant.hpp:246
constexpr bool operator<=(monostate, monostate) noexcept
Definition: variant.hpp:238
constexpr bool operator>(monostate, monostate) noexcept
Definition: variant.hpp:234
Compile-time index access to the type of the alternatives at index I.
Definition: variant.hpp:41
Get the number of alternatives in a variant.
Definition: variant.hpp:289