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
153 namespace detail {
154 template <class...> using Void_t = void;
155
156 struct Nonesuch {
157 Nonesuch() = delete;
158 ~Nonesuch() = delete;
159 Nonesuch(Nonesuch const&) = delete;
160 Nonesuch(Nonesuch &&) = delete;
161 void operator=(Nonesuch const&) = delete;
162 void operator=(Nonesuch &&) = delete;
163 };
164
165 template <class Default, class AlwaysVoid, template <class...> class Op,
166 class... Args>
167 struct Detector {
168 using value_t = std::false_type;
169 using type = Default;
170 };
171
172 template <class Default, template <class...> class Op, class... Args>
173 struct Detector<Default, Void_t<Op<Args...>>, Op, Args...> {
174 using value_t = std::true_type;
175 using type = Op<Args...>;
176 };
177 }
178
179 template <template <class...> class Op, class... Args>
180 using IsDetected = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::value_t;
181
182 template <template <class...> class Op, class... Args>
183 using Detected_t = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::type;
184
185 template <class Default, template <class...> class Op, class... Args>
186 using DetectedOr = typename detail::Detector<Default, void, Op, Args...>::type;
187
188 template <class Expected, template <typename...> class Op, class... Args>
189 using IsDetectedExact = std::is_same<Expected, Detected_t<Op, Args...>>;
190
192 // [traits.IsCallable]
193
194 namespace detail {
195 template <typename T, typename... Args>
196 using call_result_t = decltype(std::declval<T>()(std::declval<Args>()...));
197 }
198
208 template <typename T, typename... Args>
209 struct IsCallable : IsDetected<detail::call_result_t, T, Args...> {};
210
214 template <typename R, typename T, typename... Args>
215 struct IsCallableR : IsDetectedExact<R, detail::call_result_t, T, Args...> {};
216
218 // [traits.Conjunction]
219 // [traits.Disjunction]
220 // [traits.Negation]
221
222
224#if defined(__cpp_lib_logical_traits)
225 template <typename... Args> using Conjunction = std::conjunction<Args...>;
226 template <typename... Args> using Disjunction = std::disjunction<Args...>;
227 template <typename... Args> using Negation = std::negation<Args...>;
228#elif defined(__cpp_lib_experimental_logical_traits)
229 template <typename... Args> using Conjunction = std::experimental::conjunction<Args...>;
230 template <typename... Args> using Disjunction = std::experimental::disjunction<Args...>;
231 template <typename... Args> using Negation = std::experimental::negation<Args...>;
232#else
233 template <class...> struct Conjunction : std::true_type {};
234 template <class B1> struct Conjunction<B1> : B1 {};
235 template <class B1, class... Bn>
236 struct Conjunction<B1, Bn...>
237 : std::conditional_t<bool(B1::value), Conjunction<Bn...>, B1> {};
238
239 template <class...> struct Disjunction : std::false_type {};
240 template <class B1> struct Disjunction<B1> : B1 {};
241 template <class B1, class... Bn>
242 struct Disjunction<B1, Bn...>
243 : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};
244
245 template <class B>
246 using Negation = std::integral_constant<bool, !bool(B::value)>;
247#endif
248
250 // [traits.IsConvertible]
251
252 namespace detail {
253 template<typename T>
254 inline constexpr bool is_convertible(T) {return true;}
255
256 template <typename T, typename U, typename Enable = void>
257 struct IsConvertibleImp : std::false_type {};
258
259 template <typename T, typename U>
260 struct IsConvertibleImp<T, U, std::enable_if_t<is_convertible<T>(U{})>> : std::true_type {};
261 }
262
264 template <typename T, typename... Args>
266 static constexpr bool value = (... && detail::IsConvertibleImp<T, Args>::value);
267 };
268
269 template <typename T, typename... Args>
270 inline constexpr bool IsConvertible_v = IsConvertible<T, Args...>::value;
271
272 // Move this down, because doxygen can not parse anything below IsStoreAtomic
273 template <class T, class Enable = void>
274 struct IsStoreAtomic : std::false_type {};
275 //
276 template <class T>
277 struct IsStoreAtomic<T, std::enable_if_t <
278 std::is_arithmetic_v<T>
279 && sizeof(T) <= 8 > >
280 : std::true_type {};
281
282 template <class T, class Enable = void>
283 struct IsStdVector : std::false_type {};
284 //
285 template <class T>
286 struct IsStdVector<T, std::enable_if_t<std::is_base_of_v<std::vector<typename T::value_type,
287 typename T::allocator_type>,
288 T>> >
289 : std::true_type {};
290
291}
292
293#endif
Definition AMReX_MFIter.H:57
Definition AMReX_ParticleContainerBase.H:23
void Void_t
Definition AMReX_TypeTraits.H:154
constexpr bool is_convertible(T)
Definition AMReX_TypeTraits.H:254
decltype(std::declval< T >()(std::declval< Args >()...)) call_result_t
Definition AMReX_TypeTraits.H:196
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:246
constexpr bool IsMultiFabLike_v
Definition AMReX_TypeTraits.H:49
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::type Detected_t
Definition AMReX_TypeTraits.H:183
constexpr bool IsConvertible_v
Definition AMReX_TypeTraits.H:270
constexpr bool IsBaseFab_v
Definition AMReX_TypeTraits.H:27
typename detail::Detector< Default, void, Op, Args... >::type DetectedOr
Definition AMReX_TypeTraits.H:186
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:180
std::is_same< Expected, Detected_t< Op, Args... > > IsDetectedExact
Definition AMReX_TypeTraits.H:189
Definition AMReX_FabArrayCommI.H:1000
Logical traits let us combine multiple type requirements in one enable_if_t clause.
Definition AMReX_TypeTraits.H:233
Definition AMReX_TypeTraits.H:99
Definition AMReX_TypeTraits.H:239
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:215
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:209
Test if all the types Args... are automatically convertible to type T.
Definition AMReX_TypeTraits.H:265
static constexpr bool value
Definition AMReX_TypeTraits.H:266
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:274
Definition AMReX_TypeTraits.H:104
Definition AMReX_TypeTraits.H:107
Definition AMReX_TypeTraits.H:138
static constexpr bool value
Definition AMReX_TypeTraits.H:139
std::true_type value_t
Definition AMReX_TypeTraits.H:174
Definition AMReX_TypeTraits.H:167
std::false_type value_t
Definition AMReX_TypeTraits.H:168
Default type
Definition AMReX_TypeTraits.H:169
Definition AMReX_TypeTraits.H:257
Definition AMReX_TypeTraits.H:156
void operator=(Nonesuch &&)=delete
void operator=(Nonesuch const &)=delete
Nonesuch(Nonesuch const &)=delete
Nonesuch(Nonesuch &&)=delete