6#include "utils/traits.h"
15template <
typename T,
typename Variant,
typename =
void>
21template <
typename T,
typename... Ts>
25 std::void_t<decltype (std::variant<Ts...> ())>>
26 : std::bool_constant<(std::is_same_v<T, Ts> || ...)>
31template <
typename T,
typename Variant>
36using MyVariant = std::variant<int, double, std::string>;
47template <
typename... Variants>
48using merge_variants_t =
typename merge_variants<Variants...>::type;
57template <
typename... Types1,
typename... Types2,
typename... Rest>
58struct merge_variants<std::variant<Types1...>, std::variant<Types2...>, Rest...>
61 using type = merge_variants_t<std::variant<Types1..., Types2...>, Rest...>;
77 using type = std::variant<std::reference_wrapper<Ts>...>;
84template <
typename Variant>
89template <
typename... Ts>
92 using type = std::variant<std::reference_wrapper<const Ts>...>;
94template <
typename Variant>
95using to_const_reference_variant =
105 using type = std::variant<std::unique_ptr<Ts>...>;
112template <
typename Variant>
122 using type = std::variant<std::add_pointer_t<Ts>...>;
129template <
typename Variant>
135template <
typename Variant,
typename Base,
typename CastFn>
137convert_to_variant_impl (
const Base * base_ptr, CastFn &&cast_fn) -> Variant
146 auto trycast = [&]<
typename T> () {
147 if (
auto derived = cast_fn.template
operator()<T> (base_ptr))
149 result =
const_cast<T *
> (derived);
155 auto try_all_casts = [&]<
typename... Ts> (std::variant<Ts...> *) {
156 return (trycast.template
operator()<std::remove_pointer_t<Ts>> () || ...);
159 if (!try_all_casts (
static_cast<Variant *
> (
nullptr)))
161 throw std::runtime_error (
"convert_to_variant: no matching type");
179template <
typename Variant,
typename Base>
180 requires std::is_pointer_v<std::variant_alternative_t<0, Variant>>
184 return detail::convert_to_variant_impl<Variant> (
186 []<
typename T> (
const Base * p) {
return dynamic_cast<const T *
> (p); });
195template <
typename Variant,
typename Base>
196 requires std::is_pointer_v<std::variant_alternative_t<0, Variant>>
197 && std::derived_from<Base, QObject>
201 return detail::convert_to_variant_impl<Variant> (
203 []<
typename T> (
const Base * p) {
return qobject_cast<const T *> (p); });
217 using Ts::operator()...;
222template <
typename Variant,
template <
typename>
class Wrapper>
226template <
typename... Ts,
template <
typename>
class Wrapper>
230 using type = std::variant<Wrapper<Ts>...>;
239template <
typename Variant,
template <
typename>
class Wrapper>
auto convert_to_variant(const Base *base_ptr) -> Variant
Converts a base pointer to a variant of pointers using dynamic_cast.
typename to_reference_variant_impl< Variant >::type to_reference_variant
Converts a variant to a variant of reference_wrappers.
auto convert_to_variant_qobj(const Base *base_ptr) -> Variant
Converts a QObject base pointer to a variant of pointers using qobject_cast.
typename to_unique_ptr_variant_impl< Variant >::type to_unique_ptr_variant
Converts a variant to a variant of reference_wrappers.
typename to_pointer_variant_impl< Variant >::type to_pointer_variant
Converts a variant to a variant of pointers.
typename wrap_variant_impl< Variant, Wrapper >::type wrap_variant_t
Converts a variant to a variant where each type is wrapped by Wrapper<T>.
std::variant< std::add_pointer_t< Ts >... > type
The resulting variant type with pointers.
Helper struct to convert a variant to a variant of pointers.
std::variant< std::reference_wrapper< Ts >... > type
The resulting variant type with reference_wrappers.
Helper struct to convert a variant to a variant of references.
std::variant< std::unique_ptr< Ts >... > type
The resulting variant type with reference_wrappers.
Helper struct to convert a variant to a variant of unique_ptr's.
std::variant< Wrapper< Ts >... > type
The resulting variant type with wrapped types.
Helper struct to convert a variant to a variant of ArrangerObjectOwner<T>.