Skip to content

Commit 39cdc23

Browse files
committed
Add is_only_from_lo/hi
1 parent 9aab18c commit 39cdc23

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

include/xsimd/arch/common/xsimd_common_swizzle.hpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <cstdint>
1717
#include <type_traits>
1818

19+
#include "../../config/xsimd_inline.hpp"
20+
1921
namespace xsimd
2022
{
2123
template <typename T, class A, T... Values>
@@ -80,6 +82,52 @@ namespace xsimd
8082
&& dup_hi_impl<I + 1, N, T, Vs...>();
8183
}
8284

85+
// ────────────────────────────────────────────────────────────────────────
86+
// only_from_lo
87+
template <typename T, T Size, T First, T... Vals>
88+
struct only_from_lo_impl;
89+
90+
template <typename T, T Size, T Last>
91+
struct only_from_lo_impl<T, Size, Last>
92+
{
93+
static constexpr bool value = (Last < (Size / 2));
94+
};
95+
96+
template <typename T, T Size, T First, T... Vals>
97+
struct only_from_lo_impl
98+
{
99+
static constexpr bool value = (First < (Size / 2)) && only_from_lo_impl<T, Size, Vals...>::value;
100+
};
101+
102+
template <typename T, T... Vals>
103+
constexpr bool is_only_from_lo()
104+
{
105+
return only_from_lo_impl<T, sizeof...(Vals), Vals...>::value;
106+
};
107+
108+
// ────────────────────────────────────────────────────────────────────────
109+
// only_from_hi
110+
template <typename T, T Size, T First, T... Vals>
111+
struct only_from_hi_impl;
112+
113+
template <typename T, T Size, T Last>
114+
struct only_from_hi_impl<T, Size, Last>
115+
{
116+
static constexpr bool value = (Last >= (Size / 2));
117+
};
118+
119+
template <typename T, T Size, T First, T... Vals>
120+
struct only_from_hi_impl
121+
{
122+
static constexpr bool value = (First >= (Size / 2)) && only_from_hi_impl<T, Size, Vals...>::value;
123+
};
124+
125+
template <typename T, T... Vals>
126+
constexpr bool is_only_from_hi()
127+
{
128+
return only_from_hi_impl<T, sizeof...(Vals), Vals...>::value;
129+
};
130+
83131
// ────────────────────────────────────────────────────────────────────────
84132
// 1) helper to get the I-th value from the Vs pack
85133
template <std::size_t I, uint32_t Head, uint32_t... Tail>
@@ -118,6 +166,7 @@ namespace xsimd
118166
static_assert(sizeof...(Vs) >= 1, "Need at least one lane");
119167
return cross_impl<0, sizeof...(Vs), sizeof...(Vs) / 2, Vs...>::value;
120168
}
169+
121170
template <typename T, T... Vs>
122171
XSIMD_INLINE constexpr bool is_identity() noexcept { return detail::identity_impl<0, T, Vs...>(); }
123172
template <typename T, T... Vs>
@@ -131,6 +180,10 @@ namespace xsimd
131180
template <typename T, class A, T... Vs>
132181
XSIMD_INLINE constexpr bool is_dup_hi(batch_constant<T, A, Vs...>) noexcept { return is_dup_hi<T, Vs...>(); }
133182
template <typename T, class A, T... Vs>
183+
XSIMD_INLINE constexpr bool is_only_from_lo(batch_constant<T, A, Vs...>) noexcept { return detail::is_only_from_lo<T, Vs...>(); }
184+
template <typename T, class A, T... Vs>
185+
XSIMD_INLINE constexpr bool is_only_from_hi(batch_constant<T, A, Vs...>) noexcept { return detail::is_only_from_hi<T, Vs...>(); }
186+
template <typename T, class A, T... Vs>
134187
XSIMD_INLINE constexpr bool is_cross_lane(batch_constant<T, A, Vs...>) noexcept { return detail::is_cross_lane<Vs...>(); }
135188

136189
} // namespace detail

include/xsimd/arch/xsimd_common_fwd.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ namespace xsimd
6565
XSIMD_INLINE constexpr bool is_dup_hi(batch_constant<T, A, Vs...>) noexcept;
6666
template <typename T, class A, T... Vs>
6767
XSIMD_INLINE constexpr bool is_cross_lane(batch_constant<T, A, Vs...>) noexcept;
68+
template <typename T, class A, T... Vs>
69+
XSIMD_INLINE constexpr bool is_only_from_lo(batch_constant<T, A, Vs...>) noexcept;
70+
template <typename T, class A, T... Vs>
71+
XSIMD_INLINE constexpr bool is_only_from_hi(batch_constant<T, A, Vs...>) noexcept;
6872

6973
}
7074
}

test/test_batch_manip.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ namespace xsimd
3434
// 8-lane dup-hi (repeat 4..7 twice)
3535
static_assert(is_dup_hi<std::uint32_t, 4, 5, 6, 7, 4, 5, 6, 7>(), "dup_hi failed");
3636
static_assert(!is_dup_lo<std::uint32_t, 4, 5, 6, 7, 4, 5, 6, 7>(), "dup_lo on dup_hi");
37+
// 8-lane is-only-from-hi (repeat 4..7 twice)
38+
static_assert(is_only_from_hi<std::uint32_t, 4, 5, 6, 7, 7, 7, 7, 7>(), "only_from_hi on hi");
39+
static_assert(!is_only_from_hi<std::uint32_t, 4, 5, 6, 7, 7, 1, 7, 7>(), "only_from_hi failed");
40+
// 8-lane is-only-from-lo (repeat 4..7 twice)
41+
static_assert(is_only_from_lo<std::uint32_t, 0, 1, 2, 3, 3, 2, 1, 0>(), "only_from_lo on lo");
42+
static_assert(!is_only_from_lo<std::uint32_t, 0, 1, 2, 7, 3, 2, 1, 0>(), "only_from_lo failed");
3743
// ────────────────────────────────────────────────────────────────────────
3844
// 4-lane identity
3945
static_assert(is_identity<std::uint32_t, 0, 1, 2, 3>(), "4-lane identity failed");

0 commit comments

Comments
 (0)