mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Moved more code to base class.
This commit is contained in:
parent
8f7b16dc9c
commit
6f7e26523e
173
bitset.h
173
bitset.h
@ -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
181
ibitset.h
@ -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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user