diff --git a/applications/test/PackedList1/PackedListTest1.C b/applications/test/PackedList1/PackedListTest1.C index 4ee366854b04662ce3738f58abab87ce09a0a00f..5e1902f3828846943d29c89fd91686a94e9777bc 100644 --- a/applications/test/PackedList1/PackedListTest1.C +++ b/applications/test/PackedList1/PackedListTest1.C @@ -329,23 +329,42 @@ int main(int argc, char *argv[]) list3.print(Info); - List<bool> list4(4, true); + List<bool> list4(16, false); { - const List<bool>& constLst = list4; + // fill with some values + forAll(list4, i) + { + list4[i] = i % 3; + } + + const UList<bool>& constLst = list4; Info<< "\ntest operator[] const with out-of-range index\n"; Info<< constLst << endl; - if (constLst[20]) + if (constLst[100]) { - Info<< "[20] is true (unexpected)\n"; + Info<< "[100] is true (unexpected)\n"; } else { - Info<< "[20] is false (expected) list size should be unchanged " - << "(const)\n"; + Info<< "[100] is false (expected) " + << "list size should be unchanged (const)\n"; } Info<< constLst << endl; } + + PackedBoolList listb(list4); + + Info<< "copied from bool list " << endl; + listb.print(Info, true); + + { + labelList indices = listb.used(); + + Info<< "indices: " << indices << endl; + } + + Info<< "\n\nDone.\n"; return 0; diff --git a/applications/test/PackedList4/Make/files b/applications/test/PackedList4/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..0704f9b826eb283cb3c734dc0cd290154e10d9aa --- /dev/null +++ b/applications/test/PackedList4/Make/files @@ -0,0 +1,3 @@ +PackedListTest4.C + +EXE = $(FOAM_USER_APPBIN)/PackedListTest4 diff --git a/applications/test/PackedList4/Make/options b/applications/test/PackedList4/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/applications/test/PackedList4/PackedListTest4.C b/applications/test/PackedList4/PackedListTest4.C new file mode 100644 index 0000000000000000000000000000000000000000..7271a3f1dd24f47a01c8989dbc61fa191526e66c --- /dev/null +++ b/applications/test/PackedList4/PackedListTest4.C @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 + +Description + +\*---------------------------------------------------------------------------*/ + +#include "uLabel.H" +#include "IOstreams.H" +#include "PackedBoolList.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + PackedBoolList list1(20); + // set every other one on + forAll(list1, i) + { + list1[i] = i % 2; + } + + Info<< "\nalternative bit pattern\n"; + list1.print(Info, true); + + PackedBoolList list2 = ~list1; + + Info<< "\ncomplementary bit pattern\n"; + list2.print(Info, true); + + list2.resize(24, true); + list2.resize(28, false); + for (label i=0; i < 4; ++i) + { + list2[i] = true; + } + + Info<< "\nresized with 4 true + 4 false, bottom 4 bits true\n"; + list2.print(Info, true); + + labelList list2Labels = list2.used(); + + Info<< "\noperator|\n"; + (list1 | list2).print(Info, true); + + Info<< "\noperator& : does trim\n"; + (list1 & list2).print(Info, true); + + Info<< "\noperator^\n"; + (list1 ^ list2).print(Info, true); + + + Info<< "\noperator|=\n"; + { + PackedBoolList list3 = list1; + (list3 |= list2).print(Info, true); + } + + Info<< "\noperator|= with UList<label>\n"; + { + PackedBoolList list3 = list1; + (list3 |= list2Labels).print(Info, true); + } + + Info<< "\noperator&=\n"; + { + PackedBoolList list3 = list1; + (list3 &= list2).print(Info, true); + } + + Info<< "\noperator+=\n"; + { + PackedBoolList list3 = list1; + (list3 += list2).print(Info, true); + } + + Info<< "\noperator+= with UList<label>\n"; + { + PackedBoolList list3 = list1; + (list3 += list2Labels).print(Info, true); + } + + Info<< "\noperator-=\n"; + { + PackedBoolList list3 = list1; + (list3 -= list2).print(Info, true); + } + + Info<< "\noperator-= with UList<label>\n"; + { + PackedBoolList list3 = list1; + (list3 -= list2Labels).print(Info, true); + } + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index 9560986fbdfc3aac0fb8a180a47c4060951dd19c..e57d3ab2a136da54b54eaf6e9fec6832412515dd 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -67,6 +67,7 @@ containers/HashTables/HashTable/HashTableCore.C containers/HashTables/StaticHashTable/StaticHashTableCore.C containers/Lists/SortableList/ParSortableListName.C containers/Lists/PackedList/PackedListName.C +containers/Lists/PackedList/APackedBoolList.C containers/Lists/ListOps/ListOps.C containers/LinkedLists/linkTypes/SLListBase/SLListBase.C containers/LinkedLists/linkTypes/DLListBase/DLListBase.C diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C new file mode 100644 index 0000000000000000000000000000000000000000..f393e144daae3e4210344fcb38a2ae84c6c60d5a --- /dev/null +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C @@ -0,0 +1,274 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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/>. + +\*---------------------------------------------------------------------------*/ + +#include "PackedBoolList.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const +{ + labelList lst(this->count()); + + if (lst.size()) + { + label nElem = 0; + + forAll(*this, elemI) + { + if (get(elemI)) + { + lst[nElem++] = elemI; + } + } + + lst.setSize(nElem); + } + + return lst.xfer(); +} + + +template<class LabelListType> +Foam::label Foam::PackedBoolList::setFromIndices(const LabelListType& indices) +{ + // no better information, just guess something about the size + reserve(indices.size()); + + label cnt = 0; + forAll(indices, elemI) + { + if (set(indices[elemI])) + { + ++cnt; + } + } + + return cnt; +} + + +template<class LabelListType> +Foam::label Foam::PackedBoolList::unsetFromIndices(const LabelListType& indices) +{ + label cnt = 0; + forAll(indices, elemI) + { + if (unset(indices[elemI])) + { + ++cnt; + } + } + + return cnt; +} + + +Foam::label Foam::PackedBoolList::set(const UList<label>& indices) +{ + return setFromIndices(indices); +} + + +Foam::label Foam::PackedBoolList::set(const UIndirectList<label>& indices) +{ + return setFromIndices(indices); +} + + +Foam::label Foam::PackedBoolList::unset(const UList<label>& indices) +{ + return unsetFromIndices(indices); +} + + +Foam::label Foam::PackedBoolList::unset(const UIndirectList<label>& indices) +{ + return unsetFromIndices(indices); +} + + +void Foam::PackedBoolList::modulo(const PackedList<1>& lst) +{ + // operate directly with the underlying storage + StorageList& lhs = this->storage(); + const StorageList& rhs = lst.storage(); + + const label len = min(rhs.size(), lhs.size()); + + for (label i=0; i < len; ++i) + { + lhs[i] &= ~rhs[i]; + } +} + + +// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * // + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const UList<bool>& lst) +{ + this->setSize(lst.size()); + + forAll(*this, elemI) + { + set(elemI, lst[elemI]); + } + + return *this; +} + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const UList<label>& indices) +{ + clear(); + set(indices); + + return *this; +} + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const UIndirectList<label>& indices) +{ + clear(); + set(indices); + + return *this; +} + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator|=(const PackedList<1>& lst) +{ + // extend addressable area if needed + if (this->size() < lst.size()) + { + this->resize(lst.size()); + } + + // operate directly with the underlying storage + StorageList& lhs = this->storage(); + const StorageList& rhs = lst.storage(); + + forAll(rhs, i) + { + lhs[i] |= rhs[i]; + } + + return *this; +} + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator&=(const PackedList<1>& lst) +{ + // shrink addressable area if needed + if (this->size() > lst.size()) + { + this->resize(lst.size()); + } + + // operate directly with the underlying storage + StorageList& lhs = this->storage(); + const StorageList& rhs = lst.storage(); + + forAll(lhs, i) + { + lhs[i] &= rhs[i]; + } + + // trim to bits actually used + this->trim(); + + return *this; +} + + +Foam::PackedBoolList& +Foam::PackedBoolList::operator^=(const PackedList<1>& lst) +{ + // extend addressable area if needed + if (this->size() < lst.size()) + { + this->resize(lst.size()); + } + + // operate directly with the underlying storage + StorageList& lhs = this->storage(); + const StorageList& rhs = lst.storage(); + + forAll(rhs, i) + { + lhs[i] ^= rhs[i]; + } + + return *this; +} + + +// * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * * // + +Foam::PackedBoolList Foam::operator| +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +) +{ + PackedBoolList result(lst1); + result |= lst2; + return result; +} + + +Foam::PackedBoolList Foam::operator& +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +) +{ + PackedBoolList result(lst1); + result &= lst2; + return result; +} + + +Foam::PackedBoolList Foam::operator^ +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +) +{ + PackedBoolList result(lst1); + result ^= lst2; + return result; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H new file mode 100644 index 0000000000000000000000000000000000000000..1d2b19ac078c15a19c00f64723ed5d44561f4943 --- /dev/null +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H @@ -0,0 +1,261 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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/>. + +Class + Foam::PackedBoolList + +Description + A bit-packed bool list + +SourceFiles + PackedBoolListI.H + PackedBoolList.C + +SeeAlso + Foam::PackedList + +\*---------------------------------------------------------------------------*/ + +#ifndef PackedBoolList_H +#define PackedBoolList_H + +#include "PackedList.H" +#include "UIndirectList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class PackedBoolList Declaration +\*---------------------------------------------------------------------------*/ + +class PackedBoolList +: + public PackedList<1> +{ + + // Private Member Functions + + //- Modulo is everything that is not in lst + // This is equivalent to unsetting the bits specified in lst + void modulo(const PackedList<1>&); + + //- Set the listed indices. Return number of elements changed. + // Does auto-vivify for non-existent entries. + template<class LabelListType> + label setFromIndices(const LabelListType& indices); + + //- Unset the listed indices. Return number of elements changed. + // Never auto-vivify entries. + template<class LabelListType> + label unsetFromIndices(const LabelListType& indices); + + +public: + + // Constructors + + //- Construct null + inline PackedBoolList(); + + //- Construct with given size, initializes list to 0 + explicit inline PackedBoolList(const label size); + + //- Construct with given size and value for all elements + inline PackedBoolList(const label size, const bool val); + + //- Copy constructor + inline PackedBoolList(const PackedBoolList&); + + //- Copy constructor + explicit inline PackedBoolList(const PackedList<1>&); + + //- Construct by transferring the parameter contents + inline PackedBoolList(const Xfer<PackedBoolList>&); + + //- Construct by transferring the parameter contents + inline PackedBoolList(const Xfer<PackedList<1> >&); + + //- Construct from a list of bools + explicit inline PackedBoolList(const UList<bool>&); + + //- Construct from a list of labels + // using the labels as indices to indicate which bits are set + explicit inline PackedBoolList(const UList<label>& indices); + + //- Construct from a list of labels + // using the labels as indices to indicate which bits are set + explicit inline PackedBoolList(const UIndirectList<label>& indices); + + //- Clone + inline autoPtr<PackedBoolList> clone() const; + + + // Member Functions + + // Access + + //- Return indices of the used (true) elements as a list of labels + Xfer<labelList> used() const; + + using PackedList<1>::set; + using PackedList<1>::unset; + + //- Set the listed indices. Return number of elements changed. + // Does auto-vivify for non-existent entries. + label set(const UList<label>& indices); + + //- Set the listed indices. Return number of elements changed. + // Does auto-vivify for non-existent entries. + label set(const UIndirectList<label>& indices); + + //- Unset the listed indices. Return number of elements changed. + // Never auto-vivify entries. + label unset(const UList<label>& indices); + + //- Unset the listed indices. Return number of elements changed. + // Never auto-vivify entries. + label unset(const UIndirectList<label>& indices); + + + // Edit + + //- Transfer the contents of the argument list into this list + // and annul the argument list. + inline void transfer(PackedBoolList&); + + //- Transfer the contents of the argument list into this list + // and annul the argument list. + inline void transfer(PackedList<1>&); + + //- Transfer contents to the Xfer container + inline Xfer<PackedBoolList> xfer(); + + + // Member Operators + + //- Assignment of all entries to the given value. + inline PackedBoolList& operator=(const bool val); + + //- Assignment operator. + inline PackedBoolList& operator=(const PackedBoolList&); + + //- Assignment operator. + inline PackedBoolList& operator=(const PackedList<1>&); + + //- Assignment operator. + PackedBoolList& operator=(const UList<bool>&); + + //- Assignment operator, + // using the labels as indices to indicate which bits are set + PackedBoolList& operator=(const UList<label>& indices); + + //- Assignment operator, + // using the labels as indices to indicate which bits are set + PackedBoolList& operator=(const UIndirectList<label>& indices); + + //- Complement operator + inline PackedBoolList operator~() const; + + //- Or operator (lists may be dissimilar sizes) + PackedBoolList& operator|=(const PackedList<1>&); + + //- Or operator (lists may be dissimilar sizes), + // using the labels as indices to indicate which bits are set + inline PackedBoolList& operator|=(const UList<label>& indices); + + //- Or operator (lists may be dissimilar sizes), + // using the labels as indices to indicate which bits are set + inline PackedBoolList& operator|=(const UIndirectList<label>&); + + //- And operator (lists may be dissimilar sizes) + // The result is trimmed to the smallest intersecting size + PackedBoolList& operator&=(const PackedList<1>&); + + //- And operator (lists may be dissimilar sizes) + // Only retain unique entries + PackedBoolList& operator^=(const PackedList<1>&); + + + //- Synonymous with the or operator + inline PackedBoolList& operator+=(const PackedList<1>&); + + //- Synonymous with the or operator + inline PackedBoolList& operator+=(const UList<label>& indices); + + //- Synonymous with the or operator + inline PackedBoolList& operator+=(const UIndirectList<label>&); + + //- Remove entries from this list + inline PackedBoolList& operator-=(const PackedList<1>&); + + //- Remove entries from this list + inline PackedBoolList& operator-=(const UList<label>& indices); + + //- Remove entries from this list + inline PackedBoolList& operator-=(const UIndirectList<label>&); + +}; + + +// Global Operators + +//- Combine lists +PackedBoolList operator| +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +); + + +//- Intersect lists - the result is trimmed to the smallest intersecting size +PackedBoolList operator& +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +); + + +//- Combine to form a unique list (xor) +PackedBoolList operator^ +( + const PackedBoolList& lst1, + const PackedBoolList& lst2 +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "PackedBoolListI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H new file mode 100644 index 0000000000000000000000000000000000000000..f9a7f383e41d714c38312250f507ce37c5d395f9 --- /dev/null +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H @@ -0,0 +1,217 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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/>. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +inline Foam::PackedBoolList::PackedBoolList() +: + PackedList<1>() +{} + + +inline Foam::PackedBoolList::PackedBoolList(const label size) +: + PackedList<1>(size) +{} + + +inline Foam::PackedBoolList::PackedBoolList +( + const label size, + const bool val +) +: + PackedList<1>(size, (val ? 1u : 0u)) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const PackedBoolList& lst) +: + PackedList<1>(lst) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const PackedList<1>& lst) +: + PackedList<1>(lst) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedBoolList>& lst) +: + PackedList<1>() +{ + transfer(lst()); +} + + +inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1> >& lst) +: + PackedList<1>(lst) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const UList<label>& indices) +: + PackedList<1>(indices.size(), 0u) +{ + set(indices); +} + + +inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices) +: + PackedList<1>(indices.size(), 0u) +{ + set(indices); +} + + +inline Foam::autoPtr<Foam::PackedBoolList> +Foam::PackedBoolList::clone() const +{ + return autoPtr<PackedBoolList>(new PackedBoolList(*this)); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +inline void Foam::PackedBoolList::transfer(PackedBoolList& lst) +{ + PackedList<1>::transfer(static_cast<PackedList<1>&>(lst)); +} + + +inline void Foam::PackedBoolList::transfer(PackedList<1>& lst) +{ + PackedList<1>::transfer(lst); +} + + +inline Foam::Xfer<Foam::PackedBoolList> Foam::PackedBoolList::xfer() +{ + return xferMove(*this); +} + + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +inline Foam::PackedBoolList +Foam::PackedBoolList::operator~() const +{ + PackedBoolList result(*this); + result.flip(); + + return result; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const bool val) +{ + PackedList<1>::operator=(val); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const PackedBoolList& lst) +{ + PackedList<1>::operator=(lst); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator=(const PackedList<1>& lst) +{ + PackedList<1>::operator=(lst); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator|=(const UList<label>& indices) +{ + set(indices); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator|=(const UIndirectList<label>& indices) +{ + set(indices); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator+=(const PackedList<1>& lst) +{ + return this->operator|=(lst); +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator+=(const UList<label>& indices) +{ + return this->operator|=(indices); +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator+=(const UIndirectList<label>& indices) +{ + return this->operator|=(indices); +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator-=(const PackedList<1>& lst) +{ + this->modulo(lst); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator-=(const UList<label>& indices) +{ + unset(indices); + return *this; +} + + +inline Foam::PackedBoolList& +Foam::PackedBoolList::operator-=(const UIndirectList<label>& indices) +{ + unset(indices); + return *this; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C index 6bc8d79eada3b2a37b8126829d3d67a8182a2d27..b077c1c54b94cfdd5ff872b35ac44f882aeb6013 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C @@ -33,7 +33,10 @@ Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val) StorageList(packedLength(size), 0u), size_(size) { - operator=(val); + if (val) + { + operator=(val); + } } @@ -82,25 +85,11 @@ unsigned int Foam::PackedList<nBits>::count() const if (size_) { - // mask value for complete segments - unsigned int mask = maskLower(packing()); - - const unsigned int endSeg = size_ / packing(); - const unsigned int endOff = size_ % packing(); - - // count bits in complete segments - for (unsigned i = 0; i < endSeg; ++i) - { - register unsigned int bits = StorageList::operator[](i) & mask; - COUNT_PACKEDBITS(c, bits); - } + const label packLen = packedLength(size_); - // count bits in partial segment - if (endOff) + for (label i = 0; i < packLen; ++i) { - mask = maskLower(endOff); - - register unsigned int bits = StorageList::operator[](endSeg) & mask; + register unsigned int bits = StorageList::operator[](i); COUNT_PACKEDBITS(c, bits); } } @@ -117,64 +106,61 @@ bool Foam::PackedList<nBits>::trim() return false; } - // mask value for complete segments - unsigned int mask = maskLower(packing()); - - label currElem = packedLength(size_) - 1; - unsigned int endOff = size_ % packing(); + const label oldSize = size_; - // clear trailing bits on final segment - if (endOff) + for (label storeI = packedLength(size_) - 1; storeI >= 0; --storeI) { - StorageList::operator[](currElem) &= maskLower(endOff); - } + size_ = storeI * packing(); + unsigned int bits = StorageList::operator[](storeI); - // test entire segment - while (currElem > 0 && !(StorageList::operator[](currElem) &= mask)) - { - currElem--; - } - - // test segment - label newsize = (currElem + 1) * packing(); - - // mask for the final segment - mask = max_value() << (nBits * (packing() - 1)); - - for (endOff = packing(); endOff >= 1; --endOff, --newsize) - { - if (StorageList::operator[](currElem) & mask) + // found some bits + if (bits) { + while (bits) + { + bits >>= nBits; + ++size_; + } break; } - - mask >>= nBits; } - if (size_ == newsize) - { - return false; - } - - size_ = newsize; - return false; + return (size_ != oldSize); } template<unsigned nBits> void Foam::PackedList<nBits>::flip() { - label packLen = packedLength(size_); + if (!size_) + { + return; + } + + // mask value for complete segments + const unsigned int mask = maskLower(packing()); + + const label packLen = packedLength(size_); + for (label i=0; i < packLen; ++i) + { + StorageList::operator[](i) = mask & ~StorageList::operator[](i); + } - for (label i=0; i < packLen; i++) + // mask off the final partial segment { - StorageList::operator[](i) = ~StorageList::operator[](i); + const unsigned int off = size_ % packing(); + if (off) + { + const unsigned int seg = size_ / packing(); + + StorageList::operator[](seg) &= maskLower(off); + } } } template<unsigned nBits> -Foam::labelList Foam::PackedList<nBits>::values() const +Foam::Xfer<Foam::labelList> Foam::PackedList<nBits>::values() const { labelList elems(size_); @@ -182,7 +168,8 @@ Foam::labelList Foam::PackedList<nBits>::values() const { elems[i] = get(i); } - return elems; + + return elems.xfer(); } @@ -201,7 +188,11 @@ Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const template<unsigned nBits> -Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const +Foam::Ostream& Foam::PackedList<nBits>::print +( + Ostream& os, + const bool fullOutput +) const { const label packLen = packedLength(size_); @@ -215,45 +206,56 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const // mask value for complete segments unsigned int mask = maskLower(packing()); + const label outputLen = fullOutput ? StorageList::size() : packLen; - for (label i=0; i < packLen; i++) + for (label i=0; i < outputLen; ++i) { const StorageType& rawBits = StorageList::operator[](i); // the final segment may not be full, modify mask accordingly - if (i+1 == packLen) + if (i == packLen-1) { - unsigned int endOff = size_ % packing(); + const unsigned int off = size_ % packing(); - if (endOff) - { - mask = maskLower(endOff); - } - else + if (off) { - continue; + mask = maskLower(off); } } + else if (i == packLen) + { + // no mask for unaddressed bit + mask = 0u; + } + for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1) { if (mask & testBit) { + // addressable region if (rawBits & testBit) { - os << '1'; + os << '1'; } else { - os << '-'; + os << '-'; } } else { - os << 'x'; + if (rawBits & testBit) + { + os << '!'; + } + else + { + os << '.'; + } } } - os << '\n'; + os << '\n'; } os << ")\n"; @@ -264,15 +266,18 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<unsigned nBits> -void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst) +Foam::PackedList<nBits>& +Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst) { StorageList::operator=(lst); size_ = lst.size(); + return *this; } template<unsigned nBits> -void Foam::PackedList<nBits>::operator=(const UList<label>& lst) +Foam::PackedList<nBits>& +Foam::PackedList<nBits>::operator=(const UList<label>& lst) { setCapacity(lst.size()); size_ = lst.size(); @@ -281,19 +286,8 @@ void Foam::PackedList<nBits>::operator=(const UList<label>& lst) { set(i, lst[i]); } + return *this; } -// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // - -//template<unsigned nBits> -//Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst) -//{ -// os << lst(); -// return os; -//} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index 76c0e97b80924e905048006b10702faf7c2cd05d..2adb939e4d3f01eeda356b0e0d817d4e83d8db63 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -72,6 +72,10 @@ Note list[8] = 1; @endcode + Also note that all unused internal storage elements are guaranteed to + always be bit-wise zero. This property must not be violated by any + inheriting classes. + SeeAlso Foam::DynamicList @@ -114,12 +118,19 @@ class PackedList : private List<unsigned int> { +protected: + typedef unsigned int StorageType; typedef List<StorageType> StorageList; - //- nBits must be positive (non-zero) and fit within the storage - // For simplicity, assume 8-bit bytes - StaticAssert(nBits && nBits < (sizeof(StorageType) << 3)); +private: + + //- nBits must be positive (non-zero) and fit within the storage. + // For efficiency, however, require packing at least 2 items otherwise + // it is more efficient to use a normal list. + // Thus max nBits is 1/2 of the base storage size. + // For simplicity, assume 8-bit bytes in the assert. + StaticAssert(nBits && nBits <= (sizeof(StorageType) << 2)); // Private data @@ -163,20 +174,20 @@ public: //- Null constructor inline PackedList(); - //- Construct with given size, initializes list to 0. + //- Construct with given size, initializes list to 0 explicit inline PackedList(const label size); - //- Construct with given size and value for all elements. + //- Construct with given size and value for all elements PackedList(const label size, const unsigned val); - //- Copy constructor. + //- Copy constructor inline PackedList(const PackedList<nBits>&); //- Construct by transferring the parameter contents inline PackedList(const Xfer<PackedList<nBits> >&); //- Construct from a list of labels - explicit PackedList(const UList<label>&); + explicit inline PackedList(const UList<label>&); //- Clone inline autoPtr< PackedList<nBits> > clone() const; @@ -209,6 +220,7 @@ public: inline bool unset(const label); //- Return the underlying packed storage + // Manipulate with utmost caution inline List<unsigned int>& storage(); //- Return the underlying packed storage @@ -219,20 +231,30 @@ public: // http://en.wikipedia.org/wiki/Hamming_weight unsigned int count() const; - //- Return the values as a labelList - labelList values() const; + //- Return the values as a list of labels + Xfer<labelList> values() const; - //- Print values and information - Ostream& print(Ostream&) const; + //- Print values and information, optionally output unused elements + // + // addressable bits: + // on: '1', off: '-' + // + // non-addressable bits: + // on: '!', off: '.' + // + Ostream& print(Ostream&, const bool fullOutput=false) const; // Edit //- Trim any trailing zero elements bool trim(); - //- Invert the bits in the addressable region. + //- Invert the bits in the addressable region void flip(); + //- Clear all bits + inline void reset(); + //- Alter the size of the underlying storage. // The addressed size will be truncated if needed to fit, but will // remain otherwise untouched. @@ -240,10 +262,10 @@ public: //- Reset addressable list size, does not shrink the allocated size. // Optionally specify a value for new elements. - inline void resize(const label, const unsigned int& val = 0); + inline void resize(const label, const unsigned int& val = 0u); //- Alias for resize() - inline void setSize(const label, const unsigned int& val = 0); + inline void setSize(const label, const unsigned int& val = 0u); //- Reserve allocation space for at least this size. // Never shrinks the allocated size. @@ -287,23 +309,13 @@ public: inline iteratorBase operator[](const label); //- Assignment of all entries to the given value. Takes linear time. - inline void operator=(const unsigned int val); + inline PackedList<nBits>& operator=(const unsigned int val); //- Assignment operator. Takes linear time. - void operator=(const PackedList<nBits>&); + PackedList<nBits>& operator=(const PackedList<nBits>&); //- Assignment operator. Takes linear time. - void operator=(const UList<label>&); - - - // Ostream operator - - // // Write PackedList to Ostream. - // friend Ostream& operator<< <nBits> - // ( - // Ostream&, - // const PackedList<nBits>& - // ); + PackedList<nBits>& operator=(const UList<label>&); // Iterators and helpers @@ -347,6 +359,12 @@ public: public: + // Member Functions + + //- Return the element index corresponding to the iterator + inline label key() const; + + // Member Operators //- Compare values (not positions) @@ -376,11 +394,12 @@ public: public iteratorBase { - //- Disallow copy constructor from const_iterator - - // violates const-ness! + //- Disallow copy constructor from const_iterator + // This would violate const-ness! iterator(const const_iterator&); - //- Disallow assignment from const_iterator - violates const-ness! + //- Disallow assignment from const_iterator + // This would violate const-ness! void operator=(const const_iterator&); diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H index c3059a142fc6c773e77ffe752f0453362040c586..4b42056cc31e02963b7877cd1c06137e95c2bc1a 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H @@ -151,27 +151,34 @@ Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val) const unsigned int seg = index_ / packing(); const unsigned int off = index_ % packing(); + const unsigned int startBit = nBits * off; + const unsigned int mask = max_value() << startBit; + unsigned int& stored = list_->StorageList::operator[](seg); const unsigned int prev = stored; - const unsigned int startBit = nBits * off; - const unsigned int maskNew = max_value() << startBit; - - if (val & ~max_value()) + if (val >= max_value()) { // overflow is max_value, fill everything - stored |= maskNew; + stored |= mask; } else { - stored &= ~maskNew; - stored |= maskNew & (val << startBit); + stored &= ~mask; + stored |= mask & (val << startBit); } return prev != stored; } +template<unsigned nBits> +inline Foam::label Foam::PackedList<nBits>::iteratorBase::key() const +{ + return index_; +} + + template<unsigned nBits> inline bool Foam::PackedList<nBits>::iteratorBase::operator== ( @@ -564,24 +571,27 @@ inline bool Foam::PackedList<nBits>::empty() const template<unsigned nBits> inline void Foam::PackedList<nBits>::resize ( - const label nElem, + const label newSize, const unsigned int& val ) { - reserve(nElem); + reserve(newSize); + + const label oldSize = size_; + size_ = newSize; - if (nElem > size_) + if (size_ > oldSize) { // fill new elements or newly exposed elements - if (size_) + if (val) { // fill value for complete segments unsigned int fill = val; - if (fill & ~max_value()) + if (val >= max_value()) { - // overflow is max_value, fill everything - fill = ~0u; + // fill everything + fill = maskLower(packing()); } else { @@ -591,36 +601,64 @@ inline void Foam::PackedList<nBits>::resize } } - unsigned int seg = size_ / packing(); - unsigned int off = size_ % packing(); - - // partial segment, preserve existing value - if (off) + // fill in complete segments + const label oldLen = packedLength(oldSize); + const label newLen = packedLength(size_); + for (label i=oldLen; i < newLen; ++i) { - unsigned int maskOld = maskLower(off); + StorageList::operator[](i) = fill; + } - StorageList::operator[](seg) &= maskOld; - StorageList::operator[](seg) |= ~maskOld & fill; + // finish previous partial segment, preserve existing value + { + const unsigned int off = oldSize % packing(); + if (off) + { + const unsigned int seg = oldSize / packing(); + const unsigned int mask = maskLower(off); - // continue with the next segment - seg++; + StorageList::operator[](seg) &= mask; + StorageList::operator[](seg) |= ~mask & fill; + } } - unsigned int endSeg = nElem / packing(); - // fill in complete elements - while (seg < endSeg) + + // mask off the (new) final partial segment { - StorageList::operator[](seg++) = fill; + const unsigned int off = size_ % packing(); + if (off) + { + const unsigned int seg = size_ / packing(); + + StorageList::operator[](seg) &= maskLower(off); + } } } - else + } + else if (size_ < oldSize) + { + // resize shrinking + // - clear newly exposed elements + + // fill in complete segments + const label oldLen = packedLength(oldSize); + const label newLen = packedLength(size_); + for (label i=newLen; i < oldLen; ++i) { - // no original size - simply flood-fill - operator=(val); + StorageList::operator[](i) = 0u; } - } - size_ = nElem; + // mask off the final partial segment + { + const unsigned int off = size_ % packing(); + if (off) + { + const unsigned int seg = size_ / packing(); + + StorageList::operator[](seg) &= maskLower(off); + } + } + } } @@ -648,10 +686,19 @@ inline void Foam::PackedList<nBits>::setCapacity(const label nElem) { StorageList::setSize(packedLength(nElem), 0u); - // truncate addressed size too? + // truncate addressed size too if (size_ > nElem) { size_ = nElem; + + // mask off the final partial segment + const unsigned int off = size_ % packing(); + if (off) + { + const unsigned int seg = size_ / packing(); + + StorageList::operator[](seg) &= maskLower(off); + } } } @@ -662,7 +709,7 @@ inline void Foam::PackedList<nBits>::reserve const label nElem ) { - label len = packedLength(nElem); + const label len = packedLength(nElem); // need more capacity? if (len > StorageList::size()) @@ -681,9 +728,17 @@ inline void Foam::PackedList<nBits>::reserve } +template<unsigned nBits> +inline void Foam::PackedList<nBits>::reset() +{ + StorageList::operator=(0u); +} + + template<unsigned nBits> inline void Foam::PackedList<nBits>::clear() { + reset(); size_ = 0; } @@ -699,7 +754,7 @@ inline void Foam::PackedList<nBits>::clearStorage() template<unsigned nBits> inline void Foam::PackedList<nBits>::shrink() { - label len = packedLength(size_); + const label len = packedLength(size_); // we have unused space? if (len < StorageList::size()) @@ -820,7 +875,7 @@ inline bool Foam::PackedList<nBits>::unset(const label i) template<unsigned nBits> inline void Foam::PackedList<nBits>::append(const unsigned int val) { - label elemI = size_; + const label elemI = size_; reserve(elemI + 1); size_++; @@ -855,35 +910,20 @@ Foam::PackedList<nBits>::operator[](const label i) } -namespace Foam -{ - // specialization for nBits=1 - template<> - inline void Foam::PackedList<1>::operator=(const unsigned int val) - { - if (val) - { - StorageList::operator=(~0u); - } - else - { - StorageList::operator=(0u); - } - } -} - - template<unsigned nBits> -inline void Foam::PackedList<nBits>::operator=(const unsigned int val) +inline Foam::PackedList<nBits>& +Foam::PackedList<nBits>::operator=(const unsigned int val) { - if (val) + const label packLen = packedLength(size_); + + if (val && size_) { unsigned int fill = val; - if (fill & ~max_value()) + if (val >= max_value()) { - // treat overflow as max_value - fill = ~0u; + // fill everything + fill = maskLower(packing()); } else { @@ -893,12 +933,31 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val) } } - StorageList::operator=(fill); + for (label i=0; i < packLen; ++i) + { + StorageList::operator[](i) = fill; + } + + // mask off the final partial segment + { + const unsigned int off = size_ % packing(); + if (off) + { + const unsigned int seg = size_ / packing(); + + StorageList::operator[](seg) &= maskLower(off); + } + } } else { - StorageList::operator=(0u); + for (label i=0; i < packLen; ++i) + { + StorageList::operator[](i) = 0u; + } } + + return *this; } diff --git a/src/OpenFOAM/primitives/Lists/PackedBoolList.H b/src/OpenFOAM/primitives/Lists/PackedBoolList.H deleted file mode 100644 index 7dd2c81b7c70cb1a47917b5bcaeb1324ed3324ed..0000000000000000000000000000000000000000 --- a/src/OpenFOAM/primitives/Lists/PackedBoolList.H +++ /dev/null @@ -1,49 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd. - \\/ M anipulation | -------------------------------------------------------------------------------- -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/>. - -Typedef - Foam::PackedBoolList - -Description - A bit-packed bool list - -\*---------------------------------------------------------------------------*/ - -#ifndef PackedBoolList_H -#define PackedBoolList_H - -#include "bool.H" -#include "PackedList.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - typedef PackedList<> PackedBoolList; -} - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* //