Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_TypeTraits.H
Go to the documentation of this file.
1#ifndef BL_TYPETRAITS_H_
2#define BL_TYPETRAITS_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_Extension.H>
6#include <vector>
7#include <type_traits>
8
9// In case they are still used by applications
10#define AMREX_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable_v<T>
11#define AMREX_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T) std::is_trivially_default_constructible_v<T>
12
13namespace amrex
14{
15 template <class T> class BaseFab;
16 template <class FAB> class FabArray;
17
18 template <class A, class Enable = void> struct IsBaseFab : std::false_type {};
19 //
20 template <class D>
21 struct IsBaseFab<D, std::enable_if_t<
22 std::is_base_of_v<BaseFab<typename D::value_type>,
23 D>>>
24 : std::true_type {};
25 //
26 template <class A>
27 inline constexpr bool IsBaseFab_v = IsBaseFab<A>::value;
28
29 template <class A, class Enable = void> struct IsFabArray : std::false_type {};
30 //
31 template <class D>
32 struct IsFabArray<D, std::enable_if_t<
33 std::is_base_of_v<FabArray<typename D::FABType::value_type>,
34 D>>>
35 : std::true_type {};
36 //
37 template <class A>
38 inline constexpr bool IsFabArray_v = IsFabArray<A>::value;
39
40 template <class M, class Enable = void>
41 struct IsMultiFabLike : std::false_type {};
42 //
43 template <class M>
44 struct IsMultiFabLike<M, std::enable_if_t<IsFabArray_v<M> &&
45 IsBaseFab_v<typename M::fab_type> > >
46 : std::true_type {};
47 //
48 template <class M>
50
51
52 template <bool B, class T = void>
53 using EnableIf_t = std::enable_if_t<B,T>;
54
55 template <class T, class Enable = void>
56 struct HasAtomicAdd : std::false_type {};
57 template <> struct HasAtomicAdd<int> : std::true_type {};
58 template <> struct HasAtomicAdd<long> : std::true_type {};
59 template <> struct HasAtomicAdd<unsigned int> : std::true_type {};
60 template <> struct HasAtomicAdd<unsigned long long> : std::true_type {};
61 template <> struct HasAtomicAdd<float> : std::true_type {};
62 template <> struct HasAtomicAdd<double> : std::true_type {};
63
64 // support +=?
65 template <class T, class Enable = void>
66 struct IsAddAssignable : std::false_type {};
67 //
68 template <class T>
69 struct IsAddAssignable<T, std::void_t<decltype(std::declval<T&>() += std::declval<T>())>>
70 : std::true_type {};
71
72 class MFIter;
73 template <typename T>
74 struct IsMultiFabIterator : public std::is_base_of<MFIter, T>::type {};
75
76#ifdef AMREX_PARTICLES
77 // template <bool is_const, int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
78 // template<class> class Allocator>
79 // class ParIterBase;
80
81 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
82 // template<class> class Allocator>
83 // class ParIter;
84
85 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
86 // template<class> class Allocator>
87 // class ParConstIter;
88
90
91 template <typename T>
92 struct IsParticleIterator : public std::is_base_of<MFIter, T>::type {}; // not exactly right
93
94 template <typename T>
95 struct IsParticleContainer : public std::is_base_of<ParticleContainerBase, T>::type {};
96#endif
97
98 template <class T, class Enable = void>
99 struct DefinitelyNotHostRunnable : std::false_type {};
100
101#ifdef AMREX_USE_GPU
102
103 template <class T, class Enable = void>
104 struct MaybeDeviceRunnable : std::true_type {};
105
106 template <class T, class Enable = void>
107 struct MaybeHostDeviceRunnable : std::true_type {};
108
109#if defined(AMREX_USE_CUDA) && defined(__NVCC__)
110
111 template <class T>
112 struct MaybeHostDeviceRunnable<T, std::enable_if_t<__nv_is_extended_device_lambda_closure_type(T)> >
113 : std::false_type {};
114
115 template <class T>
116 struct DefinitelyNotHostRunnable<T, std::enable_if_t<__nv_is_extended_device_lambda_closure_type(T)> >
117 : std::true_type {};
118
119#elif defined(AMREX_USE_HIP)
120
121 // xxxxx HIP todo
122
123#endif
124
125#endif
126
127 template <typename T, typename U1, typename... Us>
128 struct Same;
129
130 template <typename T, typename U>
131 struct Same<T,U>
132 {
133 static constexpr bool value = std::is_same_v<T,U>;
134 };
135
136 template <typename T, typename U1, typename... Us>
137 struct Same
138 {
139 static constexpr bool value = std::is_same_v<T,U1> && Same<T,Us...>::value;
140 };
141
143 // [traits.IsDetected]
144 //
145 // We use IsDetected as a SFINAE tool to test for valid expressions.
146 //
147 // is_detected was proposed to C++ but is surpassed by concepts.
148 //
149 // The implementation is taken from
150 //
151 // https://en.cppreference.com/w/cpp/experimental/is_detected
152
154 namespace detail {
155 template <class...> using Void_t = void;
156
157 struct Nonesuch {
158 Nonesuch() = delete;
159 ~Nonesuch() = delete;
160 Nonesuch(Nonesuch const&) = delete;
161 Nonesuch(Nonesuch &&) = delete;
162 void operator=(Nonesuch const&) = delete;
163 void operator=(Nonesuch &&) = delete;
164 };
165
166 template <class Default, class AlwaysVoid, template <class...> class Op,
167 class... Args>
168 struct Detector {
169 using value_t = std::false_type;
170 using type = Default;
171 };
172
173 template <class Default, template <class...> class Op, class... Args>
174 struct Detector<Default, Void_t<Op<Args...>>, Op, Args...> {
175 using value_t = std::true_type;
176 using type = Op<Args...>;
177 };
178 }
180
181 template <template <class...> class Op, class... Args>
182 using IsDetected = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::value_t;
183
184 template <template <class...> class Op, class... Args>
185 using Detected_t = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::type;
186
187 template <class Default, template <class...> class Op, class... Args>
188 using DetectedOr = typename detail::Detector<Default, void, Op, Args...>::type;
189
190 template <class Expected, template <typename...> class Op, class... Args>
191 using IsDetectedExact = std::is_same<Expected, Detected_t<Op, Args...>>;
192
194 // [traits.IsCallable]
195
197 namespace detail {
198 template <typename T, typename... Args>
199 using call_result_t = decltype(std::declval<T>()(std::declval<Args>()...));
200 }
202
212 template <typename T, typename... Args>
213 struct IsCallable : IsDetected<detail::call_result_t, T, Args...> {};
214
218 template <typename R, typename T, typename... Args>
219 struct IsCallableR : IsDetectedExact<R, detail::call_result_t, T, Args...> {};
220
222 // [traits.Conjunction]
223 // [traits.Disjunction]
224 // [traits.Negation]
225
226
228#if defined(__cpp_lib_logical_traits)
229 template <typename... Args> using Conjunction = std::conjunction<Args...>;
230 template <typename... Args> using Disjunction = std::disjunction<Args...>;
231 template <typename... Args> using Negation = std::negation<Args...>;
232#elif defined(__cpp_lib_experimental_logical_traits)
233 template <typename... Args> using Conjunction = std::experimental::conjunction<Args...>;
234 template <typename... Args> using Disjunction = std::experimental::disjunction<Args...>;
235 template <typename... Args> using Negation = std::experimental::negation<Args...>;
236#else
237 template <class...> struct Conjunction : std::true_type {};
238 template <class B1> struct Conjunction<B1> : B1 {};
239 template <class B1, class... Bn>
240 struct Conjunction<B1, Bn...>
241 : std::conditional_t<bool(B1::value), Conjunction<Bn...>, B1> {};
242
243 template <class...> struct Disjunction : std::false_type {};
244 template <class B1> struct Disjunction<B1> : B1 {};
245 template <class B1, class... Bn>
246 struct Disjunction<B1, Bn...>
247 : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};
248
249 template <class B>
250 using Negation = std::integral_constant<bool, !bool(B::value)>;
251#endif
252
254 // [traits.IsConvertible]
255
257 namespace detail {
258 template<typename T>
259 inline constexpr bool is_convertible(T) {return true;}
260
261 template <typename T, typename U, typename Enable = void>
262 struct IsConvertibleImp : std::false_type {};
263
264 template <typename T, typename U>
265 struct IsConvertibleImp<T, U, std::enable_if_t<is_convertible<T>(U{})>> : std::true_type {};
266 }
268
270 template <typename T, typename... Args>
272 static constexpr bool value = (... && detail::IsConvertibleImp<T, Args>::value);
273 };
274
275 template <typename T, typename... Args>
276 inline constexpr bool IsConvertible_v = IsConvertible<T, Args...>::value;
277
278 // Move this down, because doxygen can not parse anything below IsStoreAtomic
279 template <class T, class Enable = void>
280 struct IsStoreAtomic : std::false_type {};
281 //
282 template <class T>
283 struct IsStoreAtomic<T, std::enable_if_t <
284 std::is_arithmetic_v<T>
285 && sizeof(T) <= 8 > >
286 : std::true_type {};
287
288 template <class T, class Enable = void>
289 struct IsStdVector : std::false_type {};
290 //
291 template <class T>
292 struct IsStdVector<T, std::enable_if_t<std::is_base_of_v<std::vector<typename T::value_type,
293 typename T::allocator_type>,
294 T>> >
295 : std::true_type {};
296
297}
298
299#endif
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:63
Definition AMReX_ParticleContainerBase.H:23
Definition AMReX_Amr.cpp:49
constexpr bool IsFabArray_v
Definition AMReX_TypeTraits.H:38
std::integral_constant< bool, !bool(B::value)> Negation
Definition AMReX_TypeTraits.H:250
constexpr bool IsMultiFabLike_v
Definition AMReX_TypeTraits.H:49
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::type Detected_t
Definition AMReX_TypeTraits.H:185
constexpr bool IsConvertible_v
Definition AMReX_TypeTraits.H:276
constexpr bool IsBaseFab_v
Definition AMReX_TypeTraits.H:27
typename detail::Detector< Default, void, Op, Args... >::type DetectedOr
Definition AMReX_TypeTraits.H:188
std::enable_if_t< B, T > EnableIf_t
Definition AMReX_TypeTraits.H:53
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::value_t IsDetected
Definition AMReX_TypeTraits.H:182
std::is_same< Expected, Detected_t< Op, Args... > > IsDetectedExact
Definition AMReX_TypeTraits.H:191
Logical traits let us combine multiple type requirements in one enable_if_t clause.
Definition AMReX_TypeTraits.H:237
Definition AMReX_TypeTraits.H:99
Definition AMReX_TypeTraits.H:243
Definition AMReX_TypeTraits.H:56
Definition AMReX_TypeTraits.H:66
Definition AMReX_TypeTraits.H:18
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:219
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:213
Test if all the types Args... are automatically convertible to type T.
Definition AMReX_TypeTraits.H:271
static constexpr bool value
Definition AMReX_TypeTraits.H:272
Definition AMReX_TypeTraits.H:29
Definition AMReX_TypeTraits.H:74
Definition AMReX_TypeTraits.H:41
Definition AMReX_TypeTraits.H:95
Definition AMReX_TypeTraits.H:92
Definition AMReX_TypeTraits.H:280
Definition AMReX_TypeTraits.H:104
Definition AMReX_TypeTraits.H:107
Definition AMReX_TypeTraits.H:138
static constexpr bool value
Definition AMReX_TypeTraits.H:139