openfoam/applications/test/bitSet2/Test-bitSet2.C

526 lines
12 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2021 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 <http://www.gnu.org/licenses/>.
Application
Test-bitSet2
Description
Test bitSet functionality
\*---------------------------------------------------------------------------*/
#include "uLabel.H"
#include "boolList.H"
#include "DynamicList.H"
#include "IOstreams.H"
#include "ITstream.H"
#include "SpanStream.H"
#include "bitSet.H"
#include "FlatOutput.H"
// #define TEST_SFINAE
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
inline Ostream& extent(const bitSet& bitset)
{
Info<< "first: " << bitset.find_first()
<< " 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()
<< " count=" << bitset.count()
<< " !count=" << bitset.count(false)
<< " all:" << bitset.all()
<< " any:" << bitset.any()
<< " 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;
if (showBits)
{
bitset.printBits(Info, debugOutput) << nl;
}
return Info;
}
inline Ostream& report(const UList<bool>& bools)
{
info(bools);
return Info;
}
template<class UIntType>
std::string toString(UIntType value, char off='.', char on='1')
{
std::string str(std::numeric_limits<UIntType>::digits, off);
unsigned n = 0;
// Starting from most significant bit - makes for easy reading.
for
(
unsigned test = (1u << (std::numeric_limits<UIntType>::digits-1));
test;
test >>= 1u
)
{
str[n++] = ((value & test) ? on : off);
}
return str;
}
inline bool compare
(
const bitSet& bitset,
const std::string& expected
)
{
const List<unsigned int>& store = bitset.storage();
std::string has;
for (label blocki=0; blocki < bitset.nBlocks(); ++blocki)
{
has += toString(store[blocki]);
}
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[])
{
Info<< "bitSet::null()" << nl
<< "sizeof : " << sizeof(bitSet::null()) << " bytes" << nl;
info(bitSet::null());
{
bitSet emptySet;
info(emptySet);
extent(emptySet);
emptySet.resize(10);
info(emptySet);
extent(emptySet);
}
Info<< nl << "Tests" << nl;
bitSet list1(22);
// 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");
// As boolList
{
boolList bools = list1.values();
Info<<"===============" << nl;
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 0, 8, 15, 32})
{
Info<< i << " is " << (bools.test(i) ? "set" : "unset")
<< " = " << bools.get(i) << nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 5, 24})
{
Info<< "set(" << i << ") = "
<< (bools.set(i) ? "true" : "false")
<< nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
for (int i : { -10, 12, 32, 150})
{
Info<< "unset(" << i << ") = "
<< (bools.unset(i) ? "true" : "false")
<< nl;
}
Info<<"bools: " << flatOutput(bools) << nl;
#if 0
boolList bools2(6, false);
Info<<"other bools: " << flatOutput(bools2) << nl;
bools2.set(4);
Info<<"other bools: " << flatOutput(bools2) << nl;
bools2.clear();
bools2.set(3);
bools2.resize(8);
Info<<"other bools: " << flatOutput(bools2) << nl;
#endif
Info<<"===============" << nl;
}
#ifdef TEST_SFINAE
{
labelList labels = list1.toc();
if (labels.test(0))
{
Info<<"no" << endl;
}
List<double*> ptrs(10, nullptr);
if (ptrs.get(0))
{
Info<<"no" << endl;
}
}
#endif
list1.unset(labelRange(13, 20)); // In range
Info<< "\nafter clear [13,..]\n";
compare(list1, "...................1..1..1..1..1");
report(list1, true);
list1.unset(labelRange(40, 20)); // out of range
Info<< "\nafter clear [40,..]\n";
compare(list1, "...................1..1..1..1..1");
report(list1, true);
extent(list1);
Info<< "iterate through:";
for (const label idx : list1)
{
Info<<" " << idx;
}
Info<< nl;
Info<< "\nalternating bit pattern\n";
report(list1, true);
bitSet list2 = ~list1;
Info<< "\nflipped bit pattern\n";
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
forAll(list2, i)
{
list2[i] = !(i % 2);
}
Info<< "\nstarting pattern\n";
report(list2, true);
list2.resize(28, false);
list2.resize(34, true);
list2.resize(40, false);
for (label i=0; i < 4; ++i)
{
list2[i] = true;
}
Info<< "\nresized with false, [28,34) true + 6 false, bottom 4 bits true\n";
compare
(
list2,
"1111.......1.1.1.1.1.1.1.1.11111"
"..............................11"
);
report(list2, true);
labelList list2Labels = list2.toc();
Info<< "\noperator|\n";
list1.printBits(Info);
list2.printBits(Info);
Info<< "==\n";
(list1 | list2).printBits(Info);
Info<< "\noperator& : does trim\n";
report((list1 & list2), true);
Info<< "\noperator^\n";
report((list1 ^ list2), true);
Info<< "\noperator|=\n";
{
bitSet a; a.set(labelRange(15, 8));
bitSet b; b.set(labelRange(30, 8));
report(a, false);
report(b, false);
report((a |= b), true);
}
{
Info<< " other test\n";
bitSet list3 = list1;
report((list3 |= list2), true);
}
Info<< "\noperator&=\n";
{
bitSet a; a.set(labelRange(30, 8));
bitSet b; b.set(labelRange(0, 8));
report(a, false);
report(b, false);
Info<< " (a & b)\n";
report((a & b), true);
Info<< " (b & a)\n";
report((b & a), true);
}
{
Info<< " other test\n";
bitSet list3 = list1;
report((list3 &= list2), true);
}
Info<< "\noperator^=\n";
{
bitSet list3 = list1;
report((list3 ^= list2), true);
}
Info<< "\noperator-=\n";
{
bitSet list3 = list1;
report((list3 -= list2), true);
}
bitSet list4
(
ITstream
(
"(1 n 1 n 1 n 1 1 off 0 0 f f 0 y yes y true y false on t)"
)()
);
Info<< "\ntest Istream constructor\n";
report(list4, true);
Info<< "\nclear/assign from labelList\n";
list4.clear();
list4.set(labelList{0, 1, 2, 3, 12, 13, 14, 19, 20, 21});
report(list4, true);
// Not yet:
// bitSet list5{0, 1, 2, 3, 12, 13, 14, 19, 20, 21};
// list5.printInfo(Info, true);
// Info<< list5 << " indices: " << list5.toc() << nl;
Info<< "\nassign from indices\n";
list4.readList
(
ICharStream
(
"{0 1 2 3 12 13 14 19 20 21}"
)()
);
report(list4, true);
compare(list4, "..........111....111........1111");
list4.set(labelRange(28, 6)); // extends size
Info<<"extended\n";
compare
(
list4,
"1111......111....111........1111"
"..............................11"
);
list4.set(labelRange(40, 6)); // extends size
Info<<"extended\n";
compare
(
list4,
"1111......111....111........1111"
"..................111111......11"
);
list4.unset(labelRange(14, 19));
Info<<"cleared [14,33)\n";
compare
(
list4,
"..................11........1111"
"..................111111......1."
);
// Test begin vs find_first etc
{
// Clear some values
list4.unset(labelRange(0, 10));
Info<< nl
<< "Test first vs begin" << nl
<< " values:" << flatOutput(list4.toc()) << nl
<< " first:" << list4.find_first() << nl
<< " begin:" << *(list4.begin()) << nl
<< " begin(0):" << *(list4.begin(0)) << nl;
// With offset
Info<< nl
<< "Test first vs begin" << nl
<< " next(35):" << list4.find_next(35)
<< " begin(35):" << *(list4.begin(35)) << nl
<< " next(40):" << list4.find_next(40)
<< " begin(40):" << *(list4.begin(40)) << nl
<< nl;
}
// Construct from labelUList, labelUIndList
{
DynamicList<label> indices({10, 50, 300});
Info<< "set: " << flatOutput(indices) << endl;
bitSet bools1(indices);
Info<< "used: " << bools1.size() << " "
<< flatOutput(bools1.toc()) << endl;
}
// Check bitSet vs boolList
{
boolList bools(list4.values());
Info<< nl << "Check BitOps on boolList" << nl << nl;
Info<<"bitSet ";
report(list4);
list4.shrink();
Info<<"shrunk ";
report(list4);
Info<< nl;
Info<<"bools ";
report(bools);
bools = false;
Info<<"bools (all unset) ";
report(bools);
bools = true;
Info<<"bools (all set) ";
report(bools);
}
Info<< "\nDone" << nl << endl;
return 0;
}
// ************************************************************************* //