diff --git a/applications/test/PackedList/Test-PackedList.C b/applications/test/PackedList/Test-PackedList.C index 90ed8ac740810c7669a892d355c13ed1580016c6..45d5ab00b6e8333a30cc181b2cfc4b508096696b 100644 --- a/applications/test/PackedList/Test-PackedList.C +++ b/applications/test/PackedList/Test-PackedList.C @@ -41,7 +41,7 @@ using namespace Foam; template<unsigned nBits> inline void reportInfo() { - unsigned offset = PackedList<nBits>::packing(); + const unsigned offset = PackedList<nBits>::packing(); unsigned useSHL = ((1u << (nBits * offset)) - 1); unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset)); diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C index 4b01a43dd61ecff39fb00d54168ea8af5f37589b..543c5b855843521d521ef93079106683bc03ebb0 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C @@ -92,13 +92,15 @@ bool Foam::PackedBoolList::bitorPrepare template<class LabelListType> Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices) { - // no better information, just guess something about the size - reserve(indices.size()); + const label len = indices.size(); + + // No better information, just guess something from the size + reserve(len); label cnt = 0; - forAll(indices, elemI) + for (label i = 0; i < len; ++i) { - if (set(indices[elemI])) + if (set(indices[i])) { ++cnt; } @@ -112,9 +114,10 @@ template<class LabelListType> Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices) { label cnt = 0; - forAll(indices, elemI) + const label len = indices.size(); + for (label i = 0; i < len; ++i) { - if (unset(indices[elemI])) + if (unset(indices[i])) { ++cnt; } @@ -127,29 +130,30 @@ Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices) template<class LabelListType> Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices) { - // handle trivial case - if (empty() || indices.empty()) + const label len = indices.size(); + + // Handle trivial case + if (empty() || !len) { clear(); return 0; } - // normal case - PackedBoolList anded; - anded.reserve(size()); + PackedBoolList result; + result.reserve(size()); label cnt = 0; - forAll(indices, elemI) + for (label i = 0; i < len; ++i) { - const label& index = indices[elemI]; - if (operator[](index)) + const label index = indices[i]; + if (get(index)) { - anded.set(index); + result.set(index); ++cnt; } } - transfer(anded); + transfer(result); return cnt; } @@ -176,7 +180,7 @@ void Foam::PackedBoolList::set(const PackedList<1>& lst) StorageList& lhs = this->storage(); const StorageList& rhs = lst.storage(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] |= rhs[i]; } @@ -209,7 +213,7 @@ void Foam::PackedBoolList::unset(const PackedList<1>& lst) // overlapping storage size const label len = min(this->packedLength(), lst.packedLength()); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] &= ~rhs[i]; } @@ -242,7 +246,7 @@ void Foam::PackedBoolList::subset(const PackedList<1>& lst) const label len = this->packedLength(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] &= rhs[i]; } @@ -288,12 +292,13 @@ Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const void Foam::PackedBoolList::operator=(const UList<bool>& lst) { - this->setSize(lst.size()); + const label len = lst.size(); + this->setSize(len); - // overwrite with new true/false values - forAll(*this, elemI) + // Overwrite with new true/false values + for (label i = 0; i < len; ++i) { - set(elemI, lst[elemI]); + set(i, lst[i]); } } @@ -301,15 +306,15 @@ void Foam::PackedBoolList::operator=(const UList<bool>& lst) Foam::PackedBoolList& Foam::PackedBoolList::operator^=(const PackedList<1>& lst) { - // extend addressable area if needed, return maximum size possible + // Extend addressable area if needed, return maximum size possible label len = 0; const bool needTrim = bitorPrepare(lst, len); - // operate directly with the underlying storage + // Operate directly with the underlying storage StorageList& lhs = this->storage(); const StorageList& rhs = lst.storage(); - for (label i=0; i < len; ++i) + for (label i = 0; i < len; ++i) { lhs[i] ^= rhs[i]; } @@ -334,7 +339,7 @@ Foam::PackedBoolList Foam::operator& PackedBoolList result(lst1); result &= lst2; - // trim to bits actually used + // Trim to bits actually used result.trim(); return result; @@ -350,7 +355,7 @@ Foam::PackedBoolList Foam::operator^ PackedBoolList result(lst1); result ^= lst2; - // trim to bits actually used + // Trim to bits actually used result.trim(); return result; diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H index f98545a9bd64e3270c8d894564c5eed5f304dce1..a667e8aecf17f4d3ea49b4f3c67b242a84c22ce7 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -96,7 +96,7 @@ public: //- Construct from Istream PackedBoolList(Istream& is); - //- Construct with given size, initializes list to 0 + //- Construct with given size, initializes list to 0 (false) explicit inline PackedBoolList(const label size); //- Construct with given size and value for all elements @@ -114,6 +114,20 @@ public: //- Construct by transferring the parameter contents inline PackedBoolList(const Xfer<PackedList<1>>& lst); + //- Construct with given size and list of labels to set as true. + inline PackedBoolList + ( + const label size, + const labelUList& indices + ); + + //- Construct with given size and list of labels to set as true. + inline PackedBoolList + ( + const label size, + const UIndirectList<label>& indices + ); + //- Construct from a list of bools explicit inline PackedBoolList(const UList<bool>& lst); diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H index a0702f9a30e92aced06170a0feb317eb92408b2c..4c713dc005d4358aa4210ab47e3d9edf7883f869 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -75,23 +75,52 @@ inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1>>& lst) inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst) : - PackedList<1>() + PackedList<1>(lst.size()) { - operator=(lst); + // Set according to indices that are true + const label len = lst.size(); + + for (label i = 0; i < len; ++i) + { + if (lst[i]) + { + this->set(i, 1u); + } + } } inline Foam::PackedBoolList::PackedBoolList(const labelUList& indices) : - PackedList<1>(indices.size(), 0u) + PackedBoolList(indices.size(), indices) +{} + + +inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices) +: + PackedBoolList(indices.size(), indices) +{} + + +inline Foam::PackedBoolList::PackedBoolList +( + const label size, + const labelUList& indices +) +: + PackedList<1>(size) { set(indices); } -inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices) +inline Foam::PackedBoolList::PackedBoolList +( + const label size, + const UIndirectList<label>& indices +) : - PackedList<1>(indices.size(), 0u) + PackedList<1>(size) { set(indices); } diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index 18720fc2ae929fc8bd697161550eae1ea68a5d87..ee03e4ad27a71fddb7a3d69d05d2b6935ceb56f0 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -48,8 +48,9 @@ Note list[1] = list[5] = list[6]; // propagates value \endcode - Using get() or the '[]' operator are similarly fast. Looping and reading - via an iterator is approx. 15% slower, but can be more flexible. + Reading via the get() or the '[]' operator are identical. + Looping and reading via an iterator is approx. 15% slower, + but can be more flexible. Using the set() operator (and the '[]' operator) are marginally slower (approx. 5%) than using an iterator, but the set() method has the @@ -157,7 +158,7 @@ protected: // Protected Member Functions //- Calculate the list length when packed - inline static label packedLength(const label); + inline static label packedLength(const label nElem); //- Read a list entry (allows for specialization) inline static unsigned int readValue(Istream& is); @@ -200,14 +201,14 @@ public: //- The max. number of bits that can be templated. // Might someday be useful for a template assert. - inline static unsigned int max_bits(); + inline static constexpr unsigned int max_bits(); //- The max. value for an entry, which simultaneously the bit-mask // eg, ((1 << 2) - 1) yields 0b0011 - inline static unsigned int max_value(); + inline static constexpr unsigned int max_value(); //- The number of entries per packed storage element - inline static unsigned int packing(); + inline static constexpr unsigned int packing(); //- Masking for all bits below the offset inline static unsigned int maskLower(unsigned offset); @@ -393,11 +394,11 @@ public: //- Remove and return the last element inline unsigned int remove(); - //- Get value at index I + //- Identical to get() - get value at index. // Never auto-vivify entries. inline unsigned int operator[](const label i) const; - //- Set value at index I. + //- Non-const access to value at index. // Returns iterator to perform the actual operation. // Does not auto-vivify entries, but will when assigned to. inline iteratorBase operator[](const label i); @@ -496,11 +497,11 @@ public: //- Disallow copy constructor from const_iterator // This would violate const-ness! - iterator(const const_iterator& iter); + iterator(const const_iterator& iter) = delete; //- Disallow assignment from const_iterator // This would violate const-ness! - void operator=(const const_iterator& iter); + void operator=(const const_iterator& iter) = delete; public: diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H index ad136b903fafd6ba25109c81b339274985f01bab..4f9c58644ad29ef91da1fbfba10b911db1196df8 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,24 +25,24 @@ License #include <climits> -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::max_bits() +inline constexpr unsigned int Foam::PackedList<nBits>::max_bits() { return sizeof(StorageType)*CHAR_BIT - 1; } template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::max_value() +inline constexpr unsigned int Foam::PackedList<nBits>::max_value() { return (1u << nBits) - 1; } template<unsigned nBits> -inline unsigned int Foam::PackedList<nBits>::packing() +inline constexpr unsigned int Foam::PackedList<nBits>::packing() { return sizeof(StorageType)*CHAR_BIT / nBits; } @@ -65,6 +65,8 @@ inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem) } +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + namespace Foam { // Template specialization for bool entries @@ -88,13 +90,10 @@ namespace Foam if (this->get()) { os << index_; - return true; } - else - { - return false; - } + + return false; } } @@ -119,12 +118,12 @@ inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is) template<unsigned nBits> inline void Foam::PackedList<nBits>::setPair(Istream& is) { - is.readBegin("Tuple2<label, unsigned int>"); + is.readBegin("Tuple2<label,unsigned int>"); const label ind = readLabel(is); const unsigned int val = readLabel(is); - is.readEnd("Tuple2<label, unsigned int>"); + is.readEnd("Tuple2<label,unsigned int>"); if (val > max_value()) { @@ -154,10 +153,8 @@ inline bool Foam::PackedList<nBits>::iteratorBase::writeIfSet(Ostream& os) const return true; } - else - { - return false; - } + + return false; } @@ -233,7 +230,8 @@ inline Foam::PackedList<nBits>::PackedList(const labelUList& lst) StorageList(packedLength(lst.size()), 0u), size_(lst.size()) { - forAll(lst, i) + const label len = lst.size(); + for (label i = 0; i < len; ++i) { set(i, lst[i]); } @@ -247,7 +245,8 @@ inline Foam::PackedList<nBits>::PackedList(const UIndirectList<label>& lst) StorageList(packedLength(lst.size()), 0u), size_(lst.size()) { - forAll(lst, i) + const label len = lst.size(); + for (label i = 0; i < len; ++i) { set(i, lst[i]); } @@ -862,16 +861,16 @@ inline void Foam::PackedList<nBits>::reserve(const label nElem) { const label len = packedLength(nElem); - // Need more capacity? + // Allocate more capacity if necessary if (len > StorageList::size()) { - // Like DynamicList with SizeInc=0, SizeMult=2, SizeDiv=1 StorageList::setSize ( max ( len, - StorageList::size()*2 + // SizeInc=0, SizeMult=2, SizeDiv=1 + 2 * StorageList::size() ), 0u ); @@ -964,27 +963,17 @@ inline unsigned int Foam::PackedList<nBits>::get(const label i) const // Lazy evaluation - return 0 for out-of-range if (i < 0 || i >= size_) { - return 0; - } - else - { - return iteratorBase(this, i).get(); + return 0u; } + + return iteratorBase(this, i).get(); } template<unsigned nBits> inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const { - // Lazy evaluation - return 0 for out-of-range - if (i < 0 || i >= size_) - { - return 0; - } - else - { - return iteratorBase(this, i).get(); - } + return get(i); } @@ -1024,10 +1013,8 @@ inline bool Foam::PackedList<nBits>::unset(const label i) { return false; } - else - { - return iteratorBase(this, i).set(0u); - } + + return iteratorBase(this, i).set(0u); } @@ -1035,11 +1022,11 @@ template<unsigned nBits> inline Foam::PackedList<nBits>& Foam::PackedList<nBits>::append(const unsigned int val) { - const label elemI = size_; - reserve(elemI + 1); + const label idx = size_; + reserve(idx + 1); size_++; - iteratorBase(this, elemI).set(val); + iteratorBase(this, idx).set(val); return *this; } @@ -1047,15 +1034,17 @@ Foam::PackedList<nBits>::append(const unsigned int val) template<unsigned nBits> inline unsigned int Foam::PackedList<nBits>::remove() { - if (!size_) + // Location of last element and simultaneously the new size + const label idx = size_ - 1; + + if (idx < 0) { FatalErrorInFunction << "List is empty" << abort(FatalError); } - label elemI = size_ - 1; - const unsigned int val = iteratorBase(this, elemI).get(); - resize(elemI); + const unsigned int val = iteratorBase(this, idx).get(); + resize(idx); return val; }