bitSetI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2018-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
29 
30 inline constexpr Foam::bitSet::bitSet() noexcept
31 :
32  PackedList<1>()
33 {}
34 
35 
36 inline Foam::bitSet::bitSet(const label n)
37 :
38  PackedList<1>(n)
39 {}
40 
41 
42 inline Foam::bitSet::bitSet(const label n, const bool val)
43 :
44  bitSet(n)
45 {
46  if (val) fill(val);
47 }
48 
49 
50 inline Foam::bitSet::bitSet(const bitSet& bitset)
51 :
52  PackedList<1>(bitset)
53 {}
54 
55 
57 :
58  PackedList<1>(std::move(bitset))
59 {}
60 
61 
63 :
64  bitSet()
65 {
66  assign(bools);
67 }
68 
69 
70 inline Foam::bitSet::bitSet(const label n, const labelUList& locations)
71 :
72  bitSet(n)
73 {
74  setMany(locations.begin(), locations.end());
75 }
76 
77 
78 template<class Addr>
80 (
81  const label n,
82  const IndirectListBase<label, Addr>& locations
83 )
84 :
86 {
87  setMany(locations.begin(), locations.end());
88 }
89 
90 
92 (
93  const label n,
94  std::initializer_list<label> locations
95 )
96 :
97  bitSet(n)
98 {
99  setMany(locations.begin(), locations.end());
100 }
101 
102 
103 inline Foam::bitSet::bitSet(const labelUList& locations)
104 :
105  bitSet()
106 {
107  setMany(locations.begin(), locations.end());
108 }
109 
110 
111 template<class Addr>
113 (
114  const IndirectListBase<label, Addr>& locations
115 )
116 :
117  bitSet()
118 {
119  setMany(locations.begin(), locations.end());
120 }
121 
122 
124 {
125  return autoPtr<bitSet>::New(*this);
126 }
127 
128 
129 // * * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * * //
130 
132 (
133  bitSet* parent,
134  const label index
135 )
136 :
137  PackedList<1>::reference(parent, index)
138 {}
139 
140 
141 inline void Foam::bitSet::reference::flip()
142 {
143  const unsigned int mask = (max_value << shift_);
144  ref_ ^= mask;
145 }
146 
147 
148 inline void Foam::bitSet::reference::operator=
149 (
150  const reference& other
151 )
152 {
153  // Accepts self-assignment
154  set(other.get());
155 }
156 
157 
158 inline void Foam::bitSet::reference::operator=
159 (
160  const unsigned int val
161 )
162 {
163  set(val);
164 }
165 
166 
167 inline Foam::bitSet::reference::operator unsigned int () const
168 {
169  return get();
170 }
171 
172 
173 // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
174 
175 inline Foam::bitSet::const_iterator::const_iterator() noexcept
176 :
177  set_(nullptr),
178  pos_(-1)
179 {}
180 
181 
182 inline Foam::bitSet::const_iterator::const_iterator(const bitSet* parent)
183 :
184  set_(parent),
185  pos_(set_->find_first())
186 {}
187 
188 
189 inline Foam::bitSet::const_iterator::const_iterator
190 (
191  const bitSet* parent,
192  label pos
193 )
194 :
195  set_(parent),
196  pos_(set_->find_next(pos-1))
197 {}
198 
200 inline Foam::label Foam::bitSet::const_iterator::operator*() const noexcept
201 {
202  return pos_;
203 }
204 
205 
207 {
208  pos_ = set_->find_next(pos_);
209  return *this;
210 }
211 
212 
213 inline bool Foam::bitSet::const_iterator::operator==
214 (
215  const const_iterator& iter
216 ) const noexcept
217 {
218  return (iter.pos_ == pos_);
219 }
220 
221 
222 inline bool Foam::bitSet::const_iterator::operator!=
223 (
224  const const_iterator& iter
225 ) const noexcept
226 {
227  return (iter.pos_ != pos_);
228 }
229 
232 {
233  return const_iterator(this);
234 }
235 
238 {
239  return const_iterator(this);
240 }
241 
244 {
245  return const_iterator(this, pos);
246 }
247 
250 {
251  return const_iterator(this, pos);
252 }
253 
256 {
257  return const_iterator();
258 }
259 
262 {
263  return const_iterator();
264 }
265 
266 
267 inline Foam::label Foam::bitSet::find_first() const
268 {
269  const label blocki = first_block();
270 
271  if (blocki >= 0)
272  {
273  label pos = (blocki * elem_per_block);
274 
275  // Detect first '1' bit within the block
276 
277  for
278  (
279  unsigned int blockval = blocks_[blocki];
280  blockval;
281  blockval >>= 1u
282  )
283  {
284  if (blockval & 1u)
285  {
286  return pos;
287  }
288  ++pos;
289  }
290  }
291 
292  return -1;
293 }
294 
295 
296 inline Foam::label Foam::bitSet::find_first_not() const
297 {
298  const label blocki = first_not_block();
299 
300  if (blocki >= 0)
301  {
302  label pos = (blocki * elem_per_block);
303 
304  // Detect first '0' bit within the block (check the complement)
305 
306  // No special masking for the final block, that was already checked
307  // in the first_not_block() call.
308 
309  for
310  (
311  unsigned int blockval = ~(blocks_[blocki]);
312  blockval;
313  blockval >>= 1u
314  )
315  {
316  if (blockval & 1u)
317  {
318  return pos;
319  }
320  ++pos;
321  }
322  }
323 
324  return -1;
325 }
326 
327 
328 inline Foam::label Foam::bitSet::find_last() const
329 {
330  // Process block-wise, detecting any '1' bits
331 
332  for (label blocki = num_blocks(size())-1; blocki >= 0; --blocki)
333  {
334  unsigned int blockval = blocks_[blocki];
335 
336  if (blockval)
337  {
338  label pos = (blocki * elem_per_block) - 1;
339 
340  while (blockval)
341  {
342  blockval >>= 1u;
343  ++pos;
344  }
345 
346  return pos;
347  }
348  }
349 
350  return -1;
351 }
352 
353 
354 inline Foam::label Foam::bitSet::find_next(label pos) const
355 {
356  ++pos;
357  if (pos < 0 || pos >= size())
358  {
359  return -1;
360  }
361 
362  // The corresponding block/offset
363  label blocki = pos / elem_per_block;
364  unsigned int off = pos % elem_per_block;
365 
366  for
367  (
368  unsigned int blockval = (blocks_[blocki] >> off);
369  blockval;
370  blockval >>= 1u
371  )
372  {
373  if (blockval & 1u)
374  {
375  return pos;
376  }
377  ++pos;
378  }
379 
380  // Normal block-wise search. Starting at the next block
381 
382  const label nblocks = num_blocks(size());
383  for (++blocki; blocki < nblocks; ++blocki)
384  {
385  label pos = (blocki * elem_per_block);
386 
387  for
388  (
389  unsigned int blockval = blocks_[blocki];
390  blockval;
391  blockval >>= 1u
392  )
393  {
394  if (blockval & 1u)
395  {
396  return pos;
397  }
398  ++pos;
399  }
400  }
402  return -1;
403 }
404 
405 
406 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
408 inline const Foam::bitSet& Foam::bitSet::null()
409 {
410  return NullObjectRef<bitSet>();
411 }
412 
413 
414 inline bool Foam::bitSet::all() const
415 {
416  if (empty()) return true; // SIC. boost convention
417  return (-1 == first_not_block());
418 }
419 
421 inline bool Foam::bitSet::any() const
422 {
423  return (-1 != first_block());
424 }
425 
427 inline bool Foam::bitSet::none() const
428 {
429  return (-1 == first_block());
430 }
431 
432 
433 inline unsigned int Foam::bitSet::count(const bool on) const
434 {
435  unsigned int total = 0;
436 
437  const label nblocks = num_blocks(size());
438 
439  for (label blocki = 0; blocki < nblocks; ++blocki)
440  {
441  total += BitOps::bit_count(blocks_[blocki]);
442  }
443 
444  if (!on)
445  {
446  // Return the number of bits that are OFF.
447  return (unsigned(size()) - total);
448  }
449 
450  return total;
451 }
452 
455 {
456  return toc();
457 }
458 
459 
460 inline void Foam::bitSet::resize_last()
461 {
462  const label pos = find_last();
463 
464  if (pos >= 0)
465  {
466  resize(pos+1);
467  }
468  else
469  {
470  clear();
471  }
472 }
473 
475 inline void Foam::bitSet::swap(bitSet& bitset)
476 {
478 }
479 
482 {
484 }
485 
486 
487 inline void Foam::bitSet::fill(const bool val)
488 {
489  if (empty())
490  {
491  return; // Trivial case
492  }
493 
494  const label nblocks = num_blocks(size());
495 
496  // Fill value for complete blocks
497  const unsigned int blockval = (val ? ~0u : 0u);
498 
499  for (label blocki=0; blocki < nblocks; ++blocki)
500  {
501  blocks_[blocki] = blockval;
502  }
503 
504  if (val)
505  {
507  }
508 }
509 
511 inline void Foam::bitSet::set(const bitSet& bitset)
512 {
513  orEq(bitset);
514 }
515 
516 
517 inline Foam::label Foam::bitSet::set(const labelUList& locations)
518 {
519  return setMany(locations.begin(), locations.end());
520 }
521 
522 
523 template<class Addr>
524 inline Foam::label Foam::bitSet::set
525 (
527 )
528 {
529  return setMany(locations.begin(), locations.end());
530 }
531 
532 
533 inline Foam::label Foam::bitSet::unset(const labelUList& locations)
534 {
535  return unset(locations.begin(), locations.end());
536 }
537 
538 
539 template<class Addr>
540 inline Foam::label Foam::bitSet::unset
541 (
543 )
544 {
545  return unset(locations.begin(), locations.end());
546 }
547 
549 inline Foam::bitSet& Foam::bitSet::unset(const bitSet& other)
550 {
551  return minusEq(other);
552 }
553 
554 
555 inline void Foam::bitSet::flip()
556 {
557  if (size())
558  {
559  const label nblocks = num_blocks(size());
560 
561  for (label blocki=0; blocki < nblocks; ++blocki)
562  {
563  blocks_[blocki] = ~(blocks_[blocki]);
564  }
566  }
567 }
568 
569 
570 inline void Foam::bitSet::flip(const label i)
571 {
572  if (i >= 0 && i < size())
573  {
574  reference(this, i).flip();
575  }
576 }
577 
578 
579 inline Foam::bitSet& Foam::bitSet::bound(const label maxSize)
580 {
581  if (maxSize < size())
582  {
583  resize(maxSize);
584  }
585 
586  return *this;
587 }
588 
590 inline Foam::bitSet& Foam::bitSet::bound(const bitSet& other)
591 {
592  return bound(other.size());
593 }
594 
595 
596 inline Foam::bitSet& Foam::bitSet::extend(const label minSize)
597 {
598  if (size() < minSize)
599  {
600  resize(minSize);
601  }
602 
603  return *this;
604 }
605 
606 
607 inline Foam::bitSet& Foam::bitSet::extend(const bitSet& other)
608 {
609  return extend(other.size());
610 }
611 
612 
613 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
615 inline bool Foam::bitSet::operator()(const label pos) const
616 {
617  return test(pos);
618 }
619 
621 inline unsigned int Foam::bitSet::operator[](const label i) const
622 {
623  return get(i);
624 }
625 
626 
628 {
629  #ifdef FULLDEBUG
630  checkIndex(i);
631  #endif
632  return reference(this, i);
633 }
634 
635 
637 {
639  return *this;
640 }
641 
642 
644 {
645  transfer(bitset);
646  return *this;
647 }
648 
649 
650 inline Foam::bitSet& Foam::bitSet::operator=(const bool val)
651 {
652  fill(val);
653  return *this;
654 }
655 
657 inline Foam::bitSet& Foam::bitSet::operator&=(const bitSet& other)
658 {
659  return andEq(other);
660 }
661 
663 inline Foam::bitSet& Foam::bitSet::operator|=(const bitSet& other)
664 {
665  return orEq(other);
666 }
667 
669 inline Foam::bitSet& Foam::bitSet::operator^=(const bitSet& other)
670 {
671  return xorEq(other);
672 }
673 
674 
675 inline Foam::bitSet& Foam::bitSet::operator-=(const bitSet& other)
676 {
677  return minusEq(other);
678 }
679 
680 
681 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
682 
684 {
685  bitSet result(bitset);
686  result.flip();
687  return result;
688 }
689 
690 
691 inline Foam::bitSet Foam::operator&(const bitSet& a, const bitSet& b)
692 {
693  bitSet result(a);
694  result &= b;
695 
696  result.resize_last();
697  return result;
698 }
699 
700 
701 inline Foam::bitSet Foam::operator|(const bitSet& a, const bitSet& b)
702 {
703  bitSet result(a);
704  result |= b;
705 
706  result.resize_last();
707  return result;
708 }
709 
710 
711 inline Foam::bitSet Foam::operator^(const bitSet& a, const bitSet& b)
712 {
713  bitSet result(a);
714  result ^= b;
715 
716  result.resize_last();
717  return result;
718 }
719 
720 
721 inline Foam::bitSet Foam::operator-(const bitSet& a, const bitSet& b)
722 {
723  bitSet result(a);
724  result |= b;
725 
726  result.resize_last();
727  return result;
728 }
729 
730 
731 // ************************************************************************* //
A reference supporting read/write access to an entry.
Definition: bitSet.H:622
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:426
const_iterator & operator++()
Move to the next on position.
Definition: bitSetI.H:199
bitSet & orEq(const bitSet &other)
The set logical OR.
Definition: bitSet.C:122
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:504
label setMany(InputIter first, InputIter last)
Set the locations listed by the iterator range, auto-vivify entries if needed.
void fill(const bool val)
Assign all entries to the given value.
Definition: bitSetI.H:480
bitSet operator~(const bitSet &bitset)
Bitset complement, returns a copy of the bitset with all its bits flipped.
Definition: bitSetI.H:676
label find_last() const
Locate the last bit set.
Definition: bitSetI.H:321
void flip()
Invert all bits in the addressable region.
Definition: bitSetI.H:548
reference(bitSet *parent, const label index)
Construct by taking reference of block from within the list and the specified index.
Definition: bitSetI.H:125
labelList sortedToc() const
The indices of the on bits as a sorted labelList.
Definition: bitSetI.H:447
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:260
bool operator()(const label pos) const
Test value at specified position, same as test()
Definition: bitSetI.H:608
bitSet & operator=(const bitSet &bitset)
Copy assignment.
Definition: bitSetI.H:629
void flip()
Flip the bit at the position, no range-checking.
Definition: bitSetI.H:134
bitSet & minusEq(const bitSet &other)
The set difference.
Definition: bitSet.C:35
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:347
const_iterator begin() const
Iterator set to the position of the first on bit.
Definition: bitSetI.H:224
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
bitSet & xorEq(const bitSet &other)
The set logical XOR.
Definition: bitSet.C:167
unsigned int operator[](const label i) const
Identical to get() - get value at index.
Definition: bitSetI.H:614
bitSet operator|(const bitSet &a, const bitSet &b)
Bitwise-OR of two bitsets.
Definition: bitSetI.H:694
void resize_last()
Resize to include the last on bit only.
Definition: bitSetI.H:453
label find_first_not() const
Locate the first bit that is unset.
Definition: bitSetI.H:289
bool any() const
True if any bits in this bitset are set.
Definition: bitSetI.H:414
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:455
label first_block() const
Find the first block with a &#39;1&#39; bit.
Definition: PackedListI.H:144
dimensionedScalar pos(const dimensionedScalar &ds)
autoPtr< bitSet > clone() const
Clone.
Definition: bitSetI.H:116
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:104
bitSet & unset(const bitSet &other)
Unset (subtract) the bits specified in the other bitset, which is a set difference corresponds to the...
Definition: bitSetI.H:542
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
static const bitSet & null()
Return a null bitSet reference.
Definition: bitSetI.H:401
bitSet & operator^=(const bitSet &other)
Bitwise-XOR operator - retains unique entries.
Definition: bitSetI.H:662
void clear()
Clear the list, i.e. set addressable size to zero.
Definition: PackedListI.H:558
bitSet & operator|=(const bitSet &other)
Bitwise-OR operator - similar to the set() method.
Definition: bitSetI.H:656
void transfer(bitSet &bitset)
Transfer the contents of the argument list into this list and annul the argument list.
Definition: bitSetI.H:474
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:391
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
Definition: bitSet.H:326
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
label first_not_block() const
Find the first block with a &#39;0&#39; bit.
Definition: PackedListI.H:164
const_iterator cend() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:254
const direction noexcept
Definition: Scalar.H:258
constexpr bitSet() noexcept
Default construct an empty, zero-sized bitSet.
Definition: bitSetI.H:23
void assign(Field< Tout > &result, const Field< T1 > &a, const UnaryOp &op)
Populate a field as the result of a unary operation on an input.
Definition: FieldOps.C:28
List< bool > bools(const labelHashSet &locations)
Transform the on locations to a boolList, with true for each non-negative location and false for all ...
Definition: HashOps.C:72
bitSet & andEq(const bitSet &other)
The set logical AND.
Definition: bitSet.C:70
bitSet & operator-=(const bitSet &other)
Remove entries from this list - identical to the unset() method.
Definition: bitSetI.H:668
void swap(PackedList< Width > &rhs)
Swap contents with argument.
Definition: PackedListI.H:656
iterator begin()
Return an iterator at begin of list.
labelList toc() const
The indices of the on bits as a sorted labelList.
Definition: bitSet.C:467
label operator*() const noexcept
Return the current on position.
Definition: bitSetI.H:193
static constexpr block_type max_value
The max value for an element which is also the bit-mask of the individual element.
Definition: PackedList.H:161
iterator end()
Return an iterator at end of list.
bitSet operator^(const bitSet &a, const bitSet &b)
Bitwise-XOR of two bitsets to form a unique bit-set.
Definition: bitSetI.H:704
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedList.H:366
A const_iterator for iterating across on values.
Definition: bitSet.H:676
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
tmp< GeometricField< Type, faPatchField, areaMesh > > operator &(const faMatrix< Type > &, const DimensionedField< Type, areaMesh > &)
unsigned int bit_count(UIntType x)
Count arbitrary number of bits (of an integral type)
Definition: BitOps.H:245
const_iterator cbegin() const
Iterator set to the position of the first on bit.
Definition: bitSetI.H:230
block_container blocks_
The blocks of raw data.
Definition: PackedList.H:203
label n
static constexpr label num_blocks(label numElem) noexcept
Calculate the number of blocks required to _address_ the requested number of elements.
Definition: PackedList.H:175
static constexpr unsigned elem_per_block
The number of elements stored per data block.
Definition: PackedList.H:153
void clear_trailing_bits()
Clear any partial rubbish in the last addressable block.
Definition: PackedListI.H:76
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:435
void transfer(PackedList< Width > &rhs)
Transfer the contents of the argument list into this list and annul the argument list.
Definition: PackedListI.H:669
const_iterator end() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:248
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
void operator=(const PackedList< Width > &list)
Copy assignment.
Definition: PackedListI.H:838
void swap(bitSet &bitset)
Swap contents.
Definition: bitSetI.H:468
bitSet & operator &=(const bitSet &other)
Bitwise-AND all the bits in other with the bits in this bitset.
bitSet & extend(const label minSize)
Ensure that minSize is covered by the bitSet.
Definition: bitSetI.H:589
bool none() const
True if no bits in this bitset are set.
Definition: bitSetI.H:420
bitSet bitset(const labelHashSet &locations)
Transform the on locations to a bitSet.
Definition: HashOps.C:63
bool all() const
True if all bits in this bitset are set or if the set is empty.
Definition: bitSetI.H:407
label size() const noexcept
Number of entries.
Definition: PackedList.H:371
bitSet & bound(const label maxSize)
Ensure the addressable range does not exceed maxSize.
Definition: bitSetI.H:572
void checkIndex(const label i) const
Check index is within valid range [0,size)
Definition: PackedListI.H:419