Wildmeshing Toolkit
as_variant.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 namespace detail {
6 
7 template <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 };
14 template <typename BaseVariantTraitsType, bool IsConst, typename... DerivedTypes, size_t Index>
15 struct 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 
57 template <typename BaseVariantTraitsType>
58 typename 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 
69 template <typename BaseVariantTraitsType>
70 typename 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
Definition: autodiff.h:995
BaseVariantTraitsType::ReferenceVariant as_variant(typename BaseVariantTraitsType::BaseType &value)
Definition: as_variant.hpp:58
BaseVariantTraitsType::ConstReferenceVariant as_const_variant(const typename BaseVariantTraitsType::BaseType &value)
Definition: as_variant.hpp:70
static RetType exec(BaseType &value, size_t index)
typename BaseVariantTraitsType::ReferenceVariant RetType
Definition: as_variant.hpp:10
typename BaseVariantTraitsType::BaseType BaseType
Definition: as_variant.hpp:11