From 6f7e26523e32a32737135a3405b379d90e53b780 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 10 Dec 2015 13:38:08 +0000 Subject: [PATCH] Moved more code to base class. --- bitset.h | 173 +++++++++------------------------------------------ ibitset.h | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 143 deletions(-) diff --git a/bitset.h b/bitset.h index 8b0ed1aa..2f51d8f5 100644 --- a/bitset.h +++ b/bitset.h @@ -36,10 +36,14 @@ SOFTWARE. #include #include "integral_limits.h" +#include "algorithm.h" #include "nullptr.h" #include "log.h" #include "ibitset.h" +#define ETL_NO_CHECKS +#include "error_handler.h" + #if defined(COMPILER_KEIL) #pragma diag_suppress 1300 #endif @@ -70,9 +74,7 @@ namespace etl static const size_t ALLOCATED_BITS = ARRAY_SIZE * BITS_PER_ELEMENT; public: - - - + //************************************************************************* /// Default constructor. //************************************************************************* @@ -88,7 +90,7 @@ namespace etl bitset(const bitset& other) : ibitset(N, ARRAY_SIZE, data) { - std::copy(other.data, other.data + ARRAY_SIZE, data); + etl::copy_n(other.data, ARRAY_SIZE, data); } //************************************************************************* @@ -97,27 +99,7 @@ namespace etl bitset(unsigned long long value) : ibitset(N, ARRAY_SIZE, data) { - reset(); - - const size_t SHIFT = (integral_limits::bits <= BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT; - - // Can we do it in one hit? - if (SHIFT == 0) - { - data[0] = element_t(value); - } - else - { - size_t i = 0; - - while ((value != 0) && (i < ARRAY_SIZE)) - { - data[i++] = value & ALL_SET; - value = value >> SHIFT; - } - } - - data[ARRAY_SIZE - 1] &= TOP_MASK; + initialise(value); } //************************************************************************* @@ -147,12 +129,19 @@ namespace etl return *this; } +//#define NDEBUG + + //************************************************************************* /// Set from a string. //************************************************************************* - bitset& set(const char* text) + bitset& set(const char* text) { - ibitset::set(text); + if (ETL_ASSERT(text != 0, etl::bitset_nullptr())) + { + ibitset::set(text); + } + return *this; } @@ -197,11 +186,7 @@ namespace etl //************************************************************************* bitset& operator =(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] = other.data[i]; - } - + etl::copy_n(other.data, ARRAY_SIZE, data); return *this; } @@ -210,11 +195,7 @@ namespace etl //************************************************************************* bitset& operator &=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] &= other.data[i]; - } - + ibitset::operator &=(other); return *this; } @@ -223,11 +204,7 @@ namespace etl //************************************************************************* bitset& operator |=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] |= other.data[i]; - } - + ibitset::operator |=(other); return *this; } @@ -236,11 +213,7 @@ namespace etl //************************************************************************* bitset& operator ^=(const bitset& other) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - data[i] ^= other.data[i]; - } - + ibitset::operator ^=(other); return *this; } @@ -249,13 +222,10 @@ namespace etl //************************************************************************* bitset operator ~() const { - bitset temp; - - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - temp[i] = ~data[i]; - } + bitset temp(*this); + temp.invert(); + return temp; } @@ -264,22 +234,9 @@ namespace etl //************************************************************************* bitset operator<<(size_t shift) const { - bitset temp; + bitset temp(*this); - if (ARRAY_SIZE == 1) - { - temp.data[0] = data[0] << shift; - } - else - { - size_t source = N - shift - 1; - size_t destination = N - 1; - - for (size_t i = 0; i < (N - shift); ++i) - { - temp.set(destination--, test(source--)); - } - } + temp <<= shift; return temp; } @@ -289,26 +246,7 @@ namespace etl //************************************************************************* bitset& operator<<=(size_t shift) { - if (ARRAY_SIZE == 1) - { - data[0] <<= shift; - } - else - { - size_t source = N - shift - 1; - size_t destination = N - 1; - - for (size_t i = 0; i < (N - shift); ++i) - { - set(destination--, test(source--)); - } - - for (size_t i = 0; i < shift; ++i) - { - reset(destination--); - } - } - + ibitset::operator <<=(shift); return *this; } @@ -317,22 +255,9 @@ namespace etl //************************************************************************* bitset operator>>(size_t shift) const { - bitset temp; + bitset temp(*this); - if (ARRAY_SIZE == 1) - { - temp.data[0] = data[0] >> shift; - } - else - { - size_t source = shift; - size_t destination = 0; - - while (source != N) - { - temp.set(destination++, test(source++)); - } - } + temp >>= shift; return temp; } @@ -342,54 +267,16 @@ namespace etl //************************************************************************* bitset& operator>>=(size_t shift) { - if (ARRAY_SIZE == 1) - { - data[0] >>= shift; - } - else - { - size_t source = shift; - size_t destination = 0; - - for (size_t i = 0; i < (N - shift); ++i) - { - set(destination++, test(source++)); - } - - for (size_t i = 0; i < shift; ++i) - { - reset(destination++); - } - } - + ibitset::operator >>=(shift); return *this; } - //************************************************************************* - /// swap - //************************************************************************* - void swap(bitset& other) - { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - std::swap(data, other.data); - } - } - //************************************************************************* /// operator == //************************************************************************* friend bool operator == (const bitset& lhs, const bitset& rhs) { - for (size_t i = 0; i < ARRAY_SIZE; ++i) - { - if (lhs.data[i] != rhs.data[i]) - { - return false; - } - } - - return true; + return ibitset::is_equal(lhs, rhs); } private: diff --git a/ibitset.h b/ibitset.h index a649e521..ff1825b4 100644 --- a/ibitset.h +++ b/ibitset.h @@ -33,6 +33,7 @@ SOFTWARE. #include #include +#include "exception.h" #include "integral_limits.h" #include "binary.h" @@ -42,6 +43,34 @@ SOFTWARE. namespace etl { + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(const char* what) + : exception(what) + { + } + }; + + //*************************************************************************** + /// Bitset nullptr exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_nullptr : public bitset_exception + { + public: + + bitset_nullptr() + : bitset_exception("bitset: nullptr") + { + } + }; + //************************************************************************* /// The base class for etl::bitset ///\ingroup bitset @@ -466,8 +495,152 @@ namespace etl return bit_reference(*this, position); } + //************************************************************************* + /// operator &= + //************************************************************************* + ibitset& operator &=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] &= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ibitset& operator |=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] |= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ibitset& operator ^=(const ibitset& other) + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] ^= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ibitset& operator<<=(size_t shift) + { + if (SIZE == 1) + { + pdata[0] <<= shift; + } + else + { + size_t source = NBITS - shift - 1; + size_t destination = NBITS - 1; + + for (size_t i = 0; i < (NBITS - shift); ++i) + { + set(destination--, test(source--)); + } + + for (size_t i = 0; i < shift; ++i) + { + reset(destination--); + } + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ibitset& operator>>=(size_t shift) + { + if (SIZE == 1) + { + pdata[0] >>= shift; + } + else + { + size_t source = shift; + size_t destination = 0; + + for (size_t i = 0; i < (NBITS - shift); ++i) + { + set(destination++, test(source++)); + } + + for (size_t i = 0; i < shift; ++i) + { + reset(destination++); + } + } + + return *this; + } + + //************************************************************************* + /// swap + //************************************************************************* + void swap(ibitset& other) + { + std::swap_ranges(pdata, pdata + SIZE, other.pdata); + } + protected: + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ibitset& initialise(unsigned long long value) + { + reset(); + + const size_t SHIFT = (integral_limits::bits <= BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT; + + // Can we do it in one hit? + if (SHIFT == 0) + { + pdata[0] = element_t(value); + } + else + { + size_t i = 0; + + while ((value != 0) && (i < SIZE)) + { + pdata[i++] = value & ALL_SET; + value = value >> SHIFT; + } + } + + pdata[SIZE - 1] &= TOP_MASK; + + return *this; + } + + //************************************************************************* + /// Invert + //************************************************************************* + void invert() + { + for (size_t i = 0; i < SIZE; ++i) + { + pdata[i] = ~pdata[i]; + } + } + //************************************************************************* /// Gets a reference to the specified bit. //************************************************************************* @@ -489,6 +662,14 @@ namespace etl TOP_MASK = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); } + //************************************************************************* + /// Compare bitsets. + //************************************************************************* + static bool is_equal(const ibitset& lhs, const ibitset&rhs) + { + return std::equal(lhs.pdata, lhs.pdata + lhs.SIZE, rhs.pdata); + } + element_t TOP_MASK; private: