Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 class MFIter;
65 template <typename T>
66 struct IsMultiFabIterator : public std::is_base_of<MFIter, T>::type {};
67
68#ifdef AMREX_PARTICLES
69 // template <bool is_const, int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
70 // template<class> class Allocator>
71 // class ParIterBase;
72
73 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
74 // template<class> class Allocator>
75 // class ParIter;
76
77 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
78 // template<class> class Allocator>
79 // class ParConstIter;
80
82
83 template <typename T>
84 struct IsParticleIterator : public std::is_base_of<MFIter, T>::type {}; // not exactly right
85
86 template <typename T>
87 struct IsParticleContainer : public std::is_base_of<ParticleContainerBase, T>::type {};
88#endif
89
90#ifdef AMREX_USE_GPU
91
92 template <class T, class Enable = void>
93 struct MaybeDeviceRunnable : std::true_type {};
94
95 template <class T, class Enable = void>
96 struct MaybeHostDeviceRunnable : std::true_type {};
97
98 template <class T, class Enable = void>
99 struct DefinitelyNotHostRunnable : std::false_type {};
100
101#if defined(AMREX_USE_CUDA) && defined(__NVCC__)
102
103 template <class T>
104 struct MaybeHostDeviceRunnable<T, std::enable_if_t<__nv_is_extended_device_lambda_closure_type(T)> >
105 : std::false_type {};
106
107 template <class T>
108 struct DefinitelyNotHostRunnable<T, std::enable_if_t<__nv_is_extended_device_lambda_closure_type(T)> >
109 : std::true_type {};
110
111#elif defined(AMREX_USE_HIP)
112
113 // xxxxx HIP todo
114
115#endif
116
117#endif
118
119 template <typename T, typename U1, typename... Us>
120 struct Same;
121
122 template <typename T, typename U>
123 struct Same<T,U>
124 {
125 static constexpr bool value = std::is_same_v<T,U>;
126 };
127
128 template <typename T, typename U1, typename... Us>
129 struct Same
130 {
131 static constexpr bool value = std::is_same_v<T,U1> && Same<T,Us...>::value;
132 };
133
135 // [traits.IsDetected]
136 //
137 // We use IsDetected as a SFINAE tool to test for valid expressions.
138 //
139 // is_detected was proposed to C++ but is surpassed by concepts.
140 //
141 // The implementation is taken from
142 //
143 // https://en.cppreference.com/w/cpp/experimental/is_detected
144
145 namespace detail {
146 template <class...> using Void_t = void;
147
148 struct Nonesuch {
149 Nonesuch() = delete;
150 ~Nonesuch() = delete;
151 Nonesuch(Nonesuch const&) = delete;
152 Nonesuch(Nonesuch &&) = delete;
153 void operator=(Nonesuch const&) = delete;
154 void operator=(Nonesuch &&) = delete;
155 };
156
157 template <class Default, class AlwaysVoid, template <class...> class Op,
158 class... Args>
159 struct Detector {
160 using value_t = std::false_type;
161 using type = Default;
162 };
163
164 template <class Default, template <class...> class Op, class... Args>
165 struct Detector<Default, Void_t<Op<Args...>>, Op, Args...> {
166 using value_t = std::true_type;
167 using type = Op<Args...>;
168 };
169 }
170
171 template <template <class...> class Op, class... Args>
172 using IsDetected = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::value_t;
173
174 template <template <class...> class Op, class... Args>
175 using Detected_t = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::type;
176
177 template <class Default, template <class...> class Op, class... Args>
178 using DetectedOr = typename detail::Detector<Default, void, Op, Args...>::type;
179
180 template <class Expected, template <typename...> class Op, class... Args>
181 using IsDetectedExact = std::is_same<Expected, Detected_t<Op, Args...>>;
182
184 // [traits.IsCallable]
185
186 namespace detail {
187 template <typename T, typename... Args>
188 using call_result_t = decltype(std::declval<T>()(std::declval<Args>()...));
189 }
190
200 template <typename T, typename... Args>
201 struct IsCallable : IsDetected<detail::call_result_t, T, Args...> {};
202
206 template <typename R, typename T, typename... Args>
207 struct IsCallableR : IsDetectedExact<R, detail::call_result_t, T, Args...> {};
208
210 // [traits.Conjunction]
211 // [traits.Disjunction]
212 // [traits.Negation]
213
214
216#if defined(__cpp_lib_logical_traits)
217 template <typename... Args> using Conjunction = std::conjunction<Args...>;
218 template <typename... Args> using Disjunction = std::disjunction<Args...>;
219 template <typename... Args> using Negation = std::negation<Args...>;
220#elif defined(__cpp_lib_experimental_logical_traits)
221 template <typename... Args> using Conjunction = std::experimental::conjunction<Args...>;
222 template <typename... Args> using Disjunction = std::experimental::disjunction<Args...>;
223 template <typename... Args> using Negation = std::experimental::negation<Args...>;
224#else
225 template <class...> struct Conjunction : std::true_type {};
226 template <class B1> struct Conjunction<B1> : B1 {};
227 template <class B1, class... Bn>
228 struct Conjunction<B1, Bn...>
229 : std::conditional_t<bool(B1::value), Conjunction<Bn...>, B1> {};
230
231 template <class...> struct Disjunction : std::false_type {};
232 template <class B1> struct Disjunction<B1> : B1 {};
233 template <class B1, class... Bn>
234 struct Disjunction<B1, Bn...>
235 : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};
236
237 template <class B>
238 using Negation = std::integral_constant<bool, !bool(B::value)>;
239#endif
240
242 // [traits.IsConvertible]
243
244 namespace detail {
245 template<typename T>
246 inline constexpr bool is_convertible(T) {return true;}
247
248 template <typename T, typename U, typename Enable = void>
249 struct IsConvertibleImp : std::false_type {};
250
251 template <typename T, typename U>
252 struct IsConvertibleImp<T, U, std::enable_if_t<is_convertible<T>(U{})>> : std::true_type {};
253 }
254
256 template <typename T, typename... Args>
258 static constexpr bool value = (... && detail::IsConvertibleImp<T, Args>::value);
259 };
260
261 template <typename T, typename... Args>
262 inline constexpr bool IsConvertible_v = IsConvertible<T, Args...>::value;
263
264 // Move this down, because doxygen can not parse anything below IsStoreAtomic
265 template <class T, class Enable = void>
266 struct IsStoreAtomic : std::false_type {};
267 //
268 template <class T>
269 struct IsStoreAtomic<T, std::enable_if_t <
270 std::is_arithmetic_v<T>
271 && sizeof(T) <= 8 > >
272 : std::true_type {};
273
274 template <class T, class Enable = void>
275 struct IsStdVector : std::false_type {};
276 //
277 template <class T>
278 struct IsStdVector<T, std::enable_if_t<std::is_base_of_v<std::vector<typename T::value_type,
279 typename T::allocator_type>,
280 T>> >
281 : std::true_type {};
282
283}
284
285#endif
Definition AMReX_MFIter.H:57
Definition AMReX_ParticleContainerBase.H:23
void Void_t
Definition AMReX_TypeTraits.H:146
constexpr bool is_convertible(T)
Definition AMReX_TypeTraits.H:246
decltype(std::declval< T >()(std::declval< Args >()...)) call_result_t
Definition AMReX_TypeTraits.H:188
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:238
constexpr bool IsMultiFabLike_v
Definition AMReX_TypeTraits.H:49
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::type Detected_t
Definition AMReX_TypeTraits.H:175
constexpr bool IsConvertible_v
Definition AMReX_TypeTraits.H:262
constexpr bool IsBaseFab_v
Definition AMReX_TypeTraits.H:27
typename detail::Detector< Default, void, Op, Args... >::type DetectedOr
Definition AMReX_TypeTraits.H:178
const int[]
Definition AMReX_BLProfiler.cpp:1664
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:172
std::is_same< Expected, Detected_t< Op, Args... > > IsDetectedExact
Definition AMReX_TypeTraits.H:181
Definition AMReX_FabArrayCommI.H:896
Logical traits let us combine multiple type requirements in one enable_if_t clause.
Definition AMReX_TypeTraits.H:225
Definition AMReX_TypeTraits.H:99
Definition AMReX_TypeTraits.H:231
Definition AMReX_TypeTraits.H:56
Definition AMReX_TypeTraits.H:18
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:207
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:201
Test if all the types Args... are automatically convertible to type T.
Definition AMReX_TypeTraits.H:257
static constexpr bool value
Definition AMReX_TypeTraits.H:258
Definition AMReX_TypeTraits.H:29
Definition AMReX_TypeTraits.H:66
Definition AMReX_TypeTraits.H:41
Definition AMReX_TypeTraits.H:266
Definition AMReX_TypeTraits.H:93
Definition AMReX_TypeTraits.H:96
Definition AMReX_TypeTraits.H:130
static constexpr bool value
Definition AMReX_TypeTraits.H:131
std::true_type value_t
Definition AMReX_TypeTraits.H:166
Definition AMReX_TypeTraits.H:159
std::false_type value_t
Definition AMReX_TypeTraits.H:160
Default type
Definition AMReX_TypeTraits.H:161
Definition AMReX_TypeTraits.H:249
Definition AMReX_TypeTraits.H:148
void operator=(Nonesuch &&)=delete
void operator=(Nonesuch const &)=delete
Nonesuch(Nonesuch const &)=delete
Nonesuch(Nonesuch &&)=delete