Moved more code to base class.

This commit is contained in:
John Wellbelove 2015-12-10 13:38:08 +00:00
parent 8f7b16dc9c
commit 6f7e26523e
2 changed files with 211 additions and 143 deletions

173
bitset.h
View File

@ -36,10 +36,14 @@ SOFTWARE.
#include <stddef.h>
#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<N>& 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<unsigned long long>::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<N>& set(const char* text)
bitset<N>& 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<N>& operator =(const bitset<N>& 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<N>& operator &=(const bitset<N>& 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<N>& operator |=(const bitset<N>& 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<N>& operator ^=(const bitset<N>& 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<N> operator ~() const
{
bitset<N> temp;
for (size_t i = 0; i < ARRAY_SIZE; ++i)
{
temp[i] = ~data[i];
}
bitset<N> temp(*this);
temp.invert();
return temp;
}
@ -264,22 +234,9 @@ namespace etl
//*************************************************************************
bitset<N> operator<<(size_t shift) const
{
bitset<N> temp;
bitset<N> 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<N>& 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<N> operator>>(size_t shift) const
{
bitset<N> temp;
bitset<N> 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<N>& 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<N>& other)
{
for (size_t i = 0; i < ARRAY_SIZE; ++i)
{
std::swap(data, other.data);
}
}
//*************************************************************************
/// operator ==
//*************************************************************************
friend bool operator == (const bitset<N>& lhs, const bitset<N>& 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:

181
ibitset.h
View File

@ -33,6 +33,7 @@ SOFTWARE.
#include <algorithm>
#include <stdint.h>
#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<unsigned long long>::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: