Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 12 additions & 14 deletions include/xsimd/arch/xsimd_avx512f.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,7 @@ namespace xsimd
using register_type = typename batch_bool<T, A>::register_type;
register_type r = 0;
unsigned shift = 0;
(void)std::initializer_list<register_type> { (r |= register_type(values ? 1 : 0) << (shift++))... };
((r |= register_type(values ? 1 : 0) << (shift++)), ...);
return r;
}

Expand Down Expand Up @@ -2656,21 +2656,19 @@ namespace xsimd

namespace detail
{
template <class T, class A, T... Idx>
struct is_pair_of_contiguous_indices;

template <class T, class A>
struct is_pair_of_contiguous_indices<T, A> : std::true_type
template <class T, T... Idx, std::size_t... Is>
constexpr bool is_pair_of_contiguous_indices_impl(std::index_sequence<Is...>) noexcept
{
};
constexpr T idx[] = { Idx... };
return (... && (idx[2 * Is] % 2 == 0 && idx[2 * Is] + 1 == idx[2 * Is + 1]));
}

template <class T, class A, T Idx0, T Idx1, T... Idx>
struct is_pair_of_contiguous_indices<T, A, Idx0, Idx1, Idx...> : std::conditional_t<(Idx0 % 2 == 0) && (Idx0 + 1 == Idx1), is_pair_of_contiguous_indices<T, A, Idx...>, std::false_type>
template <class T, T... Idx>
constexpr bool is_pair_of_contiguous_indices() noexcept
{
};

template <class T, class A, T... Idx>
inline constexpr bool is_pair_of_contiguous_indices_v = is_pair_of_contiguous_indices<T, A, Idx...>::value;
static_assert(sizeof...(Idx) % 2 == 0, "indices come in pairs");
return is_pair_of_contiguous_indices_impl<T, Idx...>(std::make_index_sequence<sizeof...(Idx) / 2>());
}

template <class A, uint16_t I0, uint16_t I1, uint16_t I2, uint16_t I3, uint16_t I4, uint16_t I5, uint16_t I6, uint16_t I7,
uint16_t I8, uint16_t I9, uint16_t I10, uint16_t I11, uint16_t I12, uint16_t I13, uint16_t I14, uint16_t I15,
Expand Down Expand Up @@ -2703,7 +2701,7 @@ namespace xsimd
template <class A, uint16_t... Idx>
XSIMD_INLINE batch<uint16_t, A> swizzle(batch<uint16_t, A> const& self, batch_constant<uint16_t, A, Idx...> mask, requires_arch<avx512f>) noexcept
{
if constexpr (detail::is_pair_of_contiguous_indices_v<uint16_t, A, Idx...>)
if constexpr (detail::is_pair_of_contiguous_indices<uint16_t, Idx...>())
{
constexpr typename detail::fold_batch_constant<A, Idx...>::type mask32;
return _mm512_permutexvar_epi32(static_cast<batch<uint32_t, A>>(mask32), self);
Expand Down
2 changes: 1 addition & 1 deletion include/xsimd/arch/xsimd_avx512vl_128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ namespace xsimd
using register_type = typename batch_bool<T, A>::register_type;
register_type r = 0;
unsigned shift = 0;
(void)std::initializer_list<register_type> { (r |= register_type(values ? 1 : 0) << (shift++))... };
((r |= register_type(values ? 1 : 0) << (shift++)), ...);
return r;
}

Expand Down
2 changes: 1 addition & 1 deletion include/xsimd/arch/xsimd_avx512vl_256.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ namespace xsimd
using register_type = typename batch_bool<T, A>::register_type;
register_type r = 0;
unsigned shift = 0;
(void)std::initializer_list<register_type> { (r |= register_type(values ? 1 : 0) << (shift++))... };
((r |= register_type(values ? 1 : 0) << (shift++)), ...);
return r;
}

Expand Down
21 changes: 2 additions & 19 deletions include/xsimd/config/xsimd_arch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "./xsimd_config.hpp"
#include "./xsimd_cpuid.hpp"

#include <initializer_list>
#include <type_traits>
#include <utility>

Expand All @@ -40,22 +39,6 @@ namespace xsimd

namespace detail
{
// Checks whether T appears in Tys.
template <class T, class... Tys>
struct contains;

template <class T>
struct contains<T> : std::false_type
{
};

template <class T, class Ty, class... Tys>
struct contains<T, Ty, Tys...>
: std::conditional_t<std::is_same_v<Ty, T>, std::true_type,
contains<T, Tys...>>
{
};

template <typename T>
XSIMD_INLINE constexpr T max_of(T value) noexcept
{
Expand Down Expand Up @@ -100,13 +83,13 @@ namespace xsimd
template <class Arch>
static constexpr bool contains() noexcept
{
return detail::contains<Arch, Archs...>::value;
return (std::is_same_v<Arch, Archs> || ...);
}

template <class F>
static XSIMD_INLINE void for_each(F&& f) noexcept
{
(void)std::initializer_list<bool> { (f(Archs {}), true)... };
(f(Archs {}), ...);
}

static constexpr std::size_t alignment() noexcept
Expand Down
20 changes: 5 additions & 15 deletions include/xsimd/types/xsimd_batch_constant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,25 +191,15 @@ namespace xsimd

private:
// Build a 64-bit mask from Values... (LSB = index 0)
template <std::size_t I, bool... Remaining>
struct build_bits_helper;

template <std::size_t I>
struct build_bits_helper<I>
{
static constexpr uint64_t value = 0u;
};

template <std::size_t I, bool Current, bool... Remaining>
struct build_bits_helper<I, Current, Remaining...>
template <std::size_t... Is>
static constexpr uint64_t build_bits(std::index_sequence<Is...>) noexcept
{
static constexpr uint64_t value = (Current ? (uint64_t(1) << I) : 0u)
| build_bits_helper<I + 1, Remaining...>::value;
};
return (uint64_t(0) | ... | (Values ? (uint64_t(1) << Is) : uint64_t(0)));
}

static constexpr uint64_t bits() noexcept
{
return build_bits_helper<0, Values...>::value;
return build_bits(std::make_index_sequence<sizeof...(Values)>());
}
static constexpr uint64_t low_mask(std::size_t k) noexcept
{
Expand Down
13 changes: 3 additions & 10 deletions include/xsimd/utils/bits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,13 @@ namespace xsimd
{
namespace utils
{
template <typename I>
constexpr I make_bit_mask(I bit)
{
static_assert(std::is_unsigned_v<I>, "Bit operations must be done on unsigned integers");
assert(bit < static_cast<I>(8 * sizeof(I)));
return static_cast<I>(I { 1 } << bit);
}

template <typename I, typename... Args>
constexpr I make_bit_mask(I bit, Args... bits)
{
// TODO(C++17): Use fold expression
static_assert(std::is_unsigned_v<I>, "Bit operations must be done on unsigned integers");
return make_bit_mask<I>(bit) | make_bit_mask<I>(static_cast<I>(bits)...);
[[maybe_unused]] constexpr I bit_count = static_cast<I>(8 * sizeof(I));
assert(((bit < bit_count) && ... && (static_cast<I>(bits) < bit_count)));
return static_cast<I>(((I { 1 } << bit) | ... | (I { 1 } << static_cast<I>(bits))));
}

template <int... Bits, typename I>
Expand Down
Loading