1616#include < cstdint>
1717#include < type_traits>
1818
19+ #include " ../../config/xsimd_inline.hpp"
20+
1921namespace 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
0 commit comments