Skip to content

Commit a3e38c4

Browse files
kalenedraelserge-sans-paille
authored andcommitted
Add unified batch traits
`xsimd::batch_traits` with mask type, scalar type, and some properties for scalar, `batch`, and `batch_bool`.
1 parent abef801 commit a3e38c4

File tree

2 files changed

+96
-27
lines changed

2 files changed

+96
-27
lines changed

docs/source/api/type_traits.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,15 @@ Type Traits
3232
===========
3333

3434
`xsimd` provides a few type traits to interact with scalar and batch types in an
35-
uniformeous manner.
35+
uniform manner.
3636

3737

38+
Combined traits:
39+
40+
+---------------------------------------+----------------------------------------------------+
41+
| :cpp:class:`batch_traits` | batch types and proprties |
42+
+---------------------------------------+----------------------------------------------------+
43+
3844
Type check:
3945

4046
+---------------------------------------+----------------------------------------------------+

include/xsimd/types/xsimd_traits.hpp

Lines changed: 89 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -233,59 +233,133 @@ namespace xsimd
233233
/**
234234
* @ingroup batch_traits
235235
*
236-
* type traits that inherits from @c std::true_type for @c batch<...> types and from
237-
* @c std::false_type otherwise.
236+
* type traits that provide information about a batch or scalar type.
238237
*
239238
* @tparam T type to analyze.
240239
*/
240+
241241
template <class T>
242-
struct is_batch;
242+
struct batch_traits
243+
{
244+
using scalar_type = T; ///< T if scalar, or type of the scalar element for the batch T.
245+
using mask_type = bool; ///< Mask type for T: bool for scalars, or batch_bool for batch types.
243246

247+
static constexpr bool is_batch = false; ///< True if T is @c batch<...>.
248+
static constexpr bool is_batch_bool = false; ///< True if T is @c batch_bool<...>.
249+
static constexpr bool is_any_batch = false; ///< True if T is @c batch<...> or @c batch_bool<...>.
250+
static constexpr bool is_complex = detail::is_complex<T>::value; ///< True if T is complex or a batch of complex values.
251+
};
252+
253+
#if __cplusplus < 201703L
254+
template <class T>
255+
constexpr bool batch_traits<T>::is_batch;
244256
template <class T>
245-
struct is_batch : std::false_type
257+
constexpr bool batch_traits<T>::is_batch_bool;
258+
template <class T>
259+
constexpr bool batch_traits<T>::is_any_batch;
260+
template <class T>
261+
constexpr bool batch_traits<T>::is_complex;
262+
#endif
263+
264+
template <class T, class A>
265+
struct batch_traits<batch<T, A>>
246266
{
267+
using scalar_type = T;
268+
using mask_type = typename batch<T, A>::batch_bool_type;
269+
270+
static constexpr bool is_batch = true;
271+
static constexpr bool is_batch_bool = false;
272+
static constexpr bool is_any_batch = true;
273+
static constexpr bool is_complex = detail::is_complex<T>::value;
247274
};
248275

276+
#if __cplusplus < 201703L
277+
template <class T, class A>
278+
constexpr bool batch_traits<batch<T, A>>::is_batch;
279+
template <class T, class A>
280+
constexpr bool batch_traits<batch<T, A>>::is_batch_bool;
281+
template <class T, class A>
282+
constexpr bool batch_traits<batch<T, A>>::is_any_batch;
283+
template <class T, class A>
284+
constexpr bool batch_traits<batch<T, A>>::is_complex;
285+
#endif
286+
249287
template <class T, class A>
250-
struct is_batch<batch<T, A>> : std::true_type
288+
struct batch_traits<batch_bool<T, A>>
251289
{
290+
using scalar_type = bool;
291+
using mask_type = batch_bool<T, A>;
292+
293+
static constexpr bool is_batch = false;
294+
static constexpr bool is_batch_bool = true;
295+
static constexpr bool is_any_batch = true;
296+
static constexpr bool is_complex = false;
252297
};
253298

299+
#if __cplusplus < 201703L
300+
template <class T, class A>
301+
constexpr bool batch_traits<batch_bool<T, A>>::is_batch;
302+
template <class T, class A>
303+
constexpr bool batch_traits<batch_bool<T, A>>::is_batch_bool;
304+
template <class T, class A>
305+
constexpr bool batch_traits<batch_bool<T, A>>::is_any_batch;
306+
template <class T, class A>
307+
constexpr bool batch_traits<batch_bool<T, A>>::is_complex;
308+
#endif
309+
254310
/**
255311
* @ingroup batch_traits
256312
*
257-
* type traits that inherits from @c std::true_type for @c batch_bool<...> types and from
313+
* type traits that inherits from @c std::true_type for @c batch<...> types and from
258314
* @c std::false_type otherwise.
259315
*
260316
* @tparam T type to analyze.
261317
*/
262318

263319
template <class T>
264-
struct is_batch_bool : std::false_type
320+
struct is_batch : std::integral_constant<bool, batch_traits<T>::is_batch>
265321
{
266322
};
267323

268-
template <class T, class A>
269-
struct is_batch_bool<batch_bool<T, A>> : std::true_type
324+
/**
325+
* @ingroup batch_traits
326+
*
327+
* type traits that inherits from @c std::true_type for @c batch_bool<...> types and from
328+
* @c std::false_type otherwise.
329+
*
330+
* @tparam T type to analyze.
331+
*/
332+
333+
template <class T>
334+
struct is_batch_bool : std::integral_constant<bool, batch_traits<T>::is_batch_bool>
270335
{
271336
};
272337

273338
/**
274339
* @ingroup batch_traits
275340
*
276-
* type traits that inherits from @c std::true_type for @c batch<std::complex<...>>
341+
* type traits that inherits from @c std::true_type for @c batch<...> or batch_bool<...>
277342
* types and from @c std::false_type otherwise.
278343
*
279344
* @tparam T type to analyze.
280345
*/
281346

282347
template <class T>
283-
struct is_batch_complex : std::false_type
348+
struct is_any_batch : std::integral_constant<bool, batch_traits<T>::is_any_batch>
284349
{
285350
};
286351

287-
template <class T, class A>
288-
struct is_batch_complex<batch<std::complex<T>, A>> : std::true_type
352+
/**
353+
* @ingroup batch_traits
354+
*
355+
* type traits that inherits from @c std::true_type for @c batch<std::complex<...>>
356+
* types and from @c std::false_type otherwise.
357+
*
358+
* @tparam T type to analyze.
359+
*/
360+
361+
template <class T>
362+
struct is_batch_complex : std::integral_constant<bool, batch_traits<T>::is_batch && batch_traits<T>::is_complex>
289363
{
290364
};
291365

@@ -300,12 +374,7 @@ namespace xsimd
300374
template <class T>
301375
struct scalar_type
302376
{
303-
using type = T;
304-
};
305-
template <class T, class A>
306-
struct scalar_type<batch<T, A>>
307-
{
308-
using type = T;
377+
using type = typename batch_traits<T>::scalar_type;
309378
};
310379

311380
template <class T>
@@ -322,12 +391,7 @@ namespace xsimd
322391
template <class T>
323392
struct mask_type
324393
{
325-
using type = bool;
326-
};
327-
template <class T, class A>
328-
struct mask_type<batch<T, A>>
329-
{
330-
using type = typename batch<T, A>::batch_bool_type;
394+
using type = typename batch_traits<T>::mask_type;
331395
};
332396

333397
template <class T>
@@ -364,7 +428,6 @@ namespace xsimd
364428
}
365429
template <typename T>
366430
using widen_t = typename detail::widen<T>::type;
367-
368431
}
369432

370433
#endif

0 commit comments

Comments
 (0)