diff --git a/applications/test/boolList/Make/files b/applications/test/boolList/Make/files new file mode 100644 index 0000000000..9cbdcc0808 --- /dev/null +++ b/applications/test/boolList/Make/files @@ -0,0 +1,3 @@ +Test-boolList.C + +EXE = $(FOAM_USER_APPBIN)/Test-boolList diff --git a/applications/test/boolList/Make/options b/applications/test/boolList/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/boolList/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/boolList/Test-boolList.C b/applications/test/boolList/Test-boolList.C new file mode 100644 index 0000000000..5e0a4772f5 --- /dev/null +++ b/applications/test/boolList/Test-boolList.C @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-boolList + +Description + Test specialized boolList functionality + +\*---------------------------------------------------------------------------*/ + +#include "uLabel.H" +#include "boolList.H" +#include "bitSet.H" +#include "BitOps.H" +#include "FlatOutput.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +using namespace Foam; + +labelList sortedToc(const UList& bools) +{ + label count = 0; + for (const bool val : bools) + { + if (val) ++count; + } + + labelList indices(count); + count = 0; + + forAll(bools, i) + { + if (bools[i]) + { + indices[count++] = i; + } + } + indices.resize(count); + + return indices; +} + + +inline Ostream& info(const UList& 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 UList& bitset, + bool showBits = false, + bool debugOutput = false +) +{ + info(bitset); + + Info<< "values: " << flatOutput(sortedToc(bitset)) << nl; + + return Info; +} + + +inline Ostream& report(const UList& bools) +{ + info(bools); + return Info; +} + + +inline bool compare +( + const UList& bitset, + const std::string& expected +) +{ + std::string has; + has.reserve(bitset.size()); + + forAll(bitset, i) + { + has += (bitset[i] ? '1' : '.'); + } + + if (has == expected) + { + Info<< "pass: " << has << nl; + return true; + } + + Info<< "fail: " << has << nl; + Info<< "expect: " << expected << nl; + + return false; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + boolList list1(22, false); + // Set every third one on + forAll(list1, i) + { + list1[i] = !(i % 3); + } + Info<< "\nalternating bit pattern\n"; + compare(list1, "1..1..1..1..1..1..1..1"); + + BitOps::unset(list1, labelRange(13, 20)); // In range + Info<< "\nafter clear [13,..]\n"; + compare(list1, "1..1..1..1..1........."); + + BitOps::unset(list1, labelRange(40, 20)); // out of range + Info<< "\nafter clear [40,..]\n"; + compare(list1, "1..1..1..1..1........."); + + BitOps::set(list1, labelRange(13, 5)); // In range + Info<< "\nafter set [13,5]\n"; + compare(list1, "1..1..1..1..111111...."); + + Info<< "\nDone" << nl << endl; + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C index 36ea5a6492..8d840513d9 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.C +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,8 +28,96 @@ License #include "BitOps.H" #include "bitSet.H" #include "HashSet.H" +#include "List.H" +#include "labelRange.H" -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * * BitOps * * * * * * * * * * * * * * * * // + +// See bitSet::set(labelRange) for original implementation +void Foam::BitOps::set(List& bools, const labelRange& range) +{ + labelRange slice(range); + slice.adjust(); // No negative start, size adjusted accordingly + + // Range is invalid (zero-sized or entirely negative) - noop + if (slice.empty()) + { + return; + } + + // Range finishes at or beyond the right side. + // - zero fill any gaps that we might create. + // - flood-fill the rest, which now corresponds to the full range. + // + // NB: use labelRange after() for the exclusive end-value, which + // corresponds to our new set size. + if (slice.after() >= bools.size()) + { + label i = bools.size(); + + bools.resize(slice.after(), true); + + // Backfill with false + while (i < slice.start()) + { + bools.unset(i); + ++i; + } + return; + } + + for (label i = slice.first(); i <= slice.last(); ++i) + { + bools.set(i); + } +} + + +// See bitSet::set(labelRange) for original implementation +void Foam::BitOps::set(labelHashSet& hashset, const labelRange& range) +{ + labelRange slice(range); + slice.adjust(); // No negative start, size adjusted accordingly + + for (label i = slice.first(); i <= slice.last(); ++i) + { + hashset.set(i); + } +} + + +void Foam::BitOps::set(bitSet& bitset, const labelRange& range) +{ + bitset.set(range); +} + + +// See bitSet::unset(labelRange) for original implementation +void Foam::BitOps::unset(List& bools, const labelRange& range) +{ + for (label i = range.first(); i <= range.last(); ++i) + { + bools.unset(i); + } +} + + +void Foam::BitOps::unset(labelHashSet& hashset, const labelRange& range) +{ + for (label i = range.first(); i <= range.last(); ++i) + { + hashset.unset(i); + } +} + + +void Foam::BitOps::unset(bitSet& bitset, const labelRange& range) +{ + bitset.unset(range); +} + + +// * * * * * * * * * * * * * * * * BitSetOps * * * * * * * * * * * * * * * * // Foam::bitSet Foam::BitSetOps::create ( diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H index e2c74b4a17..0301a03972 100644 --- a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H +++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,6 +37,8 @@ Namespace Description Factory and other methods for bitSet. + Adaptor methods for other containers that are somewhat similar to + bitSet (eg, boolList, labelHashSet). \*---------------------------------------------------------------------------*/ @@ -56,8 +58,9 @@ Description namespace Foam { -// Forward declarations +// Forward Declarations class bitSet; +template class List; /*---------------------------------------------------------------------------*\ Namespace BitOps Declaration @@ -98,6 +101,30 @@ inline bool none(const UList& bools) } +//- Set the specified range 'on' in a boolList. +// For compatibility with bitSet::set(labelRange) +void set(List& bools, const labelRange& range); + +//- Set the specified range in a labelHashSet. +// For compatibility with bitSet::set(labelRange) +void set(labelHashSet& hashset, const labelRange& range); + +//- Forward to bitSet::set(labelRange) +void set(bitSet& bitset, const labelRange& range); + + +//- Unset the specified range 'on' in a boolList. +// For compatibility with bitSet::unset(labelRange) +void unset(List& bools, const labelRange& range); + +//- Unset the specified range in a labelHashSet. +// For compatibility with bitSet::unset(labelRange) +void unset(labelHashSet& hashset, const labelRange& range); + +//- Forward to bitSet::unset(labelRange) +void unset(bitSet& bitset, const labelRange& range); + + //- Count arbitrary number of bits (of an integral type) template inline unsigned int bit_count(UIntType x) diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H index e2502ccf96..2921a02e23 100644 --- a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H +++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H @@ -308,7 +308,7 @@ public: // (auto-vivifies). inline void set(const bitSet& bitset); - //- Set the specified range of bits specified + //- Set the specified range of bits // The current set size may grow to accommodate any new bits // (auto-vivifies). // \note this operation is generally more efficient than calling