mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: bitSet::find_first_not() method (issue #751)
- find the position of the first bit off - symmetrical with find_first()
This commit is contained in:
@ -40,12 +40,19 @@ Description
|
|||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
inline Ostream& report
|
|
||||||
(
|
inline Ostream& extent(const bitSet& bitset)
|
||||||
const bitSet& bitset,
|
{
|
||||||
bool showBits = false,
|
Info<< "first: " << bitset.find_first()
|
||||||
bool debugOutput = false
|
<< " last: " << bitset.find_last()
|
||||||
)
|
<< " first_not: " << bitset.find_first_not()
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Ostream& info(const bitSet& bitset)
|
||||||
{
|
{
|
||||||
Info<< "size=" << bitset.size() << "/" << bitset.capacity()
|
Info<< "size=" << bitset.size() << "/" << bitset.capacity()
|
||||||
<< " count=" << bitset.count()
|
<< " count=" << bitset.count()
|
||||||
@ -54,6 +61,32 @@ inline Ostream& report
|
|||||||
<< " any:" << bitset.any()
|
<< " any:" << bitset.any()
|
||||||
<< " none:" << bitset.none() << nl;
|
<< " none:" << bitset.none() << nl;
|
||||||
|
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Ostream& info(const UList<bool>& bools)
|
||||||
|
{
|
||||||
|
Info<< "size=" << bools.size()
|
||||||
|
<< " count=" << BitOps::count(bools)
|
||||||
|
<< " !count=" << BitOps::count(bools, false)
|
||||||
|
<< " all:" << BitOps::all(bools)
|
||||||
|
<< " any:" << BitOps::any(bools)
|
||||||
|
<< " none:" << BitOps::none(bools) << nl;
|
||||||
|
|
||||||
|
return Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Ostream& report
|
||||||
|
(
|
||||||
|
const bitSet& bitset,
|
||||||
|
bool showBits = false,
|
||||||
|
bool debugOutput = false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
info(bitset);
|
||||||
|
|
||||||
Info<< "values: " << flatOutput(bitset) << nl;
|
Info<< "values: " << flatOutput(bitset) << nl;
|
||||||
if (showBits)
|
if (showBits)
|
||||||
{
|
{
|
||||||
@ -66,14 +99,7 @@ inline Ostream& report
|
|||||||
|
|
||||||
inline Ostream& report(const UList<bool>& bools)
|
inline Ostream& report(const UList<bool>& bools)
|
||||||
{
|
{
|
||||||
Info<< "size=" << bools.size()
|
return info(bools);
|
||||||
<< " count=" << BitOps::count(bools)
|
|
||||||
<< " !count=" << BitOps::count(bools, false)
|
|
||||||
<< " all:" << BitOps::all(bools)
|
|
||||||
<< " any:" << BitOps::any(bools)
|
|
||||||
<< " none:" << BitOps::none(bools) << nl;
|
|
||||||
|
|
||||||
return Info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -153,10 +179,7 @@ int main(int argc, char *argv[])
|
|||||||
compare(list1, "...................1..1..1..1..1");
|
compare(list1, "...................1..1..1..1..1");
|
||||||
|
|
||||||
report(list1, true);
|
report(list1, true);
|
||||||
|
extent(list1);
|
||||||
|
|
||||||
Info<< "first: " << list1.find_first()
|
|
||||||
<< " last: " << list1.find_last() << endl;
|
|
||||||
|
|
||||||
Info<< "iterate through:";
|
Info<< "iterate through:";
|
||||||
for (const label idx : list1)
|
for (const label idx : list1)
|
||||||
@ -172,6 +195,21 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "\nflipped bit pattern\n";
|
Info<< "\nflipped bit pattern\n";
|
||||||
report(list2, true);
|
report(list2, true);
|
||||||
|
extent(list2);
|
||||||
|
|
||||||
|
Info<< "\nsparse set\n";
|
||||||
|
{
|
||||||
|
bitSet sparse(1000);
|
||||||
|
sparse.set(300);
|
||||||
|
|
||||||
|
info(sparse);
|
||||||
|
extent(sparse);
|
||||||
|
|
||||||
|
sparse.set(0);
|
||||||
|
|
||||||
|
info(sparse);
|
||||||
|
extent(sparse);
|
||||||
|
}
|
||||||
|
|
||||||
// set every other on
|
// set every other on
|
||||||
forAll(list2, i)
|
forAll(list2, i)
|
||||||
|
|||||||
@ -65,6 +65,15 @@ class bitSet
|
|||||||
:
|
:
|
||||||
public PackedList<1>
|
public PackedList<1>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Find the first block with a '0' bit
|
||||||
|
// \return block number or -1 if the set is empty or all bits are on.
|
||||||
|
inline label first_not_block() const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
@ -203,12 +212,18 @@ public:
|
|||||||
// \note Method name compatibility with std::bitset
|
// \note Method name compatibility with std::bitset
|
||||||
inline bool test(const label pos) const;
|
inline bool test(const label pos) const;
|
||||||
|
|
||||||
//- Locate the first bit set.
|
//- Locate the first bit that is set.
|
||||||
// \return the location or -1 if there are no bits set.
|
// \return the location or -1 if there are no bits set.
|
||||||
//
|
//
|
||||||
// \note Method name compatibility with boost::dynamic_bitset
|
// \note Method name compatibility with boost::dynamic_bitset
|
||||||
inline label find_first() const;
|
inline label find_first() const;
|
||||||
|
|
||||||
|
//- Locate the first bit that is unset.
|
||||||
|
// \return the location or -1 if the set is empty or all bits are on.
|
||||||
|
//
|
||||||
|
// \note Provided for symmetry with find_first()
|
||||||
|
inline label find_first_not() const;
|
||||||
|
|
||||||
//- Locate the last bit set.
|
//- Locate the last bit set.
|
||||||
// \return the location or -1 if there are no bits set.
|
// \return the location or -1 if there are no bits set.
|
||||||
//
|
//
|
||||||
|
|||||||
@ -23,6 +23,53 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline Foam::label Foam::bitSet::first_not_block() const
|
||||||
|
{
|
||||||
|
if (empty())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use complement to change 0 <-> 1 and check if any 1's now appear
|
||||||
|
|
||||||
|
const label nblocks = num_blocks(size());
|
||||||
|
|
||||||
|
// Extra bits in the final block?
|
||||||
|
const unsigned int off = size() % elem_per_block;
|
||||||
|
|
||||||
|
if (!off)
|
||||||
|
{
|
||||||
|
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||||
|
{
|
||||||
|
if (~(blocks_[blocki]))
|
||||||
|
{
|
||||||
|
return blocki;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
||||||
|
{
|
||||||
|
if (~(blocks_[blocki]))
|
||||||
|
{
|
||||||
|
return blocki;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The final block needs masking
|
||||||
|
if (~(blocks_[nblocks-1]) & mask_lower(off))
|
||||||
|
{
|
||||||
|
return nblocks-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline constexpr Foam::bitSet::bitSet() noexcept
|
inline constexpr Foam::bitSet::bitSet() noexcept
|
||||||
@ -257,6 +304,38 @@ inline Foam::label Foam::bitSet::find_first() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::label Foam::bitSet::find_first_not() const
|
||||||
|
{
|
||||||
|
const label blocki = first_not_block();
|
||||||
|
|
||||||
|
if (blocki >= 0)
|
||||||
|
{
|
||||||
|
label pos = (blocki * elem_per_block);
|
||||||
|
|
||||||
|
// Detect first '0' bit by checking the complement.
|
||||||
|
|
||||||
|
// No special masking for the final block, that was already checked
|
||||||
|
// in the first_not_block() call.
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
unsigned int blockval = ~(blocks_[blocki]);
|
||||||
|
blockval;
|
||||||
|
blockval >>= 1u
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (blockval & 1u)
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::label Foam::bitSet::find_last() const
|
inline Foam::label Foam::bitSet::find_last() const
|
||||||
{
|
{
|
||||||
// Process block-wise, detecting any '1' bits
|
// Process block-wise, detecting any '1' bits
|
||||||
@ -339,44 +418,7 @@ inline Foam::label Foam::bitSet::find_next(label pos) const
|
|||||||
|
|
||||||
inline bool Foam::bitSet::all() const
|
inline bool Foam::bitSet::all() const
|
||||||
{
|
{
|
||||||
if (empty())
|
return -1 == first_not_block();
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use complement to change 0 <-> 1 and check if any 1's now appear
|
|
||||||
|
|
||||||
const label nblocks = num_blocks(size());
|
|
||||||
|
|
||||||
// Extra bits in the final block?
|
|
||||||
const unsigned int off = size() % elem_per_block;
|
|
||||||
|
|
||||||
if (!off)
|
|
||||||
{
|
|
||||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
|
||||||
{
|
|
||||||
if (~(blocks_[blocki]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
|
||||||
{
|
|
||||||
if (~(blocks_[blocki]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the final block, with masking
|
|
||||||
|
|
||||||
return (!(~blocks_[nblocks-1] & mask_lower(off)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -388,7 +430,10 @@ inline bool Foam::bitSet::any() const
|
|||||||
|
|
||||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||||
{
|
{
|
||||||
if (blocks_[blocki]) return true;
|
if (blocks_[blocki])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,7 +466,7 @@ inline unsigned int Foam::bitSet::count(const bool on) const
|
|||||||
|
|
||||||
if (!on)
|
if (!on)
|
||||||
{
|
{
|
||||||
// Return the number of bits that are off.
|
// Return the number of bits that are OFF.
|
||||||
return (unsigned(size()) - total);
|
return (unsigned(size()) - total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user