Skip to content

Commit 0a8d720

Browse files
committed
WIP
1 parent 49c9cda commit 0a8d720

File tree

2 files changed

+8
-211
lines changed

2 files changed

+8
-211
lines changed

include/xsimd/types/xsimd_batch.hpp

Lines changed: 0 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -355,17 +355,6 @@ namespace xsimd
355355
XSIMD_INLINE bool is_full() const noexcept;
356356
XSIMD_INLINE std::size_t countl_zero() const noexcept;
357357
XSIMD_INLINE std::size_t countr_zero() const noexcept;
358-
// mask utility helpers (C++11, portable)
359-
XSIMD_INLINE std::size_t popcount() const noexcept;
360-
XSIMD_INLINE std::size_t countr_one() const noexcept; // trailing contiguous 1s from LSB
361-
XSIMD_INLINE std::size_t countl_one() const noexcept; // leading contiguous 1s from MSB
362-
XSIMD_INLINE bool is_all_zeros() const noexcept;
363-
XSIMD_INLINE bool is_all_ones() const noexcept;
364-
XSIMD_INLINE std::size_t first_one_index() const noexcept; // returns size if none
365-
XSIMD_INLINE std::size_t last_one_index() const noexcept; // returns size if none
366-
XSIMD_INLINE bool is_prefix_ones() const noexcept; // mask == low contiguous ones starting at LSB
367-
XSIMD_INLINE bool is_suffix_ones() const noexcept; // mask == high contiguous ones ending at MSB
368-
369358
// comparison operators
370359
XSIMD_INLINE batch_bool operator==(batch_bool const& other) const noexcept;
371360
XSIMD_INLINE batch_bool operator!=(batch_bool const& other) const noexcept;
@@ -1119,68 +1108,6 @@ namespace xsimd
11191108
return kernel::from_mask(batch_bool<T, A>(), mask, A {});
11201109
}
11211110

1122-
template <class T, class A>
1123-
XSIMD_INLINE std::size_t batch_bool<T, A>::popcount() const noexcept
1124-
{
1125-
uint64_t m = truncated_mask();
1126-
std::size_t c = 0;
1127-
while (m)
1128-
{
1129-
m &= (m - 1); // clear lowest set bit
1130-
++c;
1131-
}
1132-
return c;
1133-
}
1134-
1135-
template <class T, class A>
1136-
XSIMD_INLINE std::size_t batch_bool<T, A>::countr_one() const noexcept
1137-
{
1138-
uint64_t m = truncated_mask();
1139-
std::size_t cnt = 0;
1140-
while (cnt < size && (m & 1u))
1141-
{
1142-
++cnt;
1143-
m >>= 1;
1144-
}
1145-
return cnt;
1146-
}
1147-
1148-
template <class T, class A>
1149-
XSIMD_INLINE std::size_t batch_bool<T, A>::countl_one() const noexcept
1150-
{
1151-
uint64_t m = truncated_mask();
1152-
const std::size_t n = size;
1153-
if (n == 0)
1154-
return 0;
1155-
std::size_t cnt = 0;
1156-
for (std::size_t i = 0; i < n; ++i)
1157-
{
1158-
const std::size_t bit = n - 1 - i;
1159-
const bool bit_value = (bit < 64) ? (((m >> bit) & 1u) != 0u) : false;
1160-
if (bit_value)
1161-
{
1162-
++cnt;
1163-
}
1164-
else
1165-
{
1166-
break;
1167-
}
1168-
}
1169-
return cnt;
1170-
}
1171-
1172-
template <class T, class A>
1173-
XSIMD_INLINE bool batch_bool<T, A>::is_all_zeros() const noexcept
1174-
{
1175-
return none();
1176-
}
1177-
1178-
template <class T, class A>
1179-
XSIMD_INLINE bool batch_bool<T, A>::is_all_ones() const noexcept
1180-
{
1181-
return all();
1182-
}
1183-
11841111
template <class T, class A>
11851112
XSIMD_INLINE uint64_t batch_bool<T, A>::truncated_mask() const noexcept
11861113
{
@@ -1249,78 +1176,6 @@ namespace xsimd
12491176
return std::min<std::size_t>(width, countr_zero_bits(m));
12501177
}
12511178

