From a3b9bc2962eb7d0a8c1dfa9abe1297365360c37f Mon Sep 17 00:00:00 2001 From: AntoinePrv Date: Wed, 5 Aug 2026 19:29:14 +0200 Subject: [PATCH] Use C++17 type traits --- .../xsimd/arch/common/xsimd_common_math.hpp | 56 +++++++------------ include/xsimd/arch/xsimd_rvv.hpp | 2 +- include/xsimd/arch/xsimd_scalar.hpp | 18 +++--- include/xsimd/arch/xsimd_sve.hpp | 2 +- include/xsimd/arch/xsimd_vsx.hpp | 2 +- include/xsimd/arch/xsimd_vxe.hpp | 10 ++-- include/xsimd/types/xsimd_utils.hpp | 16 +----- 7 files changed, 41 insertions(+), 65 deletions(-) diff --git a/include/xsimd/arch/common/xsimd_common_math.hpp b/include/xsimd/arch/common/xsimd_common_math.hpp index 570a1da89..ad8a2741a 100644 --- a/include/xsimd/arch/common/xsimd_common_math.hpp +++ b/include/xsimd/arch/common/xsimd_common_math.hpp @@ -46,62 +46,46 @@ namespace xsimd } // avg - namespace detail + template + XSIMD_INLINE batch avg(batch const& x, batch const& y, requires_arch) noexcept { - template - XSIMD_INLINE batch avg(batch const& x, batch const& y, std::true_type, std::false_type) noexcept + if constexpr (std::is_integral_v) { - return (x & y) + ((x ^ y) >> 1); - } - - template - XSIMD_INLINE batch avg(batch const& x, batch const& y, std::true_type, std::true_type) noexcept - { - // Inspired by - // https://stackoverflow.com/questions/5697500/take-the-average-of-two-signed-numbers-in-c - auto t = (x & y) + ((x ^ y) >> 1); - auto t_u = bitwise_cast>(t); - auto avg = t + (bitwise_cast(t_u >> (8 * sizeof(T) - 1)) & (x ^ y)); - return avg; + if constexpr (std::is_signed_v) + { + // Inspired by + // https://stackoverflow.com/questions/5697500/take-the-average-of-two-signed-numbers-in-c + auto t = (x & y) + ((x ^ y) >> 1); + auto t_u = bitwise_cast>(t); + return t + (bitwise_cast(t_u >> (8 * sizeof(T) - 1)) & (x ^ y)); + } + else + { + return (x & y) + ((x ^ y) >> 1); + } } - - template - XSIMD_INLINE batch avg(batch const& x, batch const& y, std::false_type, std::true_type) noexcept + else { return (x + y) / 2; } } - template - XSIMD_INLINE batch avg(batch const& x, batch const& y, requires_arch) noexcept - { - return detail::avg(x, y, typename std::is_integral::type {}, typename std::is_signed::type {}); - } - // avgr - namespace detail + template + XSIMD_INLINE batch avgr(batch const& x, batch const& y, requires_arch) noexcept { - template - XSIMD_INLINE batch avgr(batch const& x, batch const& y, std::true_type) noexcept + if constexpr (std::is_integral_v) { constexpr unsigned shift = 8 * sizeof(T) - 1; auto adj = std::is_signed_v ? ((x ^ y) & 0x1) : (((x ^ y) << shift) >> shift); return ::xsimd::kernel::avg(x, y, A {}) + adj; } - - template - XSIMD_INLINE batch avgr(batch const& x, batch const& y, std::false_type) noexcept + else { return ::xsimd::kernel::avg(x, y, A {}); } } - template - XSIMD_INLINE batch avgr(batch const& x, batch const& y, requires_arch) noexcept - { - return detail::avgr(x, y, typename std::is_integral::type {}); - } - // batch_cast template XSIMD_INLINE batch batch_cast(batch const& self, batch const&, requires_arch) noexcept diff --git a/include/xsimd/arch/xsimd_rvv.hpp b/include/xsimd/arch/xsimd_rvv.hpp index 01304b1f5..270102cc7 100644 --- a/include/xsimd/arch/xsimd_rvv.hpp +++ b/include/xsimd/arch/xsimd_rvv.hpp @@ -687,7 +687,7 @@ namespace xsimd } // mul_hi - template , int>::type = 0> + template , int> = 0> XSIMD_INLINE batch mul_hi(batch const& lhs, batch const& rhs, requires_arch) noexcept { return detail_rvv::rvvmulh(lhs, rhs); diff --git a/include/xsimd/arch/xsimd_scalar.hpp b/include/xsimd/arch/xsimd_scalar.hpp index 4802cb4eb..4feb43fd3 100644 --- a/include/xsimd/arch/xsimd_scalar.hpp +++ b/include/xsimd/arch/xsimd_scalar.hpp @@ -1081,14 +1081,16 @@ namespace xsimd namespace detail { -#define XSIMD_HASSINCOS_TRAIT(func) \ - template \ - struct has##func \ - { \ - template \ - static XSIMD_INLINE auto get(T* ptr) -> decltype(func(std::declval(), std::declval(), std::declval()), std::true_type {}); \ - static XSIMD_INLINE std::false_type get(...); \ - static constexpr bool value = decltype(get((S*)nullptr))::value; \ +#define XSIMD_HASSINCOS_TRAIT(func) \ + template \ + struct has##func : std::false_type \ + { \ + }; \ + \ + template \ + struct has##func(), std::declval(), std::declval()))>> \ + : std::true_type \ + { \ } #define XSIMD_HASSINCOS(func, T) has##func::value diff --git a/include/xsimd/arch/xsimd_sve.hpp b/include/xsimd/arch/xsimd_sve.hpp index d47525c8e..dc36bcf00 100644 --- a/include/xsimd/arch/xsimd_sve.hpp +++ b/include/xsimd/arch/xsimd_sve.hpp @@ -313,7 +313,7 @@ namespace xsimd } // mul_hi - template , int>::type = 0> + template , int> = 0> XSIMD_INLINE batch mul_hi(batch const& lhs, batch const& rhs, requires_arch) noexcept { return svmulh_x(detail_sve::ptrue(), lhs, rhs); diff --git a/include/xsimd/arch/xsimd_vsx.hpp b/include/xsimd/arch/xsimd_vsx.hpp index 4fbeb600d..b2361b5ba 100644 --- a/include/xsimd/arch/xsimd_vsx.hpp +++ b/include/xsimd/arch/xsimd_vsx.hpp @@ -57,7 +57,7 @@ namespace xsimd template <> struct builtin_scalar { - using type = typename std::conditional, signed char, unsigned char>::type; + using type = std::conditional_t, signed char, unsigned char>; }; template diff --git a/include/xsimd/arch/xsimd_vxe.hpp b/include/xsimd/arch/xsimd_vxe.hpp index e0d342691..61e9bf8a5 100644 --- a/include/xsimd/arch/xsimd_vxe.hpp +++ b/include/xsimd/arch/xsimd_vxe.hpp @@ -60,7 +60,7 @@ namespace xsimd template <> struct builtin_scalar { - using type = typename std::conditional, signed char, unsigned char>::type; + using type = std::conditional_t, signed char, unsigned char>; }; template @@ -249,7 +249,7 @@ namespace xsimd } // abs - template , void>::type> + template , void>> XSIMD_INLINE batch abs(batch const& self, requires_arch) noexcept { return vec_abs(self.data); @@ -438,7 +438,7 @@ namespace xsimd v2di sum = (v2di)self.data + shifted; return (int64_t)sum[0]; } - template , void>::type> + template , void>> XSIMD_INLINE T reduce_add(batch const& self, requires_arch) noexcept { if constexpr (sizeof(T) == 4) @@ -735,13 +735,13 @@ namespace xsimd return vec_mergeh(self.data, other.data); } // bitwise_rshift - template , void>::type> + template , void>> XSIMD_INLINE batch bitwise_rshift(batch const& self, int32_t other, requires_arch) noexcept { return self.data >> other; } // bitwise_lshift - template , void>::type> + template , void>> XSIMD_INLINE batch bitwise_lshift(batch const& self, int32_t other, requires_arch) noexcept { return self.data << other; diff --git a/include/xsimd/types/xsimd_utils.hpp b/include/xsimd/types/xsimd_utils.hpp index 66fe6dc99..f339c5de7 100644 --- a/include/xsimd/types/xsimd_utils.hpp +++ b/include/xsimd/types/xsimd_utils.hpp @@ -329,24 +329,14 @@ namespace xsimd namespace detail { - template - struct bool_pack; - - template - using all_true = std::is_same< - bool_pack, bool_pack>; - template - using is_all_convertible = all_true...>; - - template - using is_array_initializer = std::enable_if< - (sizeof...(Args) == N) && is_all_convertible::value>; + inline constexpr bool is_all_convertible_v = std::conjunction_v...>; // Check that a variadic argument pack is a list of N values of type T, // as usable for instantiating a value of type std::array. template - using is_array_initializer_t = typename is_array_initializer::type; + using is_array_initializer_t = std::enable_if_t< + (sizeof...(Args) == N) && is_all_convertible_v>; } /**************