17 #define epicsExportSharedSymbols 27 #define ADDRESS_BITS_PER_WORD 6u 28 #define BITS_PER_WORD (1u << ADDRESS_BITS_PER_WORD) 29 #define BYTES_PER_WORD sizeof(uint64) 30 #define BIT_INDEX_MASK (BITS_PER_WORD - 1u) 33 #define WORD_MASK ~((uint64)0) 36 #define WORD_INDEX(bitn) ((bitn)>>ADDRESS_BITS_PER_WORD) 38 #define WORD_OFFSET(bitn) ((bitn)&BIT_INDEX_MASK) 42 #define CHECK_POST() assert(words.empty() || words.back()!=0) 44 namespace epics {
namespace pvData {
48 return BitSet::shared_pointer(
new BitSet(nbits));
55 words.reserve((nbits == 0) ? 1 :
WORD_INDEX(nbits-1) + 1);
58 #if __cplusplus>=201103L 62 words.reserve((I.size() == 0) ? 1 :
WORD_INDEX(*(I.end()-1)) + 1);
73 void BitSet::recalculateWordsInUse() {
75 size_t nsize = words.size();
76 for(; nsize; nsize--) {
84 void BitSet::ensureCapacity(
uint32 wordsRequired) {
85 words.resize(
std::max(words.size(), (size_t)wordsRequired), 0);
88 void BitSet::expandTo(
uint32 wordIndex) {
89 ensureCapacity(wordIndex+1);
99 recalculateWordsInUse();
115 if (wordIdx < words.size()) {
118 recalculateWordsInUse();
132 return ((wordIdx < words.size())
143 if (i == 0)
return 64;
145 y = (
uint32)i;
if (y != 0) { n = n -32; x = y; }
else x = (
uint32)(i>>32);
146 y = x <<16;
if (y != 0) { n = n -16; x = y; }
147 y = x << 8;
if (y != 0) { n = n - 8; x = y; }
148 y = x << 4;
if (y != 0) { n = n - 4; x = y; }
149 y = x << 2;
if (y != 0) { n = n - 2; x = y; }
150 return n - ((x << 1) >> 31);
155 i = i - ((i >> 1) & 0x5555555555555555LL);
156 i = (i & 0x3333333333333333LL) + ((i >> 2) & 0x3333333333333333LL);
157 i = (i + (i >> 4)) & 0x0f0f0f0f0f0f0f0fLL;
161 return (
uint32)(i & 0x7f);
167 if (u >= words.size())
175 if (++u == words.size())
185 if (u >= words.size())
193 if (++u == words.size())
200 return words.empty();
205 for (
uint32 i = 0; i < words.size(); i++)
206 sum += bitCount(words[i]);
216 size_t nwords =
std::min(words.size(),
set.words.size());
217 for(
size_t i=0; i<nwords; i++) {
218 if(words[i] &
set.words[i])
225 return !words.empty() || !
set.words.empty();
230 if (
this == &
set)
return *
this;
233 words.resize(
std::min(words.size(),
set.words.size()), 0);
235 for(
size_t i=0, e=words.size(); i<e; i++)
236 words[i] &=
set.words[i];
238 recalculateWordsInUse();
244 if (
this == &
set)
return *
this;
247 words.resize(
std::max(words.size(),
set.words.size()), 0);
250 for(
size_t i=0, e=
set.words.size(); i<e; i++)
251 words[i] |=
set.words[i];
259 words.resize(
std::max(words.size(),
set.words.size()), 0);
261 for(
size_t i=0, e=
set.words.size(); i<e; i++)
262 words[i] ^=
set.words[i];
264 recalculateWordsInUse();
279 words.swap(
set.words);
284 const size_t andlen =
std::min(set1.words.size(), set2.words.size());
285 words.resize(
std::max(words.size(), andlen), 0);
288 for (
uint32 i = 0; i < andlen; i++)
289 words[i] |= (set1.words[i] & set2.words[i]);
291 recalculateWordsInUse();
299 if (words.size() !=
set.words.size())
303 for (
uint32 i = 0; i < words.size(); i++)
304 if (words[i] !=
set.words[i])
312 return !(*
this ==
set);
324 for (
uint64 x = words[n - 1]; x != 0; x >>= 8)
331 for (
uint32 i = 0; i < n; i++)
334 if (n < words.size())
335 for (
uint64 x = words[words.size() - 1]; x != 0; x >>= 8)
344 words.resize(wordsInUse);
354 words[i++] = buffer->
getLong();
356 for (
uint32 j = i; j < wordsInUse; j++)
359 for (
uint32 remaining = (bytes - longs * 8), j = 0; j < remaining; j++)
360 words[i] |= (buffer->
getByte() & 0xffLL) << (8 * j);
362 recalculateWordsInUse();
373 do { o <<
", " <<
i; }
while (++i < endOfRun);
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *flusher)
static BitSetPtr create(uint32 nbits)
EPICS_ALWAYS_INLINE int8 getByte()
bool get(uint32 bitIndex) const
TODO only here because of the Lockable.
static void writeSize(std::size_t s, ByteBuffer *buffer, SerializableControl *flusher)
BitSet & operator=(const BitSet &set)
static std::size_t readSize(ByteBuffer *buffer, DeserializableControl *control)
#define WORD_OFFSET(bitn)
Callback class for deserialization.
bool operator!=(const BitSet &set) const
std::ostream & operator<<(std::ostream &o, const Field &f)
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher) const
bool operator==(const BitSet &set) const
int32 nextClearBit(uint32 fromIndex) const
BitSet & flip(uint32 bitIndex)
APIs for the epicsMutex mutual exclusion semaphore.
EPICS_ALWAYS_INLINE void putByte(int8 value)
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
int32 nextSetBit(uint32 fromIndex) const
bool logical_and(const BitSet &other) const
Returns true if any bit is set in both *this and other.
bool logical_or(const BitSet &other) const
Returns true if any bit is set in both *this or other.
BitSet & operator|=(const BitSet &set)
void or_and(const BitSet &set1, const BitSet &set2)
EPICS_ALWAYS_INLINE int64 getLong()
BitSet & operator^=(const BitSet &set)
void swap(BitSet &set)
Swap contents.
virtual void ensureBuffer(std::size_t size)=0
Callback class for serialization.
uint32 cardinality() const
BitSet & set(uint32 bitIndex)
virtual void ensureData(std::size_t size)=0
EPICS_ALWAYS_INLINE void putLong(int64 value)
BitSet & operator&=(const BitSet &set)