Block-Structured AMR Software Framework
AMReX_TypeList.H
Go to the documentation of this file.
1 #ifndef AMREX_TYPELIST_H_
2 #define AMREX_TYPELIST_H_
3 #include <AMReX_Config.H>
4 
5 #include <utility>
6 
7 namespace amrex {
8 
10 template <class... Ts>
11 struct TypeList
12 {
14  static constexpr std::size_t size () noexcept { return sizeof...(Ts); }
15 };
16 
17 namespace detail {
18  template <std::size_t I, typename T> struct TypeListGet;
19 
20  template <std::size_t I, typename Head, typename... Tail>
21  struct TypeListGet<I, TypeList<Head, Tail...> >
22  : TypeListGet<I-1, TypeList<Tail...> > {};
23 
24  template <typename Head, typename... Tail>
25  struct TypeListGet<0, TypeList<Head, Tail...> > {
26  using type = Head;
27  };
28 }
29 
31 template <std::size_t I, typename T>
33 
34 namespace detail
35 {
36  template <typename TL, typename F, std::size_t...N>
37  constexpr void for_each_impl (F const&f, std::index_sequence<N...>)
38  {
39  (f(TypeAt<N,TL>{}), ...);
40  }
41 
42  template <typename TL, typename F, std::size_t...N>
43  constexpr bool for_each_until_impl (F const&f, std::index_sequence<N...>)
44  {
45  return (f(TypeAt<N,TL>{}) || ...);
46  }
47 }
48 
76 template <typename... Ts, typename F>
77 constexpr void
79 {
81  (std::forward<F>(f), std::make_index_sequence<sizeof...(Ts)>());
82 }
83 
113 template <typename... Ts, typename F>
114 constexpr bool
116 {
118  (std::forward<F>(f), std::make_index_sequence<sizeof...(Ts)>());
119 }
120 
122 template <typename... As, typename... Bs>
124  return TypeList<As..., Bs...>{};
125 }
126 
127 template <typename... Ls, typename A>
128 constexpr auto single_product (TypeList<Ls...>, A) {
129  return TypeList<decltype(Ls{} + TypeList<A>{})...>{};
130 }
131 
132 template <typename LLs, typename... As>
133 constexpr auto operator* (LLs, TypeList<As...>) {
134  return (TypeList<>{} + ... + single_product(LLs{}, As{}));
135 }
136 
149 template <typename... Ls>
150 constexpr auto CartesianProduct (Ls...) {
151  return (TypeList<TypeList<>>{} * ... * Ls{});
152 }
153 
154 namespace detail {
155  // return TypeList<T, T, T, T, ... (N times)> by using the fast power algorithm
156  template <class T, std::size_t N>
157  constexpr auto SingleTypeMultiplier_impl () {
158  if constexpr (N == 0) {
159  return TypeList<>{};
160  } else if constexpr (N == 1) {
161  return TypeList<T>{};
162  } else if constexpr (N % 2 == 0) {
163  return SingleTypeMultiplier_impl<T, N / 2>() + SingleTypeMultiplier_impl<T, N / 2>();
164  } else {
165  return SingleTypeMultiplier_impl<T, N - 1>() + TypeList<T>{};
166  }
167  }
168 
169  // overload of SingleTypeMultiplier for multiple types:
170  // convert T[N] to T, T, T, T, ... (N times with N >= 1)
171  template <class T, std::size_t N>
172  constexpr auto SingleTypeMultiplier (const T (&)[N]) {
173  return SingleTypeMultiplier_impl<T, N>();
174  }
175 
176  // overload of SingleTypeMultiplier for one regular type
177  template <class T>
178  constexpr auto SingleTypeMultiplier (T) {
179  return TypeList<T>{};
180  }
181 
182  // apply the types of the input TypeList as template arguments to TParam
183  template <template <class...> class TParam, class... Args>
184  constexpr auto TApply (TypeList<Args...>) {
185  return TypeList<TParam<Args...>>{};
186  }
187 }
188 
196 template <template <class...> class TParam, class... Types>
198  (TypeList<>{} + ... + detail::SingleTypeMultiplier(Types{}))
199 ))>;
200 
201 }
202 
203 #endif
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
constexpr bool for_each_until_impl(F const &f, std::index_sequence< N... >)
Definition: AMReX_TypeList.H:43
constexpr auto TApply(TypeList< Args... >)
Definition: AMReX_TypeList.H:184
constexpr auto SingleTypeMultiplier_impl()
Definition: AMReX_TypeList.H:157
constexpr auto SingleTypeMultiplier(const T(&)[N])
Definition: AMReX_TypeList.H:172
constexpr void for_each_impl(F const &f, std::index_sequence< N... >)
Definition: AMReX_TypeList.H:37
Definition: AMReX_Amr.cpp:49
typename detail::TypeListGet< I, T >::type TypeAt
Type at position I of a TypeList.
Definition: AMReX_TypeList.H:32
constexpr auto CartesianProduct(Ls...)
Cartesian Product of TypeLists.
Definition: AMReX_TypeList.H:150
constexpr auto single_product(TypeList< Ls... >, A)
Definition: AMReX_TypeList.H:128
constexpr void ForEach(TypeList< Ts... >, F &&f)
For each type t in TypeList, call f(t)
Definition: AMReX_TypeList.H:78
constexpr bool ForEachUntil(TypeList< Ts... >, F &&f)
For each type t in TypeList, call f(t) until true is returned.
Definition: AMReX_TypeList.H:115
TypeAt< 0, decltype(detail::TApply< TParam >((TypeList<>{}+...+detail::SingleTypeMultiplier(Types{}))))> TypeMultiplier
Return the first template argument with the later arguments applied to it. Types of the form T[N] are...
Definition: AMReX_TypeList.H:199
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > operator+(const GpuComplex< T > &a_x)
Identity operation on a complex number.
Definition: AMReX_GpuComplex.H:166
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > operator*(const GpuComplex< T > &a_x, const GpuComplex< T > &a_y) noexcept
Multiply two complex numbers.
Definition: AMReX_GpuComplex.H:252
Definition: AMReX_FabArrayCommI.H:896
Struct for holding types.
Definition: AMReX_TypeList.H:12
static constexpr std::size_t size() noexcept
Number of types in the TypeList.
Definition: AMReX_TypeList.H:14
Definition: AMReX_TypeList.H:18