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