12#ifndef __AUDACITY_VARIANT__
13#define __AUDACITY_VARIANT__
29template <
typename Visitor,
typename Variant>
31 using Var = std::remove_reference_t<Variant>;
32 using Alt = std::variant_alternative_t<0, Var>;
33 using QAlt = std::conditional_t<
34 std::is_const_v<Var>,
const Alt,
Alt >;
35 using Arg = std::conditional_t<std::is_lvalue_reference_v<Variant>,
36 std::add_lvalue_reference_t<QAlt>, std::add_rvalue_reference_t<QAlt>
39 decltype(std::invoke(std::declval<Visitor&&>(), std::declval<Arg>()));
43template <
typename Visitor,
typename Variant>
49 throw std::invalid_argument{
"Bad variant"};
53template <
size_t Index,
typename Visitor,
typename Variant>
57 const auto pValue = std::get_if<Index>(&var);
60 if constexpr (std::is_lvalue_reference_v<Variant>)
61 return std::invoke(std::forward<Visitor>(vis), (*pValue));
63 return std::invoke(std::forward<Visitor>(vis), std::move(*pValue));
67template <
size_t Index,
typename Visitor,
typename Variant>
71 static_assert(std::is_same_v<
74 decltype(VisitHelperFunction<Index, Visitor&&, Variant&&>),
77 "Visitor must return the same type for all alternatives of the Variant.");
78 return VisitHelperFunction<Index>(
79 std::forward<Visitor>(vis), std::forward<Variant>(var));
83template <
size_t... Indices,
typename Visitor,
typename Variant>
87 constexpr auto size =
sizeof...(Indices);
89 using Function = Return(*)(Visitor&&,
Variant&&);
90 static constexpr std::array<Function, size + 1> jumpTable{
91 TypeCheckedVisitHelperFunction<Indices>...,
95 return function(std::forward<Visitor>(vis), std::forward<Variant>(var));
103template<
typename...
Types>
106template<
typename...
Types>
109template<
typename...
Types>
112template<
typename...
Types>
119template<
typename ForwardType,
typename Variant>
121 return std::forward<ForwardType>(var);
124template<
typename ForwardType,
typename Variant>
126 return std::forward<ForwardType>(var);
136template <
typename Visitor,
typename Variant,
137 typename VariantBase = detail::deduced_variant<Variant &&>>
140 using ForwardType = std::conditional_t<std::is_lvalue_reference_v<Variant>,
141 std::add_lvalue_reference_t<VariantBase>, VariantBase>;
142 constexpr auto size = std::variant_size_v<VariantBase>;
144 std::forward<Visitor>(vis), detail::forward_variant<ForwardType>(var));
std::vector< Type > Types
decltype(auto) VisitHelper(std::index_sequence< Indices... >, Visitor &&vis, Variant &&var)
Help to define Visit() below.
auto VisitHelperBad(Visitor &&, Variant &&) -> typename VisitHelperReturn< Visitor &&, Variant && >::type
Help to define Visit() below.
decltype(auto) forward_variant(Variant &var)
decltype(auto) VisitHelperFunction(Visitor &&vis, Variant &&var)
Help to define Visit() below.
auto TypeCheckedVisitHelperFunction(Visitor &&vis, Variant &&var) -> typename VisitHelperReturn< Visitor &&, Variant && >::type
Help to define Visit() below.
auto deduce_variant(...) -> void
Unevaluated.
typename decltype(deduce_variant(std::declval< T >()))::type deduced_variant
decltype(auto) Visit(Visitor &&vis, Variant &&var)
Mimic some of std::visit, for the case of one visitor only.
Help to define Visit() below.
std::variant_alternative_t< 0, Var > Alt
std::conditional_t< std::is_const_v< Var >, const Alt, Alt > QAlt
std::conditional_t< std::is_lvalue_reference_v< Variant >, std::add_lvalue_reference_t< QAlt >, std::add_rvalue_reference_t< QAlt > > Arg
decltype(std::invoke(std::declval< Visitor && >(), std::declval< Arg >())) type
std::remove_reference_t< Variant > Var