Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
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
7namespace amrex {
8
10template <class... Ts>
12{
14 static constexpr std::size_t size () noexcept { return sizeof...(Ts); }
15};
16
18namespace detail {
19 template <std::size_t I, typename T> struct TypeListGet;
20
21 template <std::size_t I, typename Head, typename... Tail>
22 struct TypeListGet<I, TypeList<Head, Tail...> >
23 : TypeListGet<I-1, TypeList<Tail...> > {};
24
25 template <typename Head, typename... Tail>
26 struct TypeListGet<0, TypeList<Head, Tail...> > {
27 using type = Head;
28 };
29}
31
33template <std::size_t I, typename T>
34using TypeAt = typename detail::TypeListGet<I,T>::type;
35
37namespace detail
38{
39 template <typename TL, typename F, std::size_t...N>
40 constexpr void for_each_impl (F const&f, std::index_sequence<N...>)
41 {
42 (f(TypeAt<N,TL>{}), ...);
43 }
44
45 template <typename TL, typename F, std::size_t...N>
46 constexpr bool for_each_until_impl (F const&f, std::index_sequence<N...>)
47 {
48 return (f(TypeAt<N,TL>{}) || ...);
49 }
50}
52
80template <typename... Ts, typename F>
81constexpr void
83{
84 detail::for_each_impl<TypeList<Ts...>>
85 (std::forward<F>(f), std::make_index_sequence<sizeof...(Ts)>());
86}
87
117template <typename... Ts, typename F>
118constexpr bool
120{
121 return detail::for_each_until_impl<TypeList<Ts...>>
122 (std::forward<F>(f), std::make_index_sequence<sizeof...(Ts)>());
123}
124
126template <typename... As, typename... Bs>
128 return TypeList<As..., Bs...>{};
129}
130
131template <typename... Ls, typename A>
132constexpr auto single_product (TypeList<Ls...>, A) {
133 return TypeList<decltype(Ls{} + TypeList<A>{})...>{};
134}
135
136template <typename LLs, typename... As>
137constexpr auto operator* (LLs, TypeList<As...>) {
138 return (TypeList<>{} + ... + single_product(LLs{}, As{}));
139}
140
153template <typename... Ls>
154constexpr auto CartesianProduct (Ls...) {
155 return (TypeList<TypeList<>>{} * ... * Ls{});
156}
157
158template <class T, std::size_t N>
159struct TypeArray {
160 using Type = T;
161 static constexpr std::size_t size () noexcept { return N; }
162};
163
165namespace detail {
166 // return TypeList<T, T, T, T, ... (N times)> by using the fast power algorithm
167 template <class T, std::size_t N>
168 constexpr auto SingleTypeMultiplier_impl () {
169 if constexpr (N == 0) {
170 return TypeList<>{};
171 } else if constexpr (N == 1) {
172 return TypeList<T>{};
173 } else if constexpr (N % 2 == 0) {
174 return SingleTypeMultiplier_impl<T, N / 2>() + SingleTypeMultiplier_impl<T, N / 2>();
175 } else {
176 return SingleTypeMultiplier_impl<T, N - 1>() + TypeList<T>{};
177 }
178 }
179
180 // overload of SingleTypeMultiplier for multiple types:
181 // convert T[N] to T, T, T, T, ... (N times with N >= 1)
182 template <class T, std::size_t N>
183 constexpr auto SingleTypeMultiplier (const T (&)[N]) {
184 return SingleTypeMultiplier_impl<T, N>();
185 }
186
187 // overload of SingleTypeMultiplier for multiple types:
188 // convert TypeArray<T,N> to T, T, T, T, ... (N times with N >= 0)
189 // Note that only this overload works with N = 0
190 template <class T, std::size_t N>
191 constexpr auto SingleTypeMultiplier (TypeArray<T, N>) {
192 return SingleTypeMultiplier_impl<T, N>();
193 }
194
195 // overload of SingleTypeMultiplier for one regular type
196 template <class T>
197 constexpr auto SingleTypeMultiplier (T) {
198 return TypeList<T>{};
199 }
200
201 // apply the types of the input TypeList as template arguments to TParam
202 template <template <class...> class TParam, class... Args>
203 constexpr auto TApply (TypeList<Args...>) {
204 return TypeList<TParam<Args...>>{};
205 }
206}
208
217template <template <class...> class TParam, class... Types>
219 (TypeList<>{} + ... + detail::SingleTypeMultiplier(std::declval<Types>()))
220))>;
221
222}
223
224#endif
Definition AMReX_Amr.cpp:49
typename detail::TypeListGet< I, T >::type TypeAt
Type at position I of a TypeList.
Definition AMReX_TypeList.H:34
__host__ __device__ GpuComplex< T > operator*(const GpuComplex< T > &a_x, const GpuComplex< U > &a_y) noexcept
Multiply two complex numbers.
Definition AMReX_GpuComplex.H:257
constexpr auto CartesianProduct(Ls...)
Cartesian Product of TypeLists.
Definition AMReX_TypeList.H:154
constexpr auto single_product(TypeList< Ls... >, A)
Definition AMReX_TypeList.H:132
constexpr void ForEach(TypeList< Ts... >, F &&f)
For each type t in TypeList, call f(t)
Definition AMReX_TypeList.H:82
constexpr bool ForEachUntil(TypeList< Ts... >, F &&f)
For each type t in TypeList, call f(t) until true is returned.
Definition AMReX_TypeList.H:119
TypeAt< 0, decltype(detail::TApply< TParam >((TypeList<>{}+...+detail::SingleTypeMultiplier(std::declval< 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:220
__host__ __device__ XDim3 operator+(XDim3 const &a, XDim3 const &b)
Definition AMReX_Dim3.H:28
Definition AMReX_TypeList.H:159
static constexpr std::size_t size() noexcept
Definition AMReX_TypeList.H:161
T Type
Definition AMReX_TypeList.H:160
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