Bitset updates

This commit is contained in:
John Wellbelove 2022-01-22 16:16:44 +00:00
parent 1f7ebe3ee8
commit e98270ca60
2 changed files with 175 additions and 81 deletions

View File

@ -275,7 +275,8 @@ namespace etl
size_t index;
element_t mask;
if (SIZE == 0) {
if (SIZE == 0)
{
return false;
}
else if (SIZE == 1)
@ -433,6 +434,11 @@ namespace etl
typename etl::enable_if<etl::is_integral<T>::value, T>::type
value() const
{
for (size_t i = sizeof(long long) / sizeof(element_t); i < SIZE; ++i)
{
ETL_ASSERT_AND_RETURN_VALUE(!(pdata[i]), ETL_ERROR(etl::bitset_overflow), T(0));
}
T v = T(0);
const bool OK = (sizeof(T) * CHAR_BIT) >= (SIZE * BITS_PER_ELEMENT);
@ -453,6 +459,22 @@ namespace etl
return v;
}
//*************************************************************************
/// Put to a unsigned long.
//*************************************************************************
unsigned long to_ulong() const
{
return value<unsigned long>();
}
//*************************************************************************
/// Put to a unsigned long long.
//*************************************************************************
unsigned long long to_ullong() const
{
return value<unsigned long long>();
}
//*************************************************************************
/// Resets the bitset.
//*************************************************************************
@ -518,7 +540,6 @@ namespace etl
{
size_t index;
element_t bit;
if (SIZE == 0)
{
@ -546,6 +567,11 @@ namespace etl
//*************************************************************************
bool all() const
{
if (SIZE == 0UL)
{
return true;
}
// All but the last.
for (size_t i = 0UL; i < (SIZE - 1); ++i)
{
@ -726,26 +752,37 @@ namespace etl
//*************************************************************************
ibitset& operator<<=(size_t shift)
{
if (SIZE == 0) {
return *this;
}
else if (SIZE == 1)
if (SIZE != 0UL)
{
pdata[0] <<= shift;
}
else
{
size_t source = NBITS - shift - 1;
size_t destination = NBITS - 1;
for (size_t i = 0UL; i < (NBITS - shift); ++i)
// Just one element?
if (SIZE == 1UL)
{
set(destination--, test(source--));
pdata[0] <<= shift;
}
for (size_t i = 0UL; i < shift; ++i)
else if (shift == BITS_PER_ELEMENT)
{
reset(destination--);
for (size_t i = (SIZE - 1); i > 0U; --i)
{
pdata[i] = pdata[i - 1];
}
pdata[0] = 0;
}
else
{
// TODO Optimise.
size_t source = NBITS - shift - 1;
size_t destination = NBITS - 1;
for (size_t i = 0UL; i < (NBITS - shift); ++i)
{
set(destination--, test(source--));
}
for (size_t i = 0UL; i < shift; ++i)
{
reset(destination--);
}
}
}
@ -757,26 +794,38 @@ namespace etl
//*************************************************************************
ibitset& operator>>=(size_t shift)
{
if (SIZE == 0) {
return *this;
}
else if (SIZE == 1)
if (SIZE != 0UL)
{
pdata[0] >>= shift;
}
else
{
size_t source = shift;
size_t destination = 0;
for (size_t i = 0UL; i < (NBITS - shift); ++i)
// Just one element?
if (SIZE == 1UL)
{
set(destination++, test(source++));
pdata[0] >>= shift;
}
for (size_t i = 0UL; i < shift; ++i)
// Shift is the size of an element?
else if (shift == BITS_PER_ELEMENT)
{
reset(destination++);
for (size_t i = 0UL; i < (SIZE - 1); ++i)
{
pdata[i] = pdata[i + 1];
}
pdata[SIZE - 1] = 0;
}
else
{
// TODO Optimise.
size_t source = shift;
size_t destination = 0UL;
for (size_t i = 0UL; i < (NBITS - shift); ++i)
{
set(destination++, test(source++));
}
for (size_t i = 0UL; i < shift; ++i)
{
reset(destination++);
}
}
}
@ -824,46 +873,6 @@ namespace etl
}
#endif
//*************************************************************************
/// to_ulong
/// Returns an unsigned long represented by the bitset data.
//*************************************************************************
unsigned long to_ulong() const
{
for (size_t i = sizeof(long) / sizeof(element_t); i < SIZE; ++i)
ETL_ASSERT(!(pdata[i]), ETL_ERROR(etl::bitset_overflow));
unsigned long out = 0;
for (size_t i = 0UL; i < SIZE; i++)
{
out += static_cast<unsigned long>(pdata[i] & ((i < SIZE - 1) ? ALL_SET : TOP_MASK)) << (BITS_PER_ELEMENT * i);
}
return out;
}
#if ETL_CPP11_SUPPORTED
//*************************************************************************
/// to_ullong
/// Returns an unsigned long long represented by the bitset data.
//*************************************************************************
unsigned long long to_ullong() const
{
for (size_t i = sizeof(long long) / sizeof(element_t); i < SIZE; ++i)
ETL_ASSERT(!(pdata[i]), ETL_ERROR(etl::bitset_overflow));
unsigned long long out = 0;
for (size_t i = 0ULL; i < SIZE; i++)
{
out += static_cast<unsigned long long>(pdata[i] & ((i < SIZE - 1) ? ALL_SET : TOP_MASK)) << (BITS_PER_ELEMENT * i);
}
return out;
}
#endif
protected:
//*************************************************************************
@ -903,8 +912,10 @@ namespace etl
{
for (size_t i = 0UL; i < SIZE; ++i)
{
pdata[i] = ~pdata[i] & (i == SIZE - 1 ? TOP_MASK : ALL_SET);
pdata[i] = ~pdata[i];
}
pdata[SIZE - 1] &= TOP_MASK;
}
//*************************************************************************
@ -1138,13 +1149,21 @@ namespace etl
//*************************************************************************
/// Returns a string representing the bitset.
//*************************************************************************
template<class STRINGT = etl::string<MAXN> >
STRINGT to_string(typename STRINGT::value_type zero = typename STRINGT::value_type('0'), typename STRINGT::value_type one = typename STRINGT::value_type('1')) const
#if ETL_CPP11_SUPPORTED
template <typename TString = etl::string<MAXN>>
#else
template <typename TString>
#endif
TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const
{
STRINGT result;
TString result;
result.assign(MAXN, '\0');
for (size_t i = MAXN; i > 0; --i) {
result.resize(MAXN, '\0');
ETL_ASSERT_AND_RETURN_VALUE((result.size() == MAXN), ETL_ERROR(etl::bitset_overflow), result);
for (size_t i = MAXN; i > 0; --i)
{
result[MAXN - i] = test(i - 1) ? one : zero;
}
@ -1255,7 +1274,7 @@ namespace etl
private:
element_t data[ARRAY_SIZE];
element_t data[ARRAY_SIZE > 0U ? ARRAY_SIZE : 1U];
};
//***************************************************************************

View File

@ -749,6 +749,26 @@ namespace
CHECK(data2 == shift11);
}
//*************************************************************************
TEST(test_shift_left_operator_shift_element_size)
{
etl::bitset<60> data(0x12345678UL);
etl::bitset<60> shift(0x1234567800UL);
data <<= 8U;
CHECK_EQUAL(shift.value<uint64_t>(), data.value<uint64_t>());
}
//*************************************************************************
TEST(test_shift_left_operator_overflow)
{
etl::bitset<31> data(0x7FFFFFFFUL);
etl::bitset<31> shifted(0x7FFFFFFEUL);
data <<= 1U;
CHECK(data == shifted);
}
//*************************************************************************
TEST(test_shift_left_copy_operator)
{
@ -790,6 +810,16 @@ namespace
CHECK(data2 == shift11);
}
//*************************************************************************
TEST(test_shift_right_operator_shift_element_size)
{
etl::bitset<60> data(0x12345678UL);
etl::bitset<60> shift(0x123456UL);
data >>= 8U;
CHECK_EQUAL(shift.value<uint64_t>(), data.value<uint64_t>());
}
//*************************************************************************
TEST(test_shift_right_copy_operator)
{
@ -1091,5 +1121,50 @@ namespace
CHECK_EQUAL(0x34U, s[2]);
CHECK_EQUAL(0x12U, s[3]);
}
//*************************************************************************
TEST(test_to_string)
{
etl::bitset<32> b(0x12345678UL);
etl::string<32> text = b.to_string('.', '*');
std::string stdtext = b.to_string<std::string>('.', '*');
CHECK_THROW(etl::string<32> text1 = b.to_string<etl::string<30>>('.', '*'), etl::bitset_overflow);
CHECK_EQUAL("...*..*...**.*...*.*.**..****...", text.c_str());
CHECK_EQUAL("...*..*...**.*...*.*.**..****...", stdtext.c_str());
}
//*************************************************************************
TEST(test_issue_497_count_inverted_bits)
{
etl::bitset<5U> bits;
std::bitset<5U> stdbits;
etl::bitset<5U> negbits = ~bits;
std::bitset<5U> stdnegbits = ~stdbits;
CHECK_EQUAL(stdbits.count(), bits.count());
CHECK_EQUAL(stdbits.all(), bits.all());
CHECK_EQUAL(stdnegbits.count(), negbits.count());
CHECK_EQUAL(stdnegbits.all(), negbits.all());
}
//*************************************************************************
TEST(test_issue_497_shifted_zero_sized_bitset)
{
etl::bitset<0> bits;
std::bitset<0> stdbits;
CHECK_EQUAL(stdbits.size(), bits.size());
CHECK_EQUAL(stdbits.none(), bits.none());
CHECK_EQUAL(stdbits.all(), bits.all());
CHECK_EQUAL(stdbits.any(), bits.any());
CHECK_EQUAL(stdbits.count(), bits.count());
CHECK_EQUAL(stdbits.to_ulong(), bits.to_ulong());
CHECK_EQUAL(stdbits.to_ullong(), bits.to_ullong());
etl::bitset<0> shiftbits = bits << 1; // No exception.
}
};
}