1#ifndef ZSERIO_VARIANT_H_INC
2#define ZSERIO_VARIANT_H_INC
16template <
size_t I,
typename... T>
19 using type = std::tuple_element_t<I, std::tuple<T...>>;
22template <
auto I,
typename... T>
23using type_at_t =
typename type_at<static_cast<size_t>(I), T...>::type;
25template <
size_t N,
typename V,
typename F>
26void for_active_item(
const V&, F&&, std::false_type)
29template <
size_t N,
typename V,
typename F>
30void for_active_item(
const V& var, F&& fun, std::true_type = {})
32 using INDEX =
typename V::IndexType;
33 if (
static_cast<size_t>(var.index()) == N - 1)
35 std::forward<F>(fun)(*var.template get_if<static_cast<INDEX>(N - 1)>());
37 for_active_item<N - 1>(var, std::forward<F>(fun), std::bool_constant<(N - 1 > 0)>());
40template <
size_t N,
typename V,
typename F>
41void for_active_item(V& var, F&& fun, std::true_type = {})
43 using INDEX =
typename V::IndexType;
44 if (
static_cast<size_t>(var.index()) == N - 1)
46 std::forward<F>(fun)(*var.template get_if<static_cast<INDEX>(N - 1)>());
48 for_active_item<N - 1>(var, std::forward<F>(fun), std::bool_constant<(N - 1 > 0)>());
51template <
size_t N,
typename V,
typename F>
52void for_active_item_2(
const V&,
const V&, F&&, std::false_type)
55template <
size_t N,
typename V,
typename F>
56void for_active_item_2(
const V& var1,
const V& var2, F&& fun, std::true_type = {})
59 using INDEX =
typename V::IndexType;
60 if (
static_cast<size_t>(var1.index()) == N - 1)
62 std::forward<F>(fun)(*var1.template get_if<static_cast<INDEX>(N - 1)>(),
63 *var2.template
get_if<
static_cast<INDEX
>(N - 1)>());
65 for_active_item_2<N - 1>(var1, var2, std::forward<F>(fun), std::bool_constant<(N - 1 > 0)>());
101template <
typename ALLOC,
typename INDEX,
typename... T>
104 using AllocTraits = std::allocator_traits<ALLOC>;
166 m_data(
other.m_data),
167 m_index(
other.m_index)
180 m_index(
other.m_index)
194 m_data =
other.m_data;
195 m_index =
other.m_index;
208 m_index(
other.m_index)
221 m_index(
other.m_index)
240 m_data = std::move(
other.m_data);
241 m_index =
other.m_index;
257 return static_cast<size_t>(
index()) == std::variant_npos || !m_data.
hasValue();
268 using U = detail::type_at_t<I, T...>;
279 return m_data.
hasValue() ? m_index :
static_cast<INDEX>(std::variant_npos);
285 template <
INDEX I,
typename U = detail::type_at_t<I, T...>>
298 template <
INDEX I,
typename U = detail::type_at_t<I, T...>>
313 template <
INDEX I,
typename U = detail::type_at_t<I, T...>>
319 throw BadVariantAccess(
"Variant: Attempt to retrieve an inactive element at index ")
320 <<
static_cast<size_t>(I) <<
". Active element index is " <<
static_cast<size_t>(
index());
330 template <
INDEX I,
typename U = detail::type_at_t<I, T...>>
336 throw BadVariantAccess(
"Variant: Attempt to retrieve an inactive element at index ")
337 <<
static_cast<size_t>(I) <<
". Active element index is " <<
static_cast<size_t>(
index());
350 std::swap(m_index,
other.m_index);
360 template <
typename F>
361 auto visit(
F&&
fun) ->
decltype(
fun(std::declval<detail::type_at_t<0, T...>>()))
367 using R =
decltype(
fun(std::declval<detail::type_at_t<0, T...>>()));
368 if constexpr (std::is_same_v<R, void>)
370 detail::for_active_item<
sizeof...(T)>(*
this, [
func = std::forward<F>(
fun)](
auto&
elem) {
377 detail::for_active_item<
sizeof...(T)>(*
this, [&
ret,
func = std::forward<F>(
fun)](
auto&
elem) {
391 template <
typename F>
392 auto visit(
F&&
fun)
const ->
decltype(
fun(std::declval<detail::type_at_t<0, T...>>()))
398 using R =
decltype(
fun(std::declval<detail::type_at_t<0, T...>>()));
399 if constexpr (std::is_same_v<R, void>)
401 detail::for_active_item<
sizeof...(T)>(*
this, [
func = std::forward<F>(
fun)](
auto&
elem) {
408 detail::for_active_item<
sizeof...(T)>(*
this, [&
ret,
func = std::forward<F>(
fun)](
auto&
elem) {
428 detail::for_active_item_2<
sizeof...(T)>(*
this,
other, [&
ret](
auto&
elem1,
auto&
elem2) {
441 return !(*
this ==
other);
457 detail::for_active_item_2<
sizeof...(T)>(*
this,
other, [&
ret](
auto&
elem1,
auto&
elem2) {
470 return other < *
this;
480 return !(
other < *
this);
490 return !(
other > *
this);
500template <
typename INDEX,
typename... T>
510template <
auto I,
typename ALLOC,
typename INDEX,
typename... T>
513 static_assert(std::is_same_v<
decltype(I),
INDEX>,
"Index has a wrong type");
524template <
auto I,
typename ALLOC,
typename INDEX,
typename... T>
527 static_assert(std::is_same_v<
decltype(I),
INDEX>,
"Index has a wrong type");
536template <
auto I,
typename ALLOC,
typename INDEX,
typename... T>
539 static_assert(std::is_same_v<
decltype(I),
INDEX>,
"Index has a wrong type");
548template <
auto I,
typename ALLOC,
typename INDEX,
typename... T>
551 static_assert(std::is_same_v<
decltype(I),
INDEX>,
"Index has a wrong type");
563template <
typename F,
typename ALLOC,
typename INDEX,
typename... T>
566 return var.visit(std::forward<F>(
fun));
577template <
typename F,
typename ALLOC,
typename INDEX,
typename... T>
580 return var.visit(std::forward<F>(
fun));
589template <
typename ALLOC,
typename INDEX,
typename... T>
605template <
typename ALLOC,
typename INDEX,
typename... T>
606struct hash<
zserio::BasicVariant<ALLOC, INDEX, T...>>
~BadVariantAccess() override
bool hasValue() const noexcept
void swap(BasicAny &other)
BasicVariant(const BasicVariant &other, const ALLOC &allocator)
BasicVariant & operator=(BasicVariant &&other)
void swap(BasicVariant &other)
auto visit(F &&fun) const -> decltype(fun(std::declval< detail::type_at_t< 0, T... > >()))
BasicVariant(BasicVariant &&other, const ALLOC &allocator)
BasicVariant(const ALLOC &allocator)
bool operator<=(const BasicVariant &other) const
bool operator<(const BasicVariant &other) const
bool operator>(const BasicVariant &other) const
BasicVariant & operator=(const BasicVariant &other)
BasicVariant(in_place_index_t< I >, ARGS &&... args)
bool valueless_by_exception() const noexcept
BasicVariant(in_place_index_t< I >, const ALLOC &allocator, ARGS &&... args)
const U * get_if() const noexcept
bool operator==(const BasicVariant &other) const
bool operator>=(const BasicVariant &other) const
auto visit(F &&fun) -> decltype(fun(std::declval< detail::type_at_t< 0, T... > >()))
INDEX index() const noexcept
BasicVariant(const BasicVariant &other)
BasicVariant(BasicVariant &&other)
decltype(auto) emplace(ARGS &&... args)
bool operator!=(const BasicVariant &other) const
CppRuntimeException(const char *message="")
decltype(auto) visit(F &&fun, BasicVariant< ALLOC, INDEX, T... > &var)
constexpr in_place_index_t< I > in_place_index
decltype(auto) get(BasicVariant< ALLOC, INDEX, T... > &var)
uint32_t calcHashCode(uint32_t seedValue, const ArrayView< T, ARRAY_TRAITS > &array)
decltype(auto) get_if(BasicVariant< ALLOC, INDEX, T... > *var)
constexpr bool is_first_allocator_v