GY-63_MS5611/libraries/Set/Set.cpp

409 lines
7.1 KiB
C++
Raw Normal View History

2014-11-18 13:28:12 -05:00
//
2020-11-27 05:33:55 -05:00
// FILE: set.cpp
2014-11-18 13:28:12 -05:00
// AUTHOR: Rob Tillaart
2021-12-28 04:38:33 -05:00
// VERSION: 0.2.5
2020-11-27 05:33:55 -05:00
// DATE: 2014-09-11
2014-11-18 13:28:12 -05:00
// PURPOSE: SET library for Arduino
2020-11-27 05:33:55 -05:00
// URL: https://github.com/RobTillaart/SET
2014-11-18 13:28:12 -05:00
//
2021-01-29 06:31:58 -05:00
// HISTORY:
2021-12-28 04:38:33 -05:00
// 0.2.5 2021-12-28 update library.json, readme, license, minor edits
// 0.2.4 2021-05-06 getNth(n)
// 0.2.3 2021-05-05 Add addAll (256 elements) + setCurrent
// 0.2.2 2021-01-07 Arduino-CI, unit test
// 0.2.1 2020-06-19 fix library.json
// 0.2.0 2020-05-02 refactored, removed pre 1.0 support
// 0.1.11 2017-07-16 fix count() --> 16 bit when set is full !
// 0.1.10 2017-07-16 performance refactor. isEmpty()
// 0.1.09 2015-07-12 const + constructor
// 0.1.08 memset for clr()
2021-01-29 06:31:58 -05:00
// 0.1.07 faster first/next/last/prev; interface
// 0.1.06 added flag to constructor to optimize +,-,*,
// set -> Set
// 0.1.05 bug fixing + performance a.o. count()
// 0.1.04 support for + - *, some optimizations
// 0.1.03 changed &= to *= to follow Pascal conventions
// 0.1.02 documentation
// 0.1.01 extending/refactor etc (09/11/2014)
// 0.1.00 initial version by Rob Tillaart (09/11/2014)
2014-11-18 13:28:12 -05:00
//
2021-01-29 06:31:58 -05:00
2020-11-27 05:33:55 -05:00
#include "set.h"
2014-11-18 13:28:12 -05:00
2021-12-28 04:38:33 -05:00
2014-11-18 13:28:12 -05:00
/////////////////////////////////////////////////////
//
// CONSTRUCTORS
//
Set::Set(const bool clear)
2014-11-18 13:28:12 -05:00
{
if (clear)
{
clr();
}
_current = -1;
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
Set::Set(const Set &t)
2014-11-18 13:28:12 -05:00
{
2020-11-27 05:33:55 -05:00
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
_mem[i] = t._mem[i];
}
_current = -1;
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2014-11-18 13:28:12 -05:00
/////////////////////////////////////////////////////
//
// METHODS
//
2021-12-28 04:38:33 -05:00
void Set::add(const uint8_t value)
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
uint8_t idx = value / 8;
_mem[idx] |= _masks[value & 7];
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2021-12-28 04:38:33 -05:00
void Set::sub(const uint8_t value)
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
uint8_t idx = value / 8;
_mem[idx] &= ~_masks[value & 7];
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2021-12-28 04:38:33 -05:00
void Set::invert(const uint8_t value)
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
uint8_t idx = value / 8;
_mem[idx] ^= _masks[value & 7];
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2021-05-05 07:46:09 -04:00
void Set::addAll()
{
memset(_mem, 0xFF, 32);
}
2021-12-28 04:38:33 -05:00
bool Set::has(const uint8_t value)
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
uint8_t idx = value / 8;
return (_mem[idx] & _masks[value & 7]) > 0;
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2017-07-16 14:09:23 -04:00
uint16_t Set::count() const
2014-11-18 13:28:12 -05:00
{
2017-07-16 14:09:23 -04:00
uint16_t cnt = 0;
2021-12-28 04:38:33 -05:00
2020-11-27 05:33:55 -05:00
uint8_t i = 32;
do
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
// Kerningham bit count trick
2020-11-27 05:33:55 -05:00
uint8_t b = _mem[--i];
2014-11-18 13:28:12 -05:00
for (; b; cnt++)
{
b &= b-1;
}
}
2020-11-27 05:33:55 -05:00
while (i != 0);
2014-11-18 13:28:12 -05:00
return cnt;
}
2021-01-29 06:31:58 -05:00
void Set::clear()
2014-11-18 13:28:12 -05:00
{
memset(_mem, 0, 32);
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2014-11-18 13:28:12 -05:00
void Set::invert()
{
2020-11-27 05:33:55 -05:00
uint8_t i = 32;
do
2014-11-18 13:28:12 -05:00
{
2020-11-27 05:33:55 -05:00
_mem[--i] ^= 0xFF;
2021-12-28 04:38:33 -05:00
}
2020-11-27 05:33:55 -05:00
while (i != 0);
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
bool Set::isEmpty()
{
2020-11-27 05:33:55 -05:00
uint8_t i = 32;
do
{
2020-11-27 05:33:55 -05:00
if (_mem[--i] > 0) return false;
2021-12-28 04:38:33 -05:00
}
2020-11-27 05:33:55 -05:00
while (i != 0);
return true;
}
2021-01-29 06:31:58 -05:00
2017-07-16 14:09:23 -04:00
bool Set::isFull()
{
2021-12-28 04:38:33 -05:00
// check two elements per loop
2020-11-27 05:33:55 -05:00
// is faster for full sets but slower for empty set.
2021-12-28 04:38:33 -05:00
// footprint is ~25 bytes larger
// overall performance gain
2020-11-27 05:33:55 -05:00
uint8_t i = 32;
do
2017-07-16 14:09:23 -04:00
{
2020-11-27 05:33:55 -05:00
if ((_mem[--i]) != 255) return false;
2021-12-28 04:38:33 -05:00
}
2020-11-27 05:33:55 -05:00
while (i != 0);
2017-07-16 14:09:23 -04:00
return true;
}
2021-01-29 06:31:58 -05:00
2021-12-28 04:38:33 -05:00
int Set::setCurrent(const uint8_t current)
2021-05-05 07:46:09 -04:00
{
_current = -1;
2021-12-28 04:38:33 -05:00
if (has(current))
2021-05-05 07:46:09 -04:00
{
2021-12-28 04:38:33 -05:00
_current = current;
2021-05-05 07:46:09 -04:00
}
return _current;
}
2014-11-18 13:28:12 -05:00
int Set::first()
{
2020-11-27 05:33:55 -05:00
if (has(0))
{
_current = 0;
return _current;
}
return findNext(0, 0);
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2014-11-18 13:28:12 -05:00
int Set::next()
{
if (_current & 0x8000) return -1; // if current == -1
_current++;
uint8_t p = (uint8_t)_current / 8;
uint8_t q = (uint8_t)_current & 7;
return findNext(p, q);
}
2020-11-27 05:33:55 -05:00
// pointer math version ~12% faster but not for previous
// needs investigation.
// int Set::findNext(const uint8_t p, const uint8_t q)
// {
2021-12-28 04:38:33 -05:00
// uint8_t * pp = &_mem[p];
// uint8_t mask = 1 << q;
// uint8_t j = q;
// do
// {
// if (*pp != 0)
// {
2020-11-27 05:33:55 -05:00
// while (j < 8)
// {
// if (*pp & mask)
// {
// _current = (pp - _mem) * 8 + j;
// return _current;
// }
// mask <<= 1;
2021-12-28 04:38:33 -05:00
// j++;
// }
// }
// j = 0;
// mask = 1;
// pp++;
// }
// while (pp != &_mem[31]);
2020-11-27 05:33:55 -05:00
// _current = -1;
// return _current;
// }
2021-01-29 06:31:58 -05:00
int Set::findNext(const uint8_t p, uint8_t q)
{
for (uint8_t i = p; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
uint8_t b = _mem[i];
if (b != 0)
2014-11-18 13:28:12 -05:00
{
2021-12-28 04:38:33 -05:00
uint8_t mask = 1 << q; // _masks[q]
for (uint8_t j = q; j < 8; j++)
2014-11-18 13:28:12 -05:00
{
if (b & mask)
{
_current = i * 8 + j;
return _current;
}
mask <<= 1;
2014-11-18 13:28:12 -05:00
}
}
q = 0;
2014-11-18 13:28:12 -05:00
}
_current = -1;
return _current;
}
2021-01-29 06:31:58 -05:00
2014-11-18 13:28:12 -05:00
int Set::prev()
{
if (_current & 0x8000) return -1;
_current--;
uint8_t p = (uint8_t)_current / 8;
uint8_t q = (uint8_t)_current & 7;
return findPrev(p, q);
2014-11-18 13:28:12 -05:00
}
2021-01-29 06:31:58 -05:00
2014-11-18 13:28:12 -05:00
int Set::last()
{
2020-11-27 05:33:55 -05:00
if (has(255))
{
_current = 255;
return _current;
}
return findPrev(31, 7);
}
2021-01-29 06:31:58 -05:00
2021-05-08 03:51:40 -04:00
int Set::getNth(const uint8_t n)
{
if (n == 0) return -1;
if (n == 1) return first();
_current = first();
int i = 1;
while ((_current > -1) && (i < n))
{
_current = next();
i++;
}
return _current;
}
int Set::findPrev(const uint8_t p, uint8_t q)
{
uint8_t m = 1 << q;
for (uint8_t i = p; i != 255; --i) // uint < 0
2014-11-18 13:28:12 -05:00
{
uint8_t b = _mem[i];
if (b != 0)
2014-11-18 13:28:12 -05:00
{
uint8_t mask = m;
for (uint8_t j = q; j != 255; --j)
{
if (b & mask)
{
_current = i * 8 + j;
return _current;
}
mask >>= 1;
}
2014-11-18 13:28:12 -05:00
}
2020-11-27 05:33:55 -05:00
m = 128; // 1 << 7;
q = 7;
2014-11-18 13:28:12 -05:00
}
_current = -1;
2014-11-18 13:28:12 -05:00
return _current;
}
/////////////////////////////////////////////////////
//
// OPERATORS
//
Set Set::operator + (const Set &t) // union
2014-11-18 13:28:12 -05:00
{
Set s(false);
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
s._mem[i] = this->_mem[i] | t._mem[i];
}
return s;
}
2021-01-29 06:31:58 -05:00
Set Set::operator - (const Set &t) // diff
2014-11-18 13:28:12 -05:00
{
Set s(false);
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
s._mem[i] = this->_mem[i] & ~t._mem[i];
}
return s;
}
2021-01-29 06:31:58 -05:00
Set Set::operator * (const Set &t) // intersection
2014-11-18 13:28:12 -05:00
{
Set s(false);
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
s._mem[i] = this->_mem[i] & t._mem[i];
}
return s;
}
2021-01-29 06:31:58 -05:00
void Set::operator += (const Set &t) // union
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
_mem[i] |= t._mem[i];
}
}
2021-01-29 06:31:58 -05:00
void Set::operator -= (const Set &t) // diff
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
_mem[i] &= ~t._mem[i];
}
}
2021-01-29 06:31:58 -05:00
void Set::operator *= (const Set &t) // intersection
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
_mem[i] &= t._mem[i];
}
}
2021-01-29 06:31:58 -05:00
bool Set::operator == (const Set &t) const // equal
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
if (_mem[i] != t._mem[i]) return false;
}
return true;
}
2021-01-29 06:31:58 -05:00
bool Set::operator != (const Set &t) const // not equal
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
if (_mem[i] != t._mem[i]) return true;
}
return false;
}
2021-01-29 06:31:58 -05:00
bool Set::operator <= (const Set &t) const // subSet
2014-11-18 13:28:12 -05:00
{
for (uint8_t i = 0; i < 32; i++)
2014-11-18 13:28:12 -05:00
{
if ((_mem[i] & ~t._mem[i]) > 0) return false;
}
return true;
}
2020-11-27 05:33:55 -05:00
2021-12-28 04:38:33 -05:00
2020-11-27 05:33:55 -05:00
// -- END OF FILE --
2021-12-28 04:38:33 -05:00