Wildmeshing Toolkit
Loading...
Searching...
No Matches
as_variant.hpp
Go to the documentation of this file.
1#pragma once
2
5namespace detail {
6
7template <typename BaseVariantTraitsType, bool IsConst, typename TupleType, size_t Index>
9{
10 using RetType = typename BaseVariantTraitsType::ReferenceVariant;
11 using BaseType = typename BaseVariantTraitsType::BaseType;
12 static RetType exec(BaseType& value, size_t index);
13};
14template <typename BaseVariantTraitsType, bool IsConst, typename... DerivedTypes, size_t Index>
15struct as_variant_impl<BaseVariantTraitsType, IsConst, std::tuple<DerivedTypes...>, Index>
16{
17 using BaseType_ = typename BaseVariantTraitsType::BaseType;
18 using BaseType = std::conditional_t<IsConst, const BaseType_, BaseType_>;
19
20 using TupleType = typename BaseVariantTraitsType::DerivedTypesTuple;
21
22 using RetType = typename BaseVariantTraitsType::template ReferenceVariant_const<IsConst>;
23
24 using RefTupleType = typename BaseVariantTraitsType::template ReferenceTuple_const<IsConst>;
25
26 using MyRefType = std::tuple_element_t<Index, RefTupleType>;
27 using MyDerivedType = std::tuple_element_t<Index, TupleType>;
28
29 using FirstRefType = std::tuple_element_t<0, RefTupleType>;
30 using FirstDerivedType = std::tuple_element_t<0, TupleType>;
31 static auto exec(BaseType& value, size_t index) -> RetType
32 {
33 // handle case that the type isn't found / settle base case
34 if constexpr (Index < sizeof...(DerivedTypes)) {
35 if (index == Index) {
36 return RetType(
37 std::in_place_type_t<MyRefType>{},
38 static_cast<std::conditional_t<IsConst, const MyDerivedType, MyDerivedType>&>(
39 value));
40 } else {
41 if constexpr (Index + 1 < sizeof...(DerivedTypes)) {
43 exec(value, index);
44 }
45 }
46 }
47 throw std::runtime_error("Invalid Input");
48 // This should never happen, just making a dummy to suppress warnings
49 return RetType(
50 std::in_place_type_t<FirstRefType>{},
51 reinterpret_cast<
52 std::conditional_t<IsConst, const FirstDerivedType, FirstDerivedType>&>(value));
53 }
54};
55} // namespace detail
56
57template <typename BaseVariantTraitsType>
58typename BaseVariantTraitsType::ReferenceVariant as_variant(
59 typename BaseVariantTraitsType::BaseType& value)
60{
61 using impl = detail::as_variant_impl<
62 BaseVariantTraitsType,
63 false,
64 typename BaseVariantTraitsType::DerivedTypesTuple,
65 0>;
66 return impl::exec(value, BaseVariantTraitsType::get_index(value));
67}
68
69template <typename BaseVariantTraitsType>
70typename BaseVariantTraitsType::ConstReferenceVariant as_const_variant(
71 const typename BaseVariantTraitsType::BaseType& value)
72{
73 using impl = detail::as_variant_impl<
74 BaseVariantTraitsType,
75 true,
76 typename BaseVariantTraitsType::DerivedTypesTuple,
77 0>;
78 return impl::exec(value, BaseVariantTraitsType::get_index(value));
79}
80} // namespace wmtk::utils::metaprogramming
BaseVariantTraitsType::ReferenceVariant as_variant(typename BaseVariantTraitsType::BaseType &value)
BaseVariantTraitsType::ConstReferenceVariant as_const_variant(const typename BaseVariantTraitsType::BaseType &value)
static RetType exec(BaseType &value, size_t index)
typename BaseVariantTraitsType::ReferenceVariant RetType
typename BaseVariantTraitsType::BaseType BaseType