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-------------------------------------------------------------------------------
10License
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
30inline 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
83inline Foam::bitSet::bitSet(const label n)
84:
85 PackedList<1>(n)
86{}
87
88
89inline Foam::bitSet::bitSet(const label n, const bool val)
90:
91 bitSet(n)
92{
93 if (val) fill(val);
94}
95
96
97inline Foam::bitSet::bitSet(const bitSet& bitset)
98:
99 PackedList<1>(bitset)
100{}
101
102
104:
105 PackedList<1>(std::move(bitset))
106{}
107
108
110:
111 bitSet()
112{
113 assign(bools);
114}
115
116
117inline Foam::bitSet::bitSet(const label n, const labelUList& locations)
118:
119 bitSet(n)
120{
121 setMany(locations.begin(), locations.end());
122}
123
124
125template<class Addr>
127(
128 const label n,
129 const IndirectListBase<label, Addr>& locations
130)
131:
132 bitSet(n)
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
150inline Foam::bitSet::bitSet(const labelUList& locations)
151:
152 bitSet()
153{
154 setMany(locations.begin(), locations.end());
155}
156
157
158template<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
189{
190 const unsigned int mask = (max_value << shift_);
191 ref_ ^= mask;
192}
193
194
196(
197 const reference& other
198)
199{
200 // Accepts self-assignment
201 set(other.get());
202}
203
204
206(
207 const unsigned int val
208)
209{
210 set(val);
211}
212
213
214inline Foam::bitSet::reference::operator unsigned int () const
215{
216 return get();
217}
218
219
220// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
221
223:
224 set_(nullptr),
225 pos_(-1)
226{}
227
228
230:
231 set_(parent),
232 pos_(set_->find_first())
233{}
234
235
237(
238 const bitSet* parent,
239 label pos
240)
241:
242 set_(parent),
243 pos_(set_->find_next(pos-1))
244{}
245
246
248{
249 return pos_;
250}
251
252
254{
255 pos_ = set_->find_next(pos_);
256 return *this;
257}
258
259
261(
262 const const_iterator& iter
263) const noexcept
264{
265 return (iter.pos_ == pos_);
266}
267
268
270(
271 const const_iterator& iter
272) const noexcept
273{
274 return (iter.pos_ != pos_);
275}
276
277
279{
280 return const_iterator(this);
281}
282
283
285{
286 return const_iterator(this);
287}
288
289
291{
292 return const_iterator(this, pos);
293}
294
295
297{
298 return const_iterator(this, pos);
299}
300
301
303{
304 return const_iterator();
305}
306
307
309{
310 return const_iterator();
311}
312
313
314inline 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
343inline 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
375inline 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
401inline 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 }
448
449 return -1;
450}
451
452
453// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
454
456{
457 return NullObjectRef<bitSet>();
458}
459
460
461inline bool Foam::bitSet::all() const
462{
463 if (empty()) return true; // SIC. boost convention
464
465 return -1 == first_not_block();
466}
467
468
469inline 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
487
488inline bool Foam::bitSet::none() const
489{
490 return !any();
491}
492
493
494inline bool Foam::bitSet::uniform() const
495{
496 return (size() == 1 || (size() > 1 && (test(0) ? all() : none())));
497}
498
499
500inline 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
520
521inline bool Foam::bitSet::test(const label pos) const
522{
523 return get(pos);
524}
525
526
527inline bool Foam::bitSet::found(const label pos) const
528{
529 return get(pos);
530}
531
532
534{
535 return toc();
536}
537
538
540{
541 const label pos = find_last();
542
543 if (pos >= 0)
544 {
545 resize(pos+1);
546 }
547 else
548 {
549 clear();
550 }
551}
552
553
554inline void Foam::bitSet::swap(bitSet& bitset)
555{
556 PackedList<1>::swap(bitset);
557}
558
559
560inline void Foam::bitSet::transfer(bitSet& bitset)
561{
563}
564
565
566inline void Foam::bitSet::fill(const bool val)
567{
568 if (empty())
569 {
570 return; // Trivial case
571 }
572
573 const label nblocks = num_blocks(size());
574
575 // Fill value for complete blocks
576 const unsigned int blockval = (val ? ~0u : 0u);
577
578 for (label blocki=0; blocki < nblocks; ++blocki)
579 {
580 blocks_[blocki] = blockval;
581 }
582
583 if (val)
584 {
586 }
587}
588
589
590inline void Foam::bitSet::set(const bitSet& bitset)
591{
592 orEq(bitset);
593}
594
595
596inline Foam::label Foam::bitSet::set(const labelUList& locations)
597{
598 return setMany(locations.begin(), locations.end());
599}
600
601
602template<class Addr>
603inline Foam::label Foam::bitSet::set
604(
605 const IndirectListBase<label, Addr>& locations
606)
607{
608 return setMany(locations.begin(), locations.end());
609}
610
611
612inline Foam::label Foam::bitSet::unset(const labelUList& locations)
613{
614 return unset(locations.begin(), locations.end());
615}
616
617
618template<class Addr>
619inline Foam::label Foam::bitSet::unset
620(
621 const IndirectListBase<label, Addr>& locations
622)
623{
624 return unset(locations.begin(), locations.end());
625}
626
627
629{
630 return minusEq(other);
631}
632
633
635{
636 if (size())
637 {
638 const label nblocks = num_blocks(size());
639
640 for (label blocki=0; blocki < nblocks; ++blocki)
641 {
642 blocks_[blocki] = ~(blocks_[blocki]);
643 }
645 }
646}
647
648
649inline void Foam::bitSet::flip(const label i)
650{
651 if (i >= 0 && i < size())
652 {
653 reference(this, i).flip();
654 }
655}
656
657
658inline Foam::bitSet& Foam::bitSet::bound(const label maxSize)
659{
660 if (maxSize < size())
661 {
662 resize(maxSize);
663 }
664
665 return *this;
666}
667
668
670{
671 return bound(other.size());
672}
673
674
675inline Foam::bitSet& Foam::bitSet::extend(const label minSize)
676{
677 if (size() < minSize)
678 {
679 resize(minSize);
680 }
681
682 return *this;
683}
684
685
687{
688 return extend(other.size());
689}
690
691
692// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
693
694inline bool Foam::bitSet::operator()(const label pos) const
695{
696 return test(pos);
697}
698
699
700inline unsigned int Foam::bitSet::operator[](const label i) const
701{
702 return get(i);
703}
704
705
707{
708 #ifdef FULLDEBUG
709 checkIndex(i);
710 #endif
711 return reference(this, i);
712}
713
714
716{
718 return *this;
719}
720
721
723{
724 transfer(bitset);
725 return *this;
726}
727
728
730{
731 fill(val);
732 return *this;
733}
734
735
737{
738 return andEq(other);
739}
740
741
743{
744 return orEq(other);
745}
746
747
749{
750 return xorEq(other);
751}
752
753
755{
756 return minusEq(other);
757}
758
759
760// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
761
763{
764 bitSet result(bitset);
765 result.flip();
766 return result;
767}
768
769
771{
772 bitSet result(a);
773 result &= b;
774
775 result.resize_last();
776 return result;
777}
778
779
781{
782 bitSet result(a);
783 result |= b;
784
785 result.resize_last();
786 return result;
787}
788
789
791{
792 bitSet result(a);
793 result ^= b;
794
795 result.resize_last();
796 return result;
797}
798
799
801{
802 bitSet result(a);
803 result |= b;
804
805 result.resize_last();
806 return result;
807}
808
809
810// ************************************************************************* //
bool found
label n
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
iterator end()
Return an iterator at end of list.
iterator begin()
Return an iterator at begin of list.
virtual char fill() const =0
Get padding character.
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:129
void swap(PackedList< Width > &rhs)
Swap contents with argument.
Definition: PackedListI.H:603
void checkIndex(const label i) const
Check index is within valid range [0,size)
Definition: PackedListI.H:359
static constexpr block_type mask_lower(unsigned elementOffset)
Masking for all bits below the element offset.
Definition: PackedList.H:170
block_container blocks_
The blocks of raw data.
Definition: PackedList.H:184
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedListI.H:384
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:409
static constexpr block_type max_value
Definition: PackedList.H:152
void clear_trailing_bits()
Clear any partial rubbish in the last addressable block.
Definition: PackedListI.H:83
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
unsigned int get(const label i) const
Get value at index i or 0 for out-of-range.
Definition: PackedListI.H:630
void operator=(const PackedList< Width > &lst)
Copy assignment.
Definition: PackedListI.H:773
static constexpr unsigned elem_per_block
The number of elements stored per data block.
Definition: PackedList.H:147
static constexpr label num_blocks(label numElem) noexcept
Definition: PackedList.H:163
void clear()
Clear the list, i.e. set addressable size to zero.
Definition: PackedListI.H:512
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:350
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A const_iterator for iterating across on values.
Definition: bitSet.H:505
const_iterator & operator++()
Move to the next on position.
Definition: bitSetI.H:253
label operator*() const noexcept
Return the current on position.
Definition: bitSetI.H:247
A reference supporting read/write access to an entry.
Definition: bitSet.H:469
void flip()
Flip the bit at the position, no range-checking.
Definition: bitSetI.H:188
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
void fill(const bool val)
Assign all entries to the given value.
Definition: bitSetI.H:566
const_iterator cbegin() const
Iterator set to the position of the first on bit.
Definition: bitSetI.H:284
void flip()
Invert all bits in the addressable region.
Definition: bitSetI.H:634
label find_last() const
Locate the last bit set.
Definition: bitSetI.H:375
labelList sortedToc() const
The indices of the on bits as a sorted labelList.
Definition: bitSetI.H:533
static const bitSet & null()
Return a null bitSet reference.
Definition: bitSetI.H:455
const_iterator end() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:302
void set(const bitSet &bitset)
Set specified bits from another bitset.
Definition: bitSetI.H:590
bitSet & operator-=(const bitSet &other)
Remove entries from this list - identical to the unset() method.
Definition: bitSetI.H:754
bitSet & operator|=(const bitSet &other)
Bitwise-OR operator - similar to the set() method.
Definition: bitSetI.H:742
void transfer(bitSet &bitset)
Definition: bitSetI.H:560
bool none() const
True if no bits in this bitset are set.
Definition: bitSetI.H:488
autoPtr< bitSet > clone() const
Clone.
Definition: bitSetI.H:170
bool test(const label pos) const
Test value at specified position, never auto-vivify entries.
Definition: bitSetI.H:521
bitSet & bound(const label maxSize)
Ensure the addressable range does not exceed maxSize.
Definition: bitSetI.H:658
label find_first_not() const
Locate the first bit that is unset.
Definition: bitSetI.H:343
bitSet & xorEq(const bitSet &other)
The set logical XOR.
Definition: bitSet.C:174
bool all() const
True if all bits in this bitset are set or if the set is empty.
Definition: bitSetI.H:461
labelList toc() const
The indices of the on bits as a sorted labelList.
Definition: bitSet.C:474
const_iterator begin() const
Iterator set to the position of the first on bit.
Definition: bitSetI.H:278
void assign(const UList< bool > &bools)
Copy assign all entries from a list of bools.
Definition: bitSet.C:274
bitSet & operator&=(const bitSet &other)
Bitwise-AND all the bits in other with the bits in this bitset.
Definition: bitSetI.H:736
bool uniform() const
True if all entries have identical values, and the set is non-empty.
Definition: bitSetI.H:494
void resize_last()
Resize to include the last on bit only.
Definition: bitSetI.H:539
bitSet() noexcept
Default construct an empty, zero-sized bitSet.
Definition: bitSetI.H:77
bitSet & andEq(const bitSet &other)
The set logical AND.
Definition: bitSet.C:77
bitSet & orEq(const bitSet &other)
The set logical OR.
Definition: bitSet.C:129
bitSet & operator^=(const bitSet &other)
Bitwise-XOR operator - retains unique entries.
Definition: bitSetI.H:748
bitSet & unset(const bitSet &other)
Definition: bitSetI.H:628
void swap(bitSet &bitset)
Swap contents.
Definition: bitSetI.H:554
label setMany(InputIter first, InputIter last)
const_iterator cend() const noexcept
Iterator beyond the end of the bitSet.
Definition: bitSetI.H:308
label find_next(label pos) const
Locate the next bit set, starting one beyond the specified position.
Definition: bitSetI.H:401
bitSet & minusEq(const bitSet &other)
The set difference.
Definition: bitSet.C:42
bool any() const
True if any bits in this bitset are set.
Definition: bitSetI.H:469
bitSet & extend(const label minSize)
Ensure that minSize is covered by the bitSet.
Definition: bitSetI.H:675
unsigned int operator[](const label i) const
Identical to get() - get value at index.
Definition: bitSetI.H:700
label find_first() const
Locate the first bit that is set.
Definition: bitSetI.H:314
bitSet & operator=(const bitSet &bitset)
Copy assignment.
Definition: bitSetI.H:715
Ostream & operator()() const
Output stream (master only).
Definition: ensightCaseI.H:74
friend Ostream & operator(Ostream &, const faMatrix< Type > &)
Computes a field whose values are offset to a reference value obtained by from a Function1.
Definition: reference.H:211
label count() const
static const triad unset
Definition: triad.H:97
bool set() const
Are all the vector set.
Definition: triadI.H:76
const Switch & bound() const
Return the bound flag.
unsigned int bit_count(UIntType x)
Count arbitrary number of bits (of an integral type)
Definition: BitOps.H:171
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
bitSet operator~(const bitSet &bitset)
Bitset complement, returns a copy of the bitset with all its bits flipped.
Definition: bitSetI.H:762
dimensionedScalar pos(const dimensionedScalar &ds)
bitSet operator|(const bitSet &a, const bitSet &b)
Bitwise-OR of two bitsets.
Definition: bitSetI.H:780
tmp< GeometricField< Type, fvPatchField, volMesh > > operator&(const fvMatrix< Type > &, const DimensionedField< Type, volMesh > &)
bitSet operator^(const bitSet &a, const bitSet &b)
Bitwise-XOR of two bitsets to form a unique bit-set.
Definition: bitSetI.H:790
const direction noexcept
Definition: Scalar.H:223
volScalarField & b
Definition: createFields.H:27