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> struct IsBaseFab : std::false_type {};
19 //
20 template <class D>
21 requires (std::is_base_of_v<BaseFab<typename D::value_type>, D>)
22 struct IsBaseFab<D> : std::true_type {};
23 //
24 template <class A>
25 inline constexpr bool IsBaseFab_v = IsBaseFab<A>::value;
26
27 template <class A> struct IsFabArray : std::false_type {};
28 //
29 template <class D>
30 requires (std::is_base_of_v<FabArray<typename D::FABType::value_type>, D>)
31 struct IsFabArray<D> : std::true_type {};
32 //
33 template <class A>
34 inline constexpr bool IsFabArray_v = IsFabArray<A>::value;
35
36 template <class M>
37 struct IsMultiFabLike : std::false_type {};
38 //
39 template <class M>
40 requires (IsFabArray_v<M> && IsBaseFab_v<typename M::fab_type>)
41 struct IsMultiFabLike<M> : std::true_type {};
42 //
43 template <class M>
45
46
47 template <bool B, class T = void>
48 using EnableIf_t = std::enable_if_t<B,T>;
49
50 template <class T, class Enable = void>
51 struct HasAtomicAdd : std::false_type {};
52 template <> struct HasAtomicAdd<int> : std::true_type {};
53 template <> struct HasAtomicAdd<long> : std::true_type {};
54 template <> struct HasAtomicAdd<unsigned int> : std::true_type {};
55 template <> struct HasAtomicAdd<unsigned long long> : std::true_type {};
56 template <> struct HasAtomicAdd<float> : std::true_type {};
57 template <> struct HasAtomicAdd<double> : std::true_type {};
58
59 // support +=?
60 template <class T, class Enable = void>
61 struct IsAddAssignable : std::false_type {};
62 //
63 template <class T>
64 struct IsAddAssignable<T, std::void_t<decltype(std::declval<T&>() += std::declval<T>())>>
65 : std::true_type {};
66
67 class MFIter;
68 template <typename T>
69 struct IsMultiFabIterator : public std::is_base_of<MFIter, T>::type {};
70
71#ifdef AMREX_PARTICLES
72 // template <bool is_const, int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
73 // template<class> class Allocator>
74 // class ParIterBase;
75
76 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
77 // template<class> class Allocator>
78 // class ParIter;
79
80 // template <int NStructReal, int NStructInt, int NArrayReal, int NArrayInt,
81 // template<class> class Allocator>
82 // class ParConstIter;
83
85
86 template <typename T>
87 struct IsParticleIterator : public std::is_base_of<MFIter, T>::type {}; // not exactly right
88
89 template <typename T>
90 struct IsParticleContainer : public std::is_base_of<ParticleContainerBase, T>::type {};
91#endif
92
93 template <class T>
94 struct DefinitelyNotHostRunnable : std::false_type {};
95
96#ifdef AMREX_USE_GPU
97
98 template <class T>
99 struct MaybeDeviceRunnable : std::true_type {};
100
101 template <class T>
102 struct MaybeHostDeviceRunnable : std::true_type {};
103
104#if defined(AMREX_USE_CUDA) && defined(__NVCC__)
105
106 template <class T>
107 requires (__nv_is_extended_device_lambda_closure_type(T))
108 struct MaybeHostDeviceRunnable<T> : std::false_type {};
109
110 template <class T>
111 requires (__nv_is_extended_device_lambda_closure_type(T))
112 struct DefinitelyNotHostRunnable<T> : std::true_type {};
113
114#elif defined(AMREX_USE_HIP)
115
116 // xxxxx HIP todo
117
118#endif
119
120#endif
121
122 template <typename T, typename U1, typename... Us>
123 struct Same;
124
125 template <typename T, typename U>
126 struct Same<T,U>
127 {
128 static constexpr bool value = std::is_same_v<T,U>;
129 };
130
131 template <typename T, typename U1, typename... Us>
132 struct Same
133 {
134 static constexpr bool value = std::is_same_v<T,U1> && Same<T,Us...>::value;
135 };
136
138 // [traits.IsDetected]
139 //
140 // We use IsDetected as a SFINAE tool to test for valid expressions.
141 //
142 // is_detected was proposed to C++ but is surpassed by concepts.
143 //
144 // The implementation is taken from
145 //
146 // https://en.cppreference.com/w/cpp/experimental/is_detected
147
149 namespace detail {
150 template <class...> using Void_t = void;
151
152 struct Nonesuch {
153 Nonesuch() = delete;
154 ~Nonesuch() = delete;
155 Nonesuch(Nonesuch const&) = delete;
156 Nonesuch(Nonesuch &&) = delete;
157 void operator=(Nonesuch const&) = delete;
158 void operator=(Nonesuch &&) = delete;
159 };
160
161 template <class Default, class AlwaysVoid, template <class...> class Op,
162 class... Args>
163 struct Detector {
164 using value_t = std::false_type;
165 using type = Default;
166 };
167
168 template <class Default, template <class...> class Op, class... Args>
169 struct Detector<Default, Void_t<Op<Args...>>, Op, Args...> {
170 using value_t = std::true_type;
171 using type = Op<Args...>;
172 };
173 }
175
176 template <template <class...> class Op, class... Args>
177 using IsDetected = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::value_t;
178
179 template <template <class...> class Op, class... Args>
180 using Detected_t = typename detail::Detector<detail::Nonesuch, void, Op, Args...>::type;
181
182 template <class Default, template <class...> class Op, class... Args>
183 using DetectedOr = typename detail::Detector<Default, void, Op, Args...>::type;
184
185 template <class Expected, template <typename...> class Op, class... Args>
186 using IsDetectedExact = std::is_same<Expected, Detected_t<Op, Args...>>;
187
189 // [traits.IsCallable]
190
192 namespace detail {
193 template <typename T, typename... Args>
194 using call_result_t = decltype(std::declval<T>()(std::declval<Args>()...));
195 }
197
207 template <typename T, typename... Args>
208 struct IsCallable : IsDetected<detail::call_result_t, T, Args...> {};
209
213 template <typename R, typename T, typename... Args>
214 struct IsCallableR : IsDetectedExact<R, detail::call_result_t, T, Args...> {};
215
217 // [traits.Conjunction]
218 // [traits.Disjunction]
219 // [traits.Negation]
220
221
223#if defined(__cpp_lib_logical_traits)
224 template <typename... Args> using Conjunction = std::conjunction<Args...>;
225 template <typename... Args> using Disjunction = std::disjunction<Args...>;
226 template <typename... Args> using Negation = std::negation<Args...>;
227#elif defined(__cpp_lib_experimental_logical_traits)
228 template <typename... Args> using Conjunction = std::experimental::conjunction<Args...>;
229 template <typename... Args> using Disjunction = std::experimental::disjunction<Args...>;
230 template <typename... Args> using Negation = std::experimental::negation<Args...>;
231#else
232 template <class...> struct Conjunction : std::true_type {};
233 template <class B1> struct Conjunction<B1> : B1 {};
234 template <class B1, class... Bn>
235 struct Conjunction<B1, Bn...>
236 : std::conditional_t<bool(B1::value), Conjunction<Bn...>, B1> {};
237
238 template <class...> struct Disjunction : std::false_type {};
239 template <class B1> struct Disjunction<B1> : B1 {};
240 template <class B1, class... Bn>
241 struct Disjunction<B1, Bn...>
242 : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {};
243
244 template <class B>
245 using Negation = std::integral_constant<bool, !bool(B::value)>;
246#endif
247
249 // [traits.IsConvertible]
250
252 template <typename T, typename... Args>
253 using IsConvertible = std::conjunction<std::is_convertible<Args, T>...>;
254
255 template <typename T, typename... Args>
256 inline constexpr bool IsConvertible_v = IsConvertible<T, Args...>::value; // NOLINT(modernize-type-traits)
257
258 namespace detail {
259 template <typename T, typename U, typename Enable = void>
260 struct IsNarrowingConversionImp : std::true_type {};
261
262 template <typename T, typename U>
263 struct IsNarrowingConversionImp<T, U, std::void_t<decltype(U{std::declval<T>()})>> : std::false_type {};
264 }
265
266 template <typename From, typename To>
267 struct IsNarrowingConversion : detail::IsNarrowingConversionImp<From, To> {};
268
269 template <typename From, typename To>
271
272 template <typename From, typename To>
274
275 // Move this down, because doxygen can not parse anything below IsStoreAtomic
276 template <class T>
277 struct IsStoreAtomic : std::false_type {};
278 //
279 template <class T>
280 requires (std::is_arithmetic_v<T> && sizeof(T) <= 8)
281 struct IsStoreAtomic<T> : std::true_type {};
282}
283
284#endif
Iterator for looping ever tiles and boxes of amrex::FabArray based containers.
Definition AMReX_MFIter.H:88
Definition AMReX_ParticleContainerBase.H:43
Definition AMReX_Amr.cpp:50
constexpr bool IsNarrowingConversion_v
Definition AMReX_TypeTraits.H:270
constexpr bool IsFabArray_v
Definition AMReX_TypeTraits.H:34
std::integral_constant< bool, !bool(B::value)> Negation
Definition AMReX_TypeTraits.H:245
constexpr bool IsMultiFabLike_v
Definition AMReX_TypeTraits.H:44
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::type Detected_t
Definition AMReX_TypeTraits.H:180
std::conjunction< std::is_convertible< Args, T >... > IsConvertible
Test if all the types Args... are automatically convertible to type T.
Definition AMReX_TypeTraits.H:253
constexpr bool IsNonNarrowingConversion_v
Definition AMReX_TypeTraits.H:273
constexpr bool IsConvertible_v
Definition AMReX_TypeTraits.H:256
constexpr bool IsBaseFab_v
Definition AMReX_TypeTraits.H:25
typename detail::Detector< Default, void, Op, Args... >::type DetectedOr
Definition AMReX_TypeTraits.H:183
const int[]
Definition AMReX_BLProfiler.cpp:1664
std::enable_if_t< B, T > EnableIf_t
Definition AMReX_TypeTraits.H:48
typename detail::Detector< detail::Nonesuch, void, Op, Args... >::value_t IsDetected
Definition AMReX_TypeTraits.H:177
std::is_same< Expected, Detected_t< Op, Args... > > IsDetectedExact
Definition AMReX_TypeTraits.H:186
Logical traits let us combine multiple type requirements.
Definition AMReX_TypeTraits.H:232
Definition AMReX_TypeTraits.H:94
Definition AMReX_TypeTraits.H:238
Definition AMReX_TypeTraits.H:51
Definition AMReX_TypeTraits.H:61
Definition AMReX_TypeTraits.H:18
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:214
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:208
Definition AMReX_TypeTraits.H:27
Definition AMReX_TypeTraits.H:69
Definition AMReX_TypeTraits.H:37
Definition AMReX_TypeTraits.H:267
Definition AMReX_TypeTraits.H:90
Definition AMReX_TypeTraits.H:87
Definition AMReX_TypeTraits.H:277
Definition AMReX_TypeTraits.H:99
Definition AMReX_TypeTraits.H:102
Definition AMReX_TypeTraits.H:133
static constexpr bool value
Definition AMReX_TypeTraits.H:134