diff --git a/bitset.h b/bitset.h index acbfa551..e6180ea5 100644 --- a/bitset.h +++ b/bitset.h @@ -42,6 +42,7 @@ SOFTWARE. #include "nullptr.h" #include "log.h" #include "ibitset.h" +#include "binary.h" #if WIN32 #undef min @@ -70,21 +71,21 @@ namespace etl class bitset : public ibitset { // The type used for each element in the array. - typedef typename smallest_uint_for_bits::type element_type; + typedef typename smallest_uint_for_bits::type element_t; - static const element_type ALL_SET = etl::integral_limits::max; - static const element_type ALL_CLEAR = 0; - static const size_t BITS_PER_ELEMENT = etl::integral_limits::bits; - static const size_t ARRAY_SIZE = (N % BITS_PER_ELEMENT == 0) ? N / BITS_PER_ELEMENT : N / BITS_PER_ELEMENT + 1; + static const element_t ALL_SET = etl::integral_limits::max; + static const element_t ALL_CLEAR = 0; + static const size_t BITS_PER_ELEMENT = etl::integral_limits::bits; + static const size_t ARRAY_SIZE = (N % BITS_PER_ELEMENT == 0) ? N / BITS_PER_ELEMENT : N / BITS_PER_ELEMENT + 1; public: - static const size_t TOTAL_BITS = ARRAY_SIZE * BITS_PER_ELEMENT; + static const size_t TOTAL_BITS = ARRAY_SIZE * BITS_PER_ELEMENT; private: - static const size_t TOP_MASK_SHIFT = ((BITS_PER_ELEMENT - (TOTAL_BITS - N)) % BITS_PER_ELEMENT); - static const element_type TOP_MASK = element_type(TOP_MASK_SHIFT == 0 ? ALL_SET : ~(ALL_SET << TOP_MASK_SHIFT)); + static const size_t TOP_MASK_SHIFT = ((BITS_PER_ELEMENT - (TOTAL_BITS - N)) % BITS_PER_ELEMENT); + static const element_t TOP_MASK = element_t(TOP_MASK_SHIFT == 0 ? ALL_SET : ~(ALL_SET << TOP_MASK_SHIFT)); public: @@ -588,7 +589,7 @@ namespace etl // Can we do it in one hit? if (SHIFT == 0) { - data[0] = element_type(value); + data[0] = element_t(value); } else { @@ -637,18 +638,18 @@ namespace etl { if (position < N) { - size_t index; - element_type bit; + size_t index; + element_t bit; if (ARRAY_SIZE == 1) { index = 0; - bit = element_type(1) << position; + bit = element_t(1) << position; } else { index = position >> log2::value; - bit = element_type(1) << (position & (BITS_PER_ELEMENT - 1)); + bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); } if (value) @@ -698,17 +699,17 @@ namespace etl if (position < N) { size_t index; - element_type bit; + element_t bit; if (ARRAY_SIZE == 1) { index = 0; - bit = element_type(1) << position; + bit = element_t(1) << position; } else { index = position >> log2::value; - bit = element_type(1) << (position & (BITS_PER_ELEMENT - 1)); + bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); } data[index] &= ~bit; @@ -740,17 +741,17 @@ namespace etl if (position < N) { size_t index; - element_type bit; + element_t bit; if (ARRAY_SIZE == 1) { index = 0; - bit = element_type(1) << position; + bit = element_t(1) << position; } else { index = position >> log2::value; - bit = element_type(1) << (position & (BITS_PER_ELEMENT - 1)); + bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); } data[index] ^= bit; @@ -784,17 +785,17 @@ namespace etl if (position < N) { size_t index; - element_type mask; + element_t mask; if (ARRAY_SIZE == 1) { index = 0; - mask = element_type(1) << position; + mask = element_t(1) << position; } else { index = position >> log2::value; - mask = element_type(1) << (position & (BITS_PER_ELEMENT - 1)); + mask = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); } return (data[index] & mask) != 0; @@ -861,13 +862,7 @@ namespace etl for (size_t i = 0; i < ARRAY_SIZE; ++i) { - element_type value = data[i]; - - while (value != 0) - { - n += (value & 1); - value >>= 1; - } + n += etl::count_bits(data[i]); } return n; @@ -914,24 +909,35 @@ namespace etl bit = position & (BITS_PER_ELEMENT - 1); } - element_type mask = 1 << bit; + element_t mask = 1 << bit; // For each element in the bitset... while (index < ARRAY_SIZE) { - // For each bit in the element... - while ((bit < BITS_PER_ELEMENT) && (position != N)) - { - // Equal to the required state? - if (((data[index] & mask) != 0) == state) - { - return position; - } + element_t value = data[index]; - // Move on to the next bit. - mask <<= 1; - ++position; - ++bit; + // Needs checking? + if (( state && (value != ALL_CLEAR)) || + (!state && (value != ALL_SET))) + { + // For each bit in the element... + while ((bit < BITS_PER_ELEMENT) && (position < N)) + { + // Equal to the required state? + if (((value & mask) != 0) == state) + { + return position; + } + + // Move on to the next bit. + mask <<= 1; + ++position; + ++bit; + } + } + else + { + position += BITS_PER_ELEMENT; } // Start at the beginning for all other elements. @@ -941,7 +947,7 @@ namespace etl ++index; } - return N; + return ibitset::npos; } //************************************************************************* @@ -1179,7 +1185,7 @@ namespace etl private: - etl::array data; + etl::array data; }; //*************************************************************************** diff --git a/ibitset.h b/ibitset.h index 0276f358..7923d442 100644 --- a/ibitset.h +++ b/ibitset.h @@ -30,6 +30,8 @@ SOFTWARE. #ifndef __ETL_IBITSET__ #define __ETL_IBITSET__ +#include "integral_limits.h" + namespace etl { //************************************************************************* @@ -40,6 +42,8 @@ namespace etl { public: + static const size_t npos = etl::integral_limits::max; + //************************************************************************* /// Default constructor. //************************************************************************* diff --git a/ipool.h b/ipool.h index 8cdfccc2..e401ffe3 100644 --- a/ipool.h +++ b/ipool.h @@ -69,8 +69,8 @@ namespace etl //******************************* const_iterator() : index(0), - p_buffer(p_buffer), - p_in_use_flags(p_in_use_flags) + p_buffer(nullptr), + p_in_use_flags(nullptr) { } @@ -133,15 +133,6 @@ namespace etl private: //******************************* - const_iterator(const_pointer p_buffer, - const ibitset* p_in_use_flags) - : index(0), - p_buffer(p_buffer), - p_in_use_flags(p_in_use_flags) - { - index = p_in_use_flags->find_first(true); - } - //******************************* const_iterator(size_t index, const_pointer p_buffer, @@ -162,7 +153,16 @@ namespace etl //************************************************************************* const_iterator begin() const { - return const_iterator(in_use_flags.find_first(true), p_buffer, &in_use_flags); + size_t index = in_use_flags.find_first(true); + + if (index != ibitset::npos) + { + return const_iterator(index, p_buffer, &in_use_flags); + } + else + { + return end(); + } } //************************************************************************* @@ -178,7 +178,7 @@ namespace etl //************************************************************************* const_iterator end() const { - return const_iterator(in_use_flags.size(), p_buffer, &in_use_flags); + return const_iterator(ibitset::npos, p_buffer, &in_use_flags); } //************************************************************************* diff --git a/test/test_bitset.cpp b/test/test_bitset.cpp index 71d8e61a..d9391bc8 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset.cpp @@ -611,10 +611,10 @@ namespace data.set("000000"); CHECK_EQUAL(0, data.find_first(false)); - CHECK_EQUAL(6, data.find_first(true)); + CHECK_EQUAL(etl::ibitset::npos, data.find_first(true)); data.set("111111"); - CHECK_EQUAL(6, data.find_first(false)); + CHECK_EQUAL(etl::ibitset::npos, data.find_first(false)); CHECK_EQUAL(0, data.find_first(true)); data.set("000001"); @@ -646,12 +646,12 @@ namespace data.set("000000"); CHECK_EQUAL(0, data.find_next(false, 0)); CHECK_EQUAL(1, data.find_next(false, 1)); - CHECK_EQUAL(6, data.find_next(true, 2)); + CHECK_EQUAL(etl::ibitset::npos, data.find_next(true, 2)); data.set("111111"); CHECK_EQUAL(0, data.find_next(true, 0)); CHECK_EQUAL(1, data.find_next(true, 1)); - CHECK_EQUAL(6, data.find_next(false, 2)); + CHECK_EQUAL(etl::ibitset::npos, data.find_next(false, 2)); data.set("001110"); CHECK_EQUAL(0, data.find_next(false, 0));