1252-
template <class T, class A>
1253-
XSIMD_INLINE std::size_t batch_bool<T, A>::first_one_index() const noexcept
1254-
{
1255-
uint64_t m = truncated_mask();
1256-
const std::size_t n = size;
1257-
if (m == 0u)
1258-
return n;
1259-
std::size_t idx = 0;
1260-
while (idx < n)
1261-
{
1262-
if (m & 1u)
1263-
return idx;
1264-
m >>= 1;
1265-
++idx;
1266-
}
1267-
return n;
1268-
}
1269-
1270-
template <class T, class A>
1271-
XSIMD_INLINE std::size_t batch_bool<T, A>::last_one_index() const noexcept
1272-
{
1273-
uint64_t m = truncated_mask();
1274-
const std::size_t n = size;
1275-
if (m == 0u)
1276-
return n;
1277-
for (std::size_t i = 0; i < n; ++i)
1278-
{
1279-
std::size_t bit = n - 1 - i;
1280-
if (((m >> bit) & 1u) != 0u)
1281-
return bit;
1282-
}
1283-
return n;
1284-
}
1285-
1286-
template <class T, class A>
1287-
XSIMD_INLINE bool batch_bool<T, A>::is_prefix_ones() const noexcept
1288-
{
1289-
const std::size_t k = countr_one();
1290-
if (k == 0)
1291-
return is_all_zeros();
1292-
uint64_t expected = low_mask(k);
1293-
uint64_t m = truncated_mask();
1294-
return m == expected;
1295-
}
1296-
1297-
template <class T, class A>
1298-
XSIMD_INLINE bool batch_bool<T, A>::is_suffix_ones() const noexcept
1299-
{
1300-
const std::size_t n = size;
1301-
const std::size_t k = countl_one();
1302-
if (k == 0)
1303-
return is_all_zeros();
1304-
1305-
uint64_t expected;
1306-
if (k >= 64u)
1307-
{
1308-
expected = ~uint64_t(0);
1309-
}
1310-
else
1311-
{
1312-
const std::size_t shift = (n > k) ? (n - k) : 0u;
1313-
const uint64_t lowk = low_mask(k);
1314-
expected = lowk << shift;
1315-
}
1316-
if (n < 64)
1317-
{
1318-
expected &= low_mask(n);
1319-
}
1320-
uint64_t m = truncated_mask();
1321-
return m == expected;
1322-
}
1323-
13241179
template <class T, class A>
13251180
constexpr uint64_t batch_bool<T, A>::low_mask(std::size_t k) noexcept
13261181
{

test/test_batch_bool.cpp

Lines changed: 8 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -818,80 +818,22 @@ struct batch_bool_test
818818
auto check_mask = [&](batch_t const& m, const char*)
819819
{
820820
constexpr std::size_t N = batch_t::size;
821-
// expected popcount via existing count()
822-
std::size_t expected_pop = xsimd::count(m);
823-
CHECK_EQ(m.popcount(), expected_pop);
824-
825-
// expected is_all_zeros / is_all_ones
826-
CHECK_EQ(m.is_all_zeros(), expected_pop == 0);
827-
CHECK_EQ(m.is_all_ones(), expected_pop == N);
828-
829-
// build a bool array to derive prefix/suffix and indices
830821
std::array<bool, N> bits;
831822
m.store_unaligned(bits.data());
832823

833-
// countr_one (trailing ones from LSB)
834-
std::size_t cto = 0;
835-
for (std::size_t i = 0; i < N; ++i)
824+
std::size_t trailing_zeroes = 0;
825+
while (trailing_zeroes < N && !bits[trailing_zeroes])
836826
{
837-
if (bits[i])
838-
++cto;
839-
else
840-
break;
827+
++trailing_zeroes;
841828
}
842-
CHECK_EQ(m.countr_one(), cto);
829+
CHECK_EQ(m.countr_zero(), trailing_zeroes);
843830

844-
// countl_one (leading ones from MSB)
845-
std::size_t clo = 0;
846-
for (std::size_t i = 0; i < N; ++i)
847-
{
848-
std::size_t b = N - 1 - i;
849-
if (bits[b])
850-
++clo;
851-
else
852-
break;
853-
}
854-
CHECK_EQ(m.countl_one(), clo);
855-
856-
// first_one_index / last_one_index
857-
std::size_t first = N, last = N;
858-
for (std::size_t i = 0; i < N; ++i)
859-
{
860-
if (bits[i])
861-
{
862-
first = i;
863-
break;
864-
}
865-
}
866-
for (std::size_t i = 0; i < N; ++i)
831+
std::size_t leading_zeroes = 0;
832+
while (leading_zeroes < N && !bits[N - 1 - leading_zeroes])
867833
{
868-
std::size_t b = N - 1 - i;
869-
if (bits[b])
870-
{
871-
last = b;
872-
break;
873-
}
834+
++leading_zeroes;
874835
}
875-
CHECK_EQ(m.first_one_index(), first);
876-
CHECK_EQ(m.last_one_index(), last);
877-
878-
// prefix/suffix ones
879-
bool is_prefix = true;
880-
for (std::size_t i = 0; i < cto; ++i)
881-
if (!bits[i])
882-
is_prefix = false;
883-
for (std::size_t i = cto; i < N; ++i)
884-
if (bits[i])
885-
is_prefix = false;
886-
bool is_suffix = true;
887-
for (std::size_t i = 0; i < N - clo; ++i)
888-
if (bits[i])
889-
is_suffix = false;
890-
for (std::size_t i = N - clo; i < N; ++i)
891-
if (!bits[i])
892-
is_suffix = false;
893-
CHECK_EQ(m.is_prefix_ones(), is_prefix);
894-
CHECK_EQ(m.is_suffix_ones(), is_suffix);
836+
CHECK_EQ(m.countl_zero(), leading_zeroes);
895837
};
896838

897839
check_mask(bool_g.all_false, "all_false");

0 commit comments

Comments
 (0)