BitSet building convenience
Allow set()/clear()/flip() to be chained. Support c++11 initializer lists.
This commit is contained in:
@@ -55,6 +55,19 @@ namespace epics { namespace pvData {
|
||||
words.reserve((nbits == 0) ? 1 : WORD_INDEX(nbits-1) + 1);
|
||||
}
|
||||
|
||||
#if __cplusplus>=201103L
|
||||
BitSet::BitSet(std::initializer_list<uint32> I)
|
||||
{
|
||||
// optimistically guess that highest bit is last (not required)
|
||||
words.reserve((I.size() == 0) ? 1 : WORD_INDEX(*(I.end()-1)) + 1);
|
||||
|
||||
for(uint32 idx : I)
|
||||
{
|
||||
set(idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BitSet::~BitSet() {}
|
||||
|
||||
void BitSet::recalculateWordsInUse() {
|
||||
@@ -76,7 +89,7 @@ namespace epics { namespace pvData {
|
||||
ensureCapacity(wordIndex+1);
|
||||
}
|
||||
|
||||
void BitSet::flip(uint32 bitIndex) {
|
||||
BitSet& BitSet::flip(uint32 bitIndex) {
|
||||
|
||||
uint32 wordIdx = WORD_INDEX(bitIndex);
|
||||
expandTo(wordIdx);
|
||||
@@ -84,25 +97,27 @@ namespace epics { namespace pvData {
|
||||
words[wordIdx] ^= (((uint64)1) << WORD_OFFSET(bitIndex));
|
||||
|
||||
recalculateWordsInUse();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BitSet::set(uint32 bitIndex) {
|
||||
BitSet& BitSet::set(uint32 bitIndex) {
|
||||
|
||||
uint32 wordIdx = WORD_INDEX(bitIndex);
|
||||
expandTo(wordIdx);
|
||||
|
||||
words[wordIdx] |= (((uint64)1) << WORD_OFFSET(bitIndex));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BitSet::clear(uint32 bitIndex) {
|
||||
BitSet& BitSet::clear(uint32 bitIndex) {
|
||||
|
||||
uint32 wordIdx = WORD_INDEX(bitIndex);
|
||||
if (wordIdx >= words.size())
|
||||
return;
|
||||
if (wordIdx < words.size()) {
|
||||
words[wordIdx] &= ~(((uint64)1) << WORD_OFFSET(bitIndex));
|
||||
|
||||
words[wordIdx] &= ~(((uint64)1) << WORD_OFFSET(bitIndex));
|
||||
|
||||
recalculateWordsInUse();
|
||||
recalculateWordsInUse();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void BitSet::set(uint32 bitIndex, bool value) {
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#ifndef BITSET_H
|
||||
#define BITSET_H
|
||||
|
||||
#if __cplusplus>=201103L
|
||||
# include <initializer_list>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <pv/pvType.h>
|
||||
@@ -65,6 +69,16 @@ namespace epics { namespace pvData {
|
||||
*/
|
||||
BitSet(uint32 nbits);
|
||||
|
||||
#if __cplusplus>=201103L
|
||||
/** Initialize from a list of indicies
|
||||
@code
|
||||
BitSet X({1, 5});
|
||||
assert(X.get(1) && X.get(5));
|
||||
@endcode
|
||||
*/
|
||||
BitSet(std::initializer_list<uint32> I);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
@@ -76,21 +90,21 @@ namespace epics { namespace pvData {
|
||||
*
|
||||
* @param bitIndex the index of the bit to flip
|
||||
*/
|
||||
void flip(uint32 bitIndex);
|
||||
BitSet& flip(uint32 bitIndex);
|
||||
|
||||
/**
|
||||
* Sets the bit at the specified index to @c true.
|
||||
*
|
||||
* @param bitIndex a bit index
|
||||
*/
|
||||
void set(uint32 bitIndex);
|
||||
BitSet& set(uint32 bitIndex);
|
||||
|
||||
/**
|
||||
* Sets the bit specified by the index to @c false.
|
||||
*
|
||||
* @param bitIndex the index of the bit to be cleared
|
||||
*/
|
||||
void clear(uint32 bitIndex);
|
||||
BitSet& clear(uint32 bitIndex);
|
||||
|
||||
/**
|
||||
* Sets the bit at the specified index to the specified value.
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
|
||||
#include <pv/bitSet.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
#include <pv/pvUnitTest.h>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace epics::pvData;
|
||||
using std::string;
|
||||
|
||||
@@ -37,6 +40,18 @@ static string toString(BitSet& bitSet)
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void testInitialize()
|
||||
{
|
||||
testDiag("testInitialize()");
|
||||
#if __cplusplus>=201103L
|
||||
testOk1(BitSet().size()==0);
|
||||
testOk1(BitSet({}).size()==0);
|
||||
testEqual(BitSet().set(1).set(5).set(500), BitSet({1, 5, 500}));
|
||||
#else
|
||||
testSkip(3, "Not c++11");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void testGetSetClearFlip()
|
||||
{
|
||||
testDiag("testGetSetClearFlip... ");
|
||||
@@ -292,9 +307,12 @@ static void testSerialize()
|
||||
#undef TOFRO
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testBitSet)
|
||||
{
|
||||
testPlan(87);
|
||||
testPlan(90);
|
||||
testInitialize();
|
||||
testGetSetClearFlip();
|
||||
testOperators();
|
||||
testLogical();
|
||||
|
||||
Reference in New Issue
Block a user