mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Bitset updates
This commit is contained in:
parent
1f7ebe3ee8
commit
e98270ca60
@ -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];
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
|
||||
@ -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.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user