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 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
29 
30 inline Foam::label Foam::bitSet::first_not_block() const
31 {
32  if (empty())
33  {
34  return -1;
35  }
36 
37  // Use complement to change 0 <-> 1 and check if any 1's now appear
38 
39  const label nblocks = num_blocks(size());
40 
41  // Extra bits in the final block?
42  const unsigned int off = size() % elem_per_block;
43 
44  if (!off)
45  {
46  for (label blocki=0; blocki < nblocks; ++blocki)
47  {
48  if (~(blocks_[blocki]))
49  {
50  return blocki;
51  }
52  }
53  }
54  else
55  {
56  for (label blocki=0; blocki < nblocks-1; ++blocki)
57  {
58  if (~(blocks_[blocki]))
59  {
60  return blocki;
61  }
62  }
63 
64  // The final block needs masking
65  if (~(blocks_[nblocks-1]) & mask_lower(off))
66  {
67  return nblocks-1;
68  }
69  }
70 
71  return -1;
72 }
73 
74 
75 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
76 
78 :
79  PackedList<1>()
80 {}
81 
82 
83 inline Foam::bitSet::bitSet(const label n)
84 :
85  PackedList<1>(n)
86 {}
87 
88 
89 inline Foam::bitSet::bitSet(const label n, const bool val)
90 :
91  bitSet(n)
92 {
93  if (val) fill(val);
94 }
95 
96 
97 inline Foam::bitSet::bitSet(const bitSet& bitset)
98 :
99  PackedList<1>(bitset)
100 {}
101 
104 :
105  PackedList<1>(std::move(bitset))
106 {}
107 
108 
110 :
111  bitSet()
112 {
113  assign(bools);
114 }
115 
116 
117 inline Foam::bitSet::bitSet(const label n, const labelUList& locations)
118 :
119  bitSet(n)
120 {
121  setMany(locations.begin(), locations.end());
122 }
123 
124 
125 template<class Addr>
127 (
128  const label n,
129  const IndirectListBase<label, Addr>& locations
130 )
131 :
133 {
134  setMany(locations.begin(), locations.end());
135 }
136 
137 
139 (
140  const label n,
141  std::initializer_list<label> locations
142 )
143 :
144  bitSet(n)
145 {
146  setMany(locations.begin(), locations.end());
147 }
148 
149 
150 inline Foam::bitSet::bitSet(const labelUList& locations)
151 :
152  bitSet()
153 {
154  setMany(locations.begin(), locations.end());
155 }
156 
157 
158 template<class Addr>
160 (
161  const IndirectListBase<label, Addr>& locations
162 )
163 :
164  bitSet()
165 {
166  setMany(locations.begin(), locations.end());
167 }
168 
169 
171 {
172  return autoPtr<bitSet>::New(*this);
173 }
174 
175 
176 // * * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * * //
177 
179 (
180  bitSet* parent,
181  const label index
182 )
183 :
184  PackedList<1>::reference(parent, index)
185 {}
186 
187 
188 inline void Foam::bitSet::reference::flip()
189 {
190  const unsigned int mask = (max_value << shift_);
191  ref_ ^= mask;
192 }
193 
194 
195 inline void Foam::bitSet::reference::operator=
196 (
197  const reference& other
198 )
199 {
200  // Accepts self-assignment
201  set(other.get());
202 }
203 
204 
205 inline void Foam::bitSet::reference::operator=
206 (
207  const unsigned int val
208 )
209 {
210  set(val);
211 }
212 
213 
214 inline Foam::bitSet::reference::operator unsigned int () const
215 {
216  return get();
217 }
218 
219 
220 // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
221 
222 inline Foam::bitSet::const_iterator::const_iterator() noexcept
223 :
224  set_(nullptr),
225  pos_(-1)
226 {}
227 
228 
229 inline Foam::bitSet::const_iterator::const_iterator(const bitSet* parent)
230 :
231  set_(parent),
232  pos_(set_->find_first())
233 {}
234 
235 
236 inline Foam::bitSet::const_iterator::const_iterator
237 (
238  const bitSet* parent,
239  label pos
240 )
241 :
242  set_(parent),
243  pos_(set_->find_next(pos-1))
244 {}
245 
247 inline Foam::label Foam::bitSet::const_iterator::operator*() const noexcept
248 {
249  return pos_;
250 }
251 
252 
254 {
255  pos_ = set_->find_next(pos_);
256  return *this;
257 }
258 
259 
260 inline bool Foam::bitSet::const_iterator::operator==
261 (
262  const const_iterator& iter
263 ) const noexcept
264 {
265  return (iter.pos_ == pos_);
266 }
267 
268 
269 inline bool Foam::bitSet::const_iterator::operator!=
270 (
271  const const_iterator& iter
272 ) const noexcept
273 {
274  return (iter.pos_ != pos_);
275 }
276 
279 {
280  return const_iterator(this);
281 }
282 
285 {
286  return const_iterator(this);
287 }
288 
291 {
292  return const_iterator(this, pos);
293 }
294 
297 {
298  return const_iterator(this, pos);
299 }
300 
303 {
304  return const_iterator();
305 }
306 
309 {
310  return const_iterator();
311 }
312 
313 
314 inline Foam::label Foam::bitSet::find_first() const
315 {
316  // Process block-wise, detecting any '1' bits
317 
318  const label nblocks = num_blocks(size());
319 
320  for (label blocki = 0; blocki < nblocks; ++blocki)
321  {
322  label pos = (blocki * elem_per_block);
323 
324  for
325  (
326  unsigned int blockval = blocks_[blocki];
327  blockval;
328  blockval >>= 1u
329  )
330  {
331  if (blockval & 1u)
332  {
333  return pos;
334  }
335  ++pos;
336  }
337  }
338 
339  return -1;
340 }
341 
342 
343 inline Foam::label Foam::bitSet::find_first_not() const
344 {
345  const label blocki = first_not_block();
346 
347  if (blocki >= 0)
348  {
349  label pos = (blocki * elem_per_block);
350 
351  // Detect first '0' bit by checking the complement.
352 
353  // No special masking for the final block, that was already checked
354  // in the first_not_block() call.
355 
356  for
357  (
358  unsigned int blockval = ~(blocks_[blocki]);
359  blockval;
360  blockval >>= 1u
361  )
362  {
363  if (blockval & 1u)
364  {
365  return pos;
366  }
367  ++pos;
368  }
369  }
370 
371  return -1;
372 }
373 
374 
375 inline Foam::label Foam::bitSet::find_last() const
376 {
377  // Process block-wise, detecting any '1' bits
378 
379  for (label blocki = num_blocks(size())-1; blocki >= 0; --blocki)
380  {
381  unsigned int blockval = blocks_[blocki];
382 
383  if (blockval)
384  {
385  label pos = (blocki * elem_per_block) - 1;
386 
387  while (blockval)
388  {
389  blockval >>= 1u;
390  ++pos;
391  }
392 
393  return pos;
394  }
395  }
396 
397  return -1;
398 }
399 
400 
401 inline Foam::label Foam::bitSet::find_next(label pos) const
402 {
403  ++pos;
404  if (pos < 0 || pos >= size())
405  {
406  return -1;
407  }
408 
409  // The corresponding block/offset
410  label blocki = pos / elem_per_block;
411  unsigned int off = pos % elem_per_block;
412 
413  for
414  (
415  unsigned int blockval = (blocks_[blocki] >> off);
416  blockval;
417  blockval >>= 1u
418  )
419  {
420  if (blockval & 1u)
421  {
422  return pos;
423  }
424  ++pos;
425  }
426 
427  // Normal block-wise search. Starting at the next block
428 
429  const label nblocks = num_blocks(size());
430  for (++blocki; blocki < nblocks; ++blocki)
431  {
432  label pos = (blocki * elem_per_block);
433 
434  for
435  (
436  unsigned int blockval = blocks_[blocki];
437  blockval;
438  blockval >>= 1u
439  )
440  {
441  if (blockval & 1u)
442  {
443  return pos;
444  }
445  ++pos;
446  }
447  }
449  return -1;
450 }
451 
452 
453 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
455 inline const Foam::bitSet& Foam::bitSet::null()
456 {
457  return NullObjectRef<bitSet>();
458 }
459 
460 
461 inline bool Foam::bitSet::all() const
462 {
463  if (empty()) return true; // SIC. boost convention
464 
465  return -1 == first_not_block();
466 }
467 
468 
469 inline bool Foam::bitSet::any() const
470 {
471  if (size())
472  {
473  const label nblocks = num_blocks(size());
474 
475  for (label blocki=0; blocki < nblocks; ++blocki)
476  {
477  if (blocks_[blocki])
478  {
479  return true;
480  }
481  }
482  }
483 
484  return false;
485 }
486 
488 inline bool Foam::bitSet::none() const
489 {
490  return !any();
491 }
492 
494 inline bool Foam::bitSet::uniform() const
495 {
496  return (size() == 1 || (size() > 1 && (test(0) ? all() : none())));
497 }
498 
499 
500 inline unsigned int Foam::bitSet::count(const bool on) const
501 {
502  unsigned int total = 0;
503 
504  const label nblocks = num_blocks(size());
505 
506  for (label blocki = 0; blocki < nblocks; ++blocki)
507  {
508  total += BitOps::bit_count(blocks_[blocki]);
509  }
510 
511  if (!on)
512  {
513  // Return the number of bits that are OFF.
514  return (unsigned(size()) - total);
515  }
516 
517  return total;
518 }
519 
522 {
523  return toc();
524 }
525 
526 
527 inline void Foam::bitSet::resize_last()
528 {
529  const label pos = find_last();
530 
531  if (pos >= 0)
532  {
533  resize(pos+1);
534  }
535  else
536  {
537  clear();
538  }
539 }
540 
542 inline void Foam::bitSet::swap(bitSet& bitset)
543 {
545 }
546 
549 {
551 }
552 
553 
554 inline void Foam::bitSet::fill(const bool val)
555 {
556  if (empty())
557  {
558  return; // Trivial case
559  }
560 
561  const label nblocks = num_blocks(size());
562 
563  // Fill value for complete blocks
564  const unsigned int blockval = (val ? ~0u : 0u);
565 
566  for (label blocki=0; blocki < nblocks; ++blocki)
567  {
568  blocks_[blocki] = blockval;
569  }
570 
571  if (val)
572  {
574  }
575 }
576 
578 inline void Foam::bitSet::set(const bitSet& bitset)
579 {
580  orEq(bitset);
581 }
582 
583 
584 inline Foam::label Foam::bitSet::set(const labelUList& locations)
585 {
586  return setMany(locations.begin(), locations.end());
587 }
588 
589 
590 template<class Addr>
591 inline Foam::label Foam::bitSet::set
592 (
594 )
595 {
596  return setMany(locations.begin(), locations.end());
597 }
598 
599 
600 inline Foam::label Foam::bitSet::unset(const labelUList& locations)
601 {
602  return unset(locations.begin(), locations.end());
603 }
604 
605 
606 template<class Addr>
607 inline Foam::label Foam::bitSet::unset
608 (
610 )
611 {
612  return unset(locations.begin(), locations.end());
613 }
614 
616 inline Foam::bitSet& Foam::bitSet::unset(const bitSet& other)
617 {
618  return minusEq(other);
619 }
620 
621 
622 inline void Foam::bitSet::flip()
623 {
624  if (size())
625  {
626  const label nblocks = num_blocks(size());
627 
628  for (label blocki=0; blocki < nblocks; ++blocki)
629  {
630  blocks_[blocki] = ~(blocks_[blocki]);
631  }
633  }
634 }
635 
636 
637 inline void Foam::bitSet::flip(const label i)
638 {
639  if (i >= 0 && i < size())
640  {
641  reference(this, i).flip();
642  }
643 }
644 
645 
646 inline Foam::bitSet& Foam::bitSet::bound(const label maxSize)
647 {
648  if (maxSize < size())
649  {
650  resize(maxSize);
651  }
652 
653  return *this;
654 }
655 
657 inline Foam::bitSet& Foam::bitSet::bound(const bitSet& other)
658 {
659  return bound(other.size());
660 }
661 
662 
663 inline Foam::bitSet& Foam::bitSet::extend(const label minSize)
664 {
665  if (size() < minSize)
666  {
667  resize(minSize);
668  }
669 
670  return *this;
671 }
672 
673 
674 inline Foam::bitSet& Foam::bitSet::extend(const bitSet& other)
675 {
676  return extend(other.size());
677 }
678 
679 
680 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
682 inline bool Foam::bitSet::operator()(const label pos) const
683 {
684  return test(pos);
685 }
686 
688 inline unsigned int Foam::bitSet::operator[](const label i) const
689 {
690  return get(i);
691 }
692 
693 
695 {
696  #ifdef FULLDEBUG
697  checkIndex(i);
698  #endif
699  return reference(this, i);
700 }
701 
702 
704 {
706  return *this;
707 }
708 
709 
711 {
712  transfer(bitset);
713  return *this;
714 }
715 
716 
717 inline Foam::bitSet& Foam::bitSet::operator=(const bool val)
718 {
719  fill(val);
720  return *this;
721 }
722 
724 inline Foam::bitSet& Foam::bitSet::operator&=(const bitSet& other)
725 {
726  return andEq(other);
727 }
728 
730 inline Foam::bitSet& Foam::bitSet::operator|=(const bitSet& other)
731 {
732  return orEq(other);
733 }
734 
736 inline Foam::bitSet& Foam::bitSet::operator^=(const bitSet& other)
737 {
738  return xorEq(other);
739 }
740 
741 
742 inline Foam::bitSet& Foam::bitSet::operator-=(const bitSet& other)
743 {
744  return minusEq(other);
745 }
746 
747 
748 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
749 
751 {
752  bitSet result(bitset);
753  result.flip();
754  return result;
755 }
756 
757 
758 inline Foam::bitSet Foam::operator&(const bitSet& a, const bitSet& b)
759 {
760  bitSet result(a);
761  result &= b;
762 
763  result.resize_last();
764  return result;
765 }
766 
767 
768 inline Foam::bitSet Foam::operator|(const bitSet& a, const bitSet& b)
769 {
770  bitSet result(a);
771  result |= b;
772 
773  result.resize_last();
774  return result;
775 }
776 
777 
778 inline Foam::bitSet Foam::operator^(const bitSet& a, const bitSet& b)
779 {
780  bitSet result(a);
781  result ^= b;
782 
783  result.resize_last();
784  return result;
785 }
786 
787 
788 inline Foam::bitSet Foam::operator-(const bitSet& a, const bitSet& b)
789 {
790  bitSet result(a);
791  result |= b;
792 
793  result.resize_last();
794  return result;
795 }
796 
797 
798 // ************************************************************************* //
A reference supporting read/write access to an entry.
Definition: bitSet.H:637
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:493
const_iterator & operator++()
Move to the next on position.
Definition: bitSetI.H:246
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:571
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:547
bitSet operator~(const bitSet &bitset)
Bitset complement, returns a copy of the bitset with all its bits flipped.
Definition: bitSetI.H:743
label find_last() const
Locate the last bit set.
Definition: bitSetI.H:368
bool uniform() const
True if all entries have identical values, and the set is non-empty.
Definition: bitSetI.H:487
void flip()
Invert all bits in the addressable region.
Definition: bitSetI.H:615
reference(bitSet *parent, const label index)
Construct by taking reference of block from within the list and the specified index.
Definition: bitSetI.H:172
labelList sortedToc() const
The indices of the on bits as a sorted labelList.
Definition: bitSetI.H:514
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:307
bool operator()(const label pos) const
Test value at specified position, same as test()
Definition: bitSetI.H:675
bitSet & operator=(const bitSet &bitset)
Copy assignment.
Definition: bitSetI.H:696
bitSet() noexcept
Default construct an empty, zero-sized bitSet.
Definition: bitSetI.H:70
void flip()
Flip the bit at the position, no range-checking.
Definition: bitSetI.H:181
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:394
const_iterator begin() const
Iterator set to the position of the first on bit.
Definition: bitSetI.H:271
void operator=(const PackedList< Width > &lst)
Copy assignment.
Definition: PackedListI.H:771
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:681
bitSet operator|(const bitSet &a, const bitSet &b)
Bitwise-OR of two bitsets.
Definition: bitSetI.H:761
void resize_last()
Resize to include the last on bit only.
Definition: bitSetI.H:520
label find_first_not() const
Locate the first bit that is unset.
Definition: bitSetI.H:336
bool any() const
True if any bits in this bitset are set.
Definition: bitSetI.H:462
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:388
dimensionedScalar pos(const dimensionedScalar &ds)
autoPtr< bitSet > clone() const
Clone.
Definition: bitSetI.H:163
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:609
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:448
bitSet & operator^=(const bitSet &other)
Bitwise-XOR operator - retains unique entries.
Definition: bitSetI.H:729
void clear()
Clear the list, i.e. set addressable size to zero.
Definition: PackedListI.H:491
bitSet & operator|=(const bitSet &other)
Bitwise-OR operator - similar to the set() method.
Definition: bitSetI.H:723
void transfer(bitSet &bitset)
Transfer the contents of the argument list into this list and annul the argument list.
Definition: bitSetI.H:541
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:321
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:341
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:99
const_iterator cend() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:301
const direction noexcept
Definition: Scalar.H:258
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:735
void swap(PackedList< Width > &rhs)
Swap contents with argument.
Definition: PackedListI.H:589
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:240
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:771
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedList.H:352
A const_iterator for iterating across on values.
Definition: bitSet.H:691
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:277
block_container blocks_
The blocks of raw data.
Definition: PackedList.H:203
label n
static constexpr block_type mask_lower(unsigned elementOffset)
Masking for all bits below the element offset.
Definition: PackedList.H:185
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:365
void transfer(PackedList< Width > &rhs)
Transfer the contents of the argument list into this list and annul the argument list.
Definition: PackedListI.H:602
const_iterator end() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:295
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
void swap(bitSet &bitset)
Swap contents.
Definition: bitSetI.H:535
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:656
bool none() const
True if no bits in this bitset are set.
Definition: bitSetI.H:481
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:454
label size() const noexcept
Number of entries.
Definition: PackedList.H:357
bitSet & bound(const label maxSize)
Ensure the addressable range does not exceed maxSize.
Definition: bitSetI.H:639
void checkIndex(const label i) const
Check index is within valid range [0,size)
Definition: PackedListI.H:352