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> {};
333template <
size_t I,
class... TS>
336 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
347template <
size_t I,
class... TS>
350 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
361template <
size_t I,
class... TS>
364 static_assert(I <
sizeof...(TS),
"CVB: alternative index out of range");
391template <
class T,
class... TS>
394 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
395 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
397 return get<index>(var);
404template <
class T,
class... TS>
407 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
408 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
410 return get<index>(var);
417template <
class T,
class... TS>
420 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
421 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
423 return get<index>(std::move(var));
428#pragma region get_if<I>
441template <
size_t I,
class... TS>
444 if(!pvar || pvar->index() != I)
447 return &get<I>(*pvar);
454template <
size_t I,
class... TS>
457 if(!pvar || pvar->index() != I)
460 return &get<I>(*pvar);
465#pragma region get_if<I>
483template <
class T,
class... TS>
486 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
487 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
489 return get_if<index>(pvar);
496template <
class T,
class... TS>
499 static const constexpr size_t index = Detail::IndexOf<T, TS...>;
500 static_assert(index !=
variant_npos,
"CVB: type not in alternatives list");
502 return get_if<index>(pvar);
507#pragma region holds_alternative
517template <
class T,
class... TS>
520 static_assert(Detail::Contains<T, TS...>,
"CVB: alternative is not contained in variant.");
521 return var.index() == Detail::IndexOf<T, TS...>;
528#pragma region VisitHelper
534template <
class T,
size_t COUNT,
size_t I = 0>
537 template <
class VISITOR,
class VARIANT>
538 T operator()(VISITOR &&visitor, VARIANT &&var)
const
541 return visitor(get<I>(std::forward<VARIANT>(var)));
543 return VisitHelper1<T, COUNT, I + 1>{}(std::forward<VISITOR>(visitor), std::forward<VARIANT>(var));
547template <
class T,
size_t COUNT>
548struct VisitHelper1<T, COUNT, COUNT>
550 template <
class VISITOR,
class VARIANT>
551 T operator()(VISITOR &&, VARIANT &&)
const
553 throw bad_variant_access{};
572template <
class VISITOR,
class VARIANT>
573auto visit(VISITOR &&visitor, VARIANT &&var) ->
decltype(visitor(get<0>(var)))
575 using RESULT =
decltype(visitor(get<0>(var)));
576 using HELPER = Detail::VisitHelper1<RESULT, variant_alternatives_size_v<VARIANT>>;
578 return HELPER{}(std::forward<VISITOR>(visitor), std::forward<VARIANT>(var));
583#pragma region comparison operators
595template <
class... TS>
612template <
class... TS>
615 return !(lhs == rhs);
631template <
class... TS>
638 || (lhs.
index() == rhs.
index() && visit(Detail::VariantLess{&lhs.data_}, rhs))
650template <
class... TS>
665template <
class... TS>
680template <
class... TS>
688#pragma region variant copy
690template <
class... TS>
694 visit(Detail::VariantCopier{&data_}, rhs);
697template <
class... TS>
703 visit(Detail::VariantCopier{&data_}, rhs);
712#pragma region variant move
714template <
class... TS>
720 visit(Detail::VariantMover{ &data_ }, std::move(rhs));
721 rhs.delete_if_valid();
729template <
class... TS>
735 visit(Detail::VariantMover{&data_}, std::move(rhs));
737 rhs.delete_if_valid();
745#pragma region variant swap
747template <
class... TS>
752 auto old = std::move(*
this);
753 *
this = std::move(other);
754 other = std::move(old);
759#pragma region variant::delete_if_valid
762template <
class... TS>
767 if (!valueless_by_exception())
769 visit(Detail::VariantDestructor{}, *
this);
781#pragma region variant::emplace<I>
783template <
class... TS>
784template <
size_t I,
class... ARGS>
787 using NewT = Detail::TypeAt<I, TS...>;
790 auto result =
new(&data_) NewT(std::forward<ARGS>(args)...);
807 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:698
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
variant_alternative< I, variant< TS... > >::type & emplace(ARGS &&... args)
Emplaces an object as alternative at index I.
Definition: variant.hpp:785
std::add_pointer< constT >::type get_if(const variant< TS... > *pvar) noexcept
Definition: variant.hpp:484
auto visit(VISITOR &&visitor, VARIANT &&var) -> decltype(visitor(get< 0 >(var)))
Visits the given Shims::variant var. Cvb::Shims::visit can only visit one variant (not multiple like ...
Definition: variant.hpp:573
~variant() noexcept
Destructor.
Definition: variant.hpp:105
void swap(variant &other)
Swaps the content of this variant with the other one.
Definition: variant.hpp:748
std::add_pointer< T >::type get_if(variant< TS... > *pvar) noexcept
Definition: variant.hpp:497
const variant_alternative_t< I, variant< TS... > > & get(const variant< TS... > &var)
Definition: variant.hpp:334
std::add_pointer< variant_alternative_t< I, variant< TS... > > >::type get_if(variant< TS... > *pvar) noexcept
Definition: variant.hpp:455
T get(variant< TS... > &&var)
Definition: variant.hpp:418
variant_alternative_t< I, variant< TS... > > get(variant< TS... > &&var)
Definition: variant.hpp:362
variant_alternative_t< I, variant< TS... > > & get(variant< TS... > &var)
Definition: variant.hpp:348
T & get(variant< TS... > &var)
Definition: variant.hpp:405
bool holds_alternative(const variant< TS... > &var) noexcept
Gets whether the Shims::variant var holds an instance of type T.
Definition: variant.hpp:518
const T & get(const variant< TS... > &var)
Definition: variant.hpp:392
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
Root namespace for the Image Manager interface.
Definition: c_barcode.h:15
Unit type intended for use as a well-behaved empty alternative in Shims::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