@@ -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