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 * * * * * * * * * * * * * //
407 
408 inline bool Foam::bitSet::all() const
409 {
410  if (empty()) return true; // SIC. boost convention
411  return (-1 == first_not_block());
412 }
413 
415 inline bool Foam::bitSet::any() const
416 {
417  return (-1 != first_block());
418 }
419 
421 inline bool Foam::bitSet::none() const
422 {
423  return (-1 == first_block());
424 }
425 
426 
427 inline unsigned int Foam::bitSet::count(const bool on) const
428 {
429  unsigned int total = 0;
430 
431  const label nblocks = num_blocks(size());
432 
433  for (label blocki = 0; blocki < nblocks; ++blocki)
434  {
435  total += BitOps::bit_count(blocks_[blocki]);
436  }
437 
438  if (!on)
439  {
440  // Return the number of bits that are OFF.
441  return (unsigned(size()) - total);
442  }
443 
444  return total;
445 }
446 
449 {
450  return toc();
451 }
452 
453 
454 inline void Foam::bitSet::resize_last()
455 {
456  const label pos = find_last();
457 
458  if (pos >= 0)
459  {
460  resize(pos+1);
461  }
462  else
463  {
464  clear();
465  }
466 }
467 
469 inline void Foam::bitSet::swap(bitSet& bitset)
470 {
472 }
473 
476 {
478 }
479 
480 
481 inline void Foam::bitSet::fill(const bool val)
482 {
483  if (empty())
484  {
485  return; // Trivial case
486  }
487 
488  const label nblocks = num_blocks(size());
489 
490  // Fill value for complete blocks
491  const unsigned int blockval = (val ? ~0u : 0u);
492 
493  for (label blocki=0; blocki < nblocks; ++blocki)
494  {
495  blocks_[blocki] = blockval;
496  }
497 
498  if (val)
499  {
501  }
502 }
503 
505 inline void Foam::bitSet::set(const bitSet& bitset)
506 {
507  orEq(bitset);
508 }
509 
510 
511 inline Foam::label Foam::bitSet::set(const labelUList& locations)
512 {
513  return setMany(locations.begin(), locations.end());
514 }
515 
516 
517 template<class Addr>
518 inline Foam::label Foam::bitSet::set
519 (
521 )
522 {
523  return setMany(locations.begin(), locations.end());
524 }
525 
526 
527 inline Foam::label Foam::bitSet::unset(const labelUList& locations)
528 {
529  return unset(locations.begin(), locations.end());
530 }
531 
532 
533 template<class Addr>
534 inline Foam::label Foam::bitSet::unset
535 (
537 )
538 {
539  return unset(locations.begin(), locations.end());
540 }
541 
543 inline Foam::bitSet& Foam::bitSet::unset(const bitSet& other)
544 {
545  return minusEq(other);
546 }
547 
548 
549 inline void Foam::bitSet::flip()
550 {
551  if (size())
552  {
553  const label nblocks = num_blocks(size());
554 
555  for (label blocki=0; blocki < nblocks; ++blocki)
556  {
557  blocks_[blocki] = ~(blocks_[blocki]);
558  }
560  }
561 }
562 
563 
564 inline void Foam::bitSet::flip(const label i)
565 {
566  if (i >= 0 && i < size())
567  {
568  reference(this, i).flip();
569  }
570 }
571 
572 
573 inline Foam::bitSet& Foam::bitSet::bound(const label maxSize)
574 {
575  if (maxSize < size())
576  {
577  resize(maxSize);
578  }
579 
580  return *this;
581 }
582 
584 inline Foam::bitSet& Foam::bitSet::bound(const bitSet& other)
585 {
586  return bound(other.size());
587 }
588 
589 
590 inline Foam::bitSet& Foam::bitSet::extend(const label minSize)
591 {
592  if (size() < minSize)
593  {
594  resize(minSize);
595  }
596 
597  return *this;
598 }
599 
600 
601 inline Foam::bitSet& Foam::bitSet::extend(const bitSet& other)
602 {
603  return extend(other.size());
604 }
605 
606 
607 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
609 inline bool Foam::bitSet::operator()(const label pos) const
610 {
611  return test(pos);
612 }
613 
615 inline unsigned int Foam::bitSet::operator[](const label i) const
616 {
617  return get(i);
618 }
619 
620 
622 {
623  #ifdef FULLDEBUG
624  checkIndex(i);
625  #endif
626  return reference(this, i);
627 }
628 
629 
631 {
633  return *this;
634 }
635 
636 
638 {
639  transfer(bitset);
640  return *this;
641 }
642 
643 
644 inline Foam::bitSet& Foam::bitSet::operator=(const bool val)
645 {
646  fill(val);
647  return *this;
648 }
649 
651 inline Foam::bitSet& Foam::bitSet::operator&=(const bitSet& other)
652 {
653  return andEq(other);
654 }
655 
657 inline Foam::bitSet& Foam::bitSet::operator|=(const bitSet& other)
658 {
659  return orEq(other);
660 }
661 
663 inline Foam::bitSet& Foam::bitSet::operator^=(const bitSet& other)
664 {
665  return xorEq(other);
666 }
667 
668 
669 inline Foam::bitSet& Foam::bitSet::operator-=(const bitSet& other)
670 {
671  return minusEq(other);
672 }
673 
674 
675 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
676 
678 {
679  bitSet result(bitset);
680  result.flip();
681  return result;
682 }
683 
684 
685 inline Foam::bitSet Foam::operator&(const bitSet& a, const bitSet& b)
686 {
687  bitSet result(a);
688  result &= b;
689 
690  result.resize_last();
691  return result;
692 }
693 
694 
695 inline Foam::bitSet Foam::operator|(const bitSet& a, const bitSet& b)
696 {
697  bitSet result(a);
698  result |= b;
699 
700  result.resize_last();
701  return result;
702 }
703 
704 
705 inline Foam::bitSet Foam::operator^(const bitSet& a, const bitSet& b)
706 {
707  bitSet result(a);
708  result ^= b;
709 
710  result.resize_last();
711  return result;
712 }
713 
714 
715 inline Foam::bitSet Foam::operator-(const bitSet& a, const bitSet& b)
716 {
717  bitSet result(a);
718  result |= b;
719 
720  result.resize_last();
721  return result;
722 }
723 
724 
725 // ************************************************************************* //
A reference supporting read/write access to an entry.
Definition: bitSet.H:625
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:420
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:498
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:474
bitSet operator~(const bitSet &bitset)
Bitset complement, returns a copy of the bitset with all its bits flipped.
Definition: bitSetI.H:670
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:542
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:441
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:602
bitSet & operator=(const bitSet &bitset)
Copy assignment.
Definition: bitSetI.H:623
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:608
bitSet operator|(const bitSet &a, const bitSet &b)
Bitwise-OR of two bitsets.
Definition: bitSetI.H:688
void resize_last()
Resize to include the last on bit only.
Definition: bitSetI.H:447
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:408
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:105
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:536
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
bitSet & operator^=(const bitSet &other)
Bitwise-XOR operator - retains unique entries.
Definition: bitSetI.H:656
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:650
void transfer(bitSet &bitset)
Transfer the contents of the argument list into this list and annul the argument list.
Definition: bitSetI.H:468
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:392
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:329
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:662
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:183
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:698
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedList.H:388
A const_iterator for iterating across on values.
Definition: bitSet.H:679
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:225
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:197
static constexpr unsigned elem_per_block
The number of elements stored per data block.
Definition: PackedList.H:175
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:436
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:462
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:583
bool none() const
True if no bits in this bitset are set.
Definition: bitSetI.H:414
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:401
label size() const noexcept
Number of entries.
Definition: PackedList.H:393
bitSet & bound(const label maxSize)
Ensure the addressable range does not exceed maxSize.
Definition: bitSetI.H:566
void checkIndex(const label i) const
Check index is within valid range [0,size)
Definition: PackedListI.H:419