diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C index e598337b07b68d0d05e797af285554964518dc80..f1f58f3abcad7d5450102a969c996664934c448f 100644 --- a/applications/test/PackedList/PackedListTest.C +++ b/applications/test/PackedList/PackedListTest.C @@ -52,25 +52,29 @@ int main(int argc, char *argv[]) list1 = -1; list1.print(Info); - Info<< "\ntest assign between references - does not work as expected\n"; + Info<< "\ntest assign between references\n"; list1[2] = 3; list1[4] = list1[2]; list1.print(Info); + Info<< "\ntest assign between references, with chaining\n"; + list1[4] = list1[2] = 1; + list1.print(Info); + { const PackedList<3>& constLst = list1; Info<< "\ntest operator[] const with out-of-range index\n"; constLst.print(Info); if (!constLst[20]) { - Info<< "[20] is false, as expected\n"; + Info<< "[20] is false (expected) list size should be unchanged (const)\n"; } constLst.print(Info); Info<< "\ntest operator[] non-const with out-of-range index\n"; if (!list1[20]) { - Info<< "[20] is false, as expected but list was resized!! (non-const)\n"; + Info<< "[20] is false (expected) but list was resized?? (non-const)\n"; } list1.print(Info); } @@ -145,6 +149,10 @@ int main(int argc, char *argv[]) list1.setCapacity(24); list1.print(Info); + Info<< "\ntest resize much smaller\n"; + list1.resize(150); + list1.print(Info); + Info<< "\ntest trim\n"; list1.trim(); list1.print(Info); @@ -159,13 +167,16 @@ int main(int argc, char *argv[]) Info<< "begin():"; iter.print(Info) << "\n"; - Info<< "\ntest iterator operator=\n"; - iter = 2; - Info<< "iterator:" << iter() << "\n"; - iter = 5; + iter() = 5; + iter.print(Info); list1.print(Info); + iter = list1[31]; + Info<< "iterator:" << iter() << "\n"; + iter.print(Info); + + Info<< "\ntest get() method\n"; Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n"; list1.print(Info); @@ -173,25 +184,34 @@ int main(int argc, char *argv[]) Info<< "\ntest iterator indexing\n"; Info<< "cend() "; list1.cend().print(Info) << "\n"; - + + { + Info<< "\ntest assignment of iterator\n"; + list1.print(Info); + PackedList<3>::iterator cit = list1[25]; + cit.print(Info); + list1.end().print(Info); + } + + for ( - PackedList<3>::const_iterator cit = list1[30]; - cit != list1.cend(); + PackedList<3>::iterator cit = list1[5]; + cit != list1.end(); ++cit ) { cit.print(Info); } - Info<< "\ntest operator[] auto-vivify\n"; - const unsigned int val = list1[45]; - - Info<< "list[45]:" << val << "\n"; - list1[45] = list1.max_value(); - Info<< "list[45]:" << list1[45] << "\n"; - list1[49] = list1.max_value(); - list1.print(Info); +// Info<< "\ntest operator[] auto-vivify\n"; +// const unsigned int val = list1[45]; +// +// Info<< "list[45]:" << val << "\n"; +// list1[45] = list1.max_value(); +// Info<< "list[45]:" << list1[45] << "\n"; +// list1[49] = list1.max_value(); +// list1.print(Info); Info<< "\ntest copy constructor + append\n"; diff --git a/applications/test/PackedList2/PackedListTest2.C b/applications/test/PackedList2/PackedListTest2.C index 61bd2530db3dca8cef56e4f0827f1feb75b378ae..22282058ac741a50d2a3366083a9091f55012153 100644 --- a/applications/test/PackedList2/PackedListTest2.C +++ b/applications/test/PackedList2/PackedListTest2.C @@ -61,8 +61,8 @@ int main(int argc, char *argv[]) } cpuTime timer; - - for (label iter = 0; iter < nIters; iter++) + + for (label iter = 0; iter < nIters; ++iter) { packed.resize(40); packed.shrink(); @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) // Count packed sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(packed, i) { @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) // Count packed sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { sum += packed.count(); } @@ -101,7 +101,7 @@ int main(int argc, char *argv[]) // Dummy addition sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(unpacked, i) { @@ -117,7 +117,7 @@ int main(int argc, char *argv[]) // Read stl sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { for(unsigned int i = 0; i < stlVector.size(); i++) { @@ -130,7 +130,7 @@ int main(int argc, char *argv[]) // Read unpacked sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(unpacked, i) { @@ -143,7 +143,7 @@ int main(int argc, char *argv[]) // Read packed sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(packed, i) { @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) // Read packed sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(packed, i) { @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) // Read via iterator sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { for ( @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) // Read via iterator sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { for ( @@ -209,7 +209,7 @@ int main(int argc, char *argv[]) // Read empty hash sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(unpacked, i) { @@ -223,7 +223,7 @@ int main(int argc, char *argv[]) // Read full hash sum = 0; - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(unpacked, i) { @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) // // Write stl - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { for (unsigned int i = 0; i < stlVector.size(); i++) { @@ -250,7 +250,7 @@ int main(int argc, char *argv[]) Info<< "Writing stl:" << timer.cpuTimeIncrement() << " s" << endl; // Write unpacked - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(unpacked, i) { @@ -261,7 +261,7 @@ int main(int argc, char *argv[]) // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(packed, i) { @@ -273,7 +273,7 @@ int main(int argc, char *argv[]) // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { forAll(packed, i) { @@ -283,25 +283,9 @@ int main(int argc, char *argv[]) Info<< "Writing packed using set:" << timer.cpuTimeIncrement() << " s" << endl; - // Write packed - for (label iter = 0; iter < nIters; iter++) - { - for - ( - PackedBoolList::iterator it = packed.begin(); - it != packed.end(); - ++it - ) - { - it = 1; - } - } - Info<< "Writing packed using iterator:" << timer.cpuTimeIncrement() - << " s" << endl; - // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { for ( @@ -313,12 +297,12 @@ int main(int argc, char *argv[]) it() = 1; } } - Info<< "Writing packed using iteratorRef:" << timer.cpuTimeIncrement() + Info<< "Writing packed using iterator:" << timer.cpuTimeIncrement() << " s" << endl; // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { packed = 0; } @@ -327,7 +311,7 @@ int main(int argc, char *argv[]) // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { packed = 1; } @@ -338,7 +322,7 @@ int main(int argc, char *argv[]) PackedList<3> oddPacked(n, 3); // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { packed = 0; } @@ -347,14 +331,14 @@ int main(int argc, char *argv[]) // Write packed - for (label iter = 0; iter < nIters; iter++) + for (label iter = 0; iter < nIters; ++iter) { packed = 1; } Info<< "Writing packed<3> uniform 1:" << timer.cpuTimeIncrement() << " s" << endl; - + Info << "End\n" << endl; return 0; diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C index ced308eaffdea21eeef61fbe7c5f37fb521faa8d..0cf022e77be6fbe4fbbbca490f39fea435bde416 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C @@ -84,7 +84,7 @@ unsigned int Foam::PackedList<nBits>::count() const if (size_) { // mask value for complete chunks - unsigned int mask = (0x1 << (nBits * packing())) - 1; + unsigned int mask = maskLower(packing()); unsigned int endIdx = size_ / packing(); unsigned int endOff = size_ % packing(); @@ -99,7 +99,7 @@ unsigned int Foam::PackedList<nBits>::count() const // count bits in partial chunk if (endOff) { - mask = (0x1 << (nBits * endOff)) - 1; + mask = maskLower(endOff); register unsigned int bits = StorageList::operator[](endIdx) & mask; COUNT_PACKEDBITS(c, bits); @@ -119,7 +119,7 @@ bool Foam::PackedList<nBits>::trim() } // mask value for complete chunks - unsigned int mask = (0x1 << (nBits * packing())) - 1; + unsigned int mask = maskLower(packing()); label currElem = packedLength(size_) - 1; unsigned int endOff = size_ % packing(); @@ -127,7 +127,7 @@ bool Foam::PackedList<nBits>::trim() // clear trailing bits on final segment if (endOff) { - StorageList::operator[](currElem) &= ((0x1 << (nBits * endOff)) - 1); + StorageList::operator[](currElem) &= maskLower(endOff); } // test entire chunk @@ -176,7 +176,7 @@ Foam::labelList Foam::PackedList<nBits>::values() const template<int nBits> -Foam::Ostream& Foam::PackedList<nBits>::const_iterator::print(Ostream& os) const +Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const { os << "iterator<" << nBits << "> [" << (index_ * packing() + offset_) << "]" @@ -206,7 +206,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const << "storage: " << packLen << "/" << StorageList::size() << "( "; // mask value for complete chunks - unsigned int mask = (0x1 << (nBits * packing())) - 1; + unsigned int mask = maskLower(packing()); for (label i=0; i < packLen; i++) { @@ -219,7 +219,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const if (endOff) { - mask = (0x1 << (nBits * endOff)) - 1; + mask = maskLower(endOff); } else { @@ -227,7 +227,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const } } - for (unsigned int testBit = 0x1 << max_bits(); testBit; testBit >>= 1) + for (unsigned int testBit = (1 << max_bits()); testBit; testBit >>= 1) { if (testBit & mask) { diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H index eef440c5c7c195bc6a6b6b64de1f05d0dab97dcb..14be22367d09021bba4900fd2d1e921bcf53287b 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H @@ -35,21 +35,32 @@ Description The number of bits per item is specified by the template parameter nBits. Note - The iterator '()' dereferencing operator returns a proxy class that handles - assignment. However, the iterator itself can also handle assignment - directly, but does not return anything. - Thus the following bit of code works as expected: + In a const context, the '[]' operator simply returns the stored value, + with out-of-range elements returned as zero. + In a non-const context, the '[]' operator returns an iteratorBase, which + may not have a valid reference for out-of-range elements. + The iteratorBase class handles the assignment of new values. + + Using the iteratorBase as a proxy allows assignment of values + between list elements. Thus the following bit of code works as expected: @code - blist[5] = 4; - changed = blist.set(5, 8); - changed = (blist[5] = 1); // ERROR - operator= is 'void' + blist[1] = blist[5]; // value assignment, not iterator position + blist[2] = blist[5] = 4; // propagates value + blist[1] = blist[5] = blist[6]; // propagates value @endcode - Making the assignment operator void prevents people from trying this type - of thing: + Using get() or the '[]' operator are similarly fast. Looping and reading + with 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 an + advantage that it also returns a bool if the value changed. This can be + useful for branching on changed values. + @code - blist[2] = blist[5] = 4; // bad idea, thus ERROR - operator= is 'void' - blist[1] = blist[5]; // iterator not value assignment! + blist[5] = 4; + changed = blist.set(5, 8); + if (changed) ... @endcode SeeAlso @@ -91,7 +102,7 @@ TemplateName(PackedList); Class PackedList Declaration \*---------------------------------------------------------------------------*/ -template <int nBits> +template <int nBits=1> class PackedList : private List<unsigned int> @@ -127,9 +138,12 @@ public: //- The number of entries per packed storage element inline static unsigned int packing(); - // Forward declaration of iterator and const_iterator - class iterator; - class const_iterator; + //- Masking for all bits below the offset + inline static unsigned int maskLower(unsigned offset); + + // Forward declaration of iteratorBase + + class iteratorBase; // Constructors @@ -241,13 +255,13 @@ public: inline unsigned int remove(); //- Get value at index I - // Does not auto-vivify elements. + // Does not auto-vivify entries. inline unsigned int operator[](const label) const; //- Set value at index I. // Returns iterator to perform the actual operation. - // Auto-vivifies any new values to zero. - inline iterator operator[](const label); + // Does not auto-vivify entries. + inline iteratorBase operator[](const label); //- Assignment of all entries to the given value. Takes linear time. inline void operator=(const unsigned int val); @@ -263,11 +277,12 @@ public: // // Write PackedList to Ostream. // friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&); - //- The const_iterator for PackedList - // Note: data and functions are protected, to allow reuse by iterator. - // Try not to be disturbed by non-const methods such as set(), they are - // just inherited and used by iterator. - class const_iterator + // Iterators and helpers + + //- The iterator base for PackedList + // Note: data and functions are protected, to allow reuse by iterator + // and prevent most external usage. + class iteratorBase { friend class PackedList; @@ -275,125 +290,121 @@ public: // Protected Data - //- Pointer to original list - // This also lets us use the default bitwise copy/assignment - PackedList* list_; + //- Pointer to original list + // This also lets us use the default bitwise copy/assignment + PackedList* list_; - //- Element index within storage - unsigned index_; + //- Element index within storage + unsigned index_; - //- Offset within storage element - unsigned offset_; + //- Offset within storage element + unsigned offset_; // Protected Member Functions - //- Get value as unsigned - inline unsigned int get() const; + //- Get value as unsigned + inline unsigned int get() const; - //- Set value, returning true if changed - // This is obviously used by iterator and not by const_iterator - inline bool set(unsigned int); + //- Set value, returning true if changed + inline bool set(unsigned int); - public: + //- Increment to new position + inline void incr(); - // Constructors + //- Decrement to new position + inline void decr(); - //- Construct from base list and position index - inline const_iterator(const PackedList*, const label); + //- Move to new position, but not beyond end() + inline void seek(const iteratorBase&); - //- Construct from non-const iterator - explicit inline const_iterator(const iterator&); - // Member operators + // Constructors - inline bool operator==(const const_iterator&) const; - inline bool operator!=(const const_iterator&) const; + //- Construct null + inline iteratorBase(); - //- Return referenced value directly - inline unsigned int operator*() const; + //- Copy construct + inline iteratorBase(const iteratorBase&); - //- Return referenced value directly - inline unsigned int operator()() const; + //- Construct from base list and position index + inline iteratorBase(const PackedList*, const label); - inline const_iterator& operator++(); - inline const_iterator operator++(int); + public: - inline const_iterator& operator--(); - inline const_iterator operator--(int); + // Member Functions - //- Conversion operator - inline operator unsigned int () const; + //- Return true if the element is within addressable range + inline bool valid() const; - //- Print value and information - Ostream& print(Ostream&) const; - }; + //- Move iterator to end() if it would otherwise be out-of-range + // Returns true if the element was already ok + inline bool validate(); + // Member Operators - //- const_iterator set to the beginning of the PackedList - inline const_iterator cbegin() const; + //- Compare positions + inline bool operator==(const iteratorBase&) const; + inline bool operator!=(const iteratorBase&) const; - //- const_iterator set to beyond the end of the PackedList - inline const_iterator cend() const; + //- Assign value, not position. + // This allows packed[0] = packed[3] for assigning values + inline unsigned int operator=(const iteratorBase&); - //- const_iterator set to the beginning of the PackedList - inline const_iterator begin() const; + //- Assign value + inline unsigned int operator=(const unsigned int val); - //- const_iterator set to beyond the end of the PackedList - inline const_iterator end() const; + //- Conversion operator + inline operator unsigned int () const; + + //- Print value and information + Ostream& print(Ostream&) const; + }; //- The iterator class used for PackedList class iterator : - public const_iterator + public iteratorBase { - friend class PackedList; - //- A proxy reference to the iterator, used for setting values. - // Also provides a uniform target for the iterator 'operator*' - // and 'operator()' methods - class iteratorProxy - { - iterator* iter_; - public: + //- Should never violate const-ness! + void operator=(const const_iterator&); - //- Construct from pointer to iterator - inline iteratorProxy(iterator*); + public: - //- Assign value - inline void operator=(const unsigned int val); + // Constructors - //- Conversion operator - inline operator unsigned int () const; - }; + //- Construct null + inline iterator(); - public: + //- Construct from iterator base, eg iter(packedlist[i]) + inline iterator(const iteratorBase&); - // Constructors + //- Construct from base list and position index + inline iterator(const PackedList*, const label); - //- Construct from base list and position index - inline iterator(const PackedList*, const label); + // Member Operators - //- Assign value directly - inline void operator=(unsigned int); + //- Assign from iteratorBase, eg iter = packedlist[i] + inline iterator& operator=(const iteratorBase&); - //- Return value - inline unsigned int operator*() const; + //- Return value + inline unsigned int operator*() const; - //- Return value - inline unsigned int operator()() const; + //- Return value + inline unsigned int operator()() const; - //- Return proxy for assigning the referenced value - inline iteratorProxy operator*(); + //- Return iteratorBase for assigning values + inline iteratorBase& operator*(); - //- Return proxy for assigning the referenced value - inline iteratorProxy operator()(); + //- Return iteratorBase for assigning values + inline iteratorBase& operator()(); - inline iterator& operator++(); - inline iterator operator++(int); + inline iterator& operator++(); + inline iterator operator++(int); - inline iterator& operator--(); - inline iterator operator--(int); + inline iterator& operator--(); + inline iterator operator--(int); }; @@ -403,6 +414,61 @@ public: //- iterator set to beyond the end of the HashTable inline iterator end(); + + //- The const_iterator for PackedList + class const_iterator + : + public iteratorBase + { + public: + + // Constructors + + //- Construct null + inline const_iterator(); + + //- Construct from iterator base + inline const_iterator(const iteratorBase&); + + //- Construct from base list and position index + inline const_iterator(const PackedList*, const label); + + //- Construct from non-const iterator + inline const_iterator(const iterator&); + + // Member operators + + //- Assign from iteratorBase or derived + // eg, iter = packedlist[i] or iter = [non-const]list.begin() + inline const_iterator& operator=(const iteratorBase&); + + //- Return referenced value directly + inline unsigned int operator*() const; + + //- Return referenced value directly + inline unsigned int operator()() const; + + inline const_iterator& operator++(); + inline const_iterator operator++(int); + + inline const_iterator& operator--(); + inline const_iterator operator--(int); + + }; + + + //- const_iterator set to the beginning of the PackedList + inline const_iterator cbegin() const; + + //- const_iterator set to beyond the end of the PackedList + inline const_iterator cend() const; + + //- const_iterator set to the beginning of the PackedList + inline const_iterator begin() const; + + //- const_iterator set to beyond the end of the PackedList + inline const_iterator end() const; + }; diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H index b898cf5822381418ba3c48cf5e0c11fcb13cc500..1206e6483fe9a37732ebd36f201543e168acd65f 100644 --- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H +++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H @@ -40,7 +40,7 @@ inline unsigned int Foam::PackedList<nBits>::max_bits() template<int nBits> inline unsigned int Foam::PackedList<nBits>::max_value() { - return (1u << nBits) - 1; + return (1 << nBits) - 1; } @@ -51,6 +51,13 @@ inline unsigned int Foam::PackedList<nBits>::packing() } +template<int nBits> +inline unsigned int Foam::PackedList<nBits>::maskLower(unsigned offset) +{ + return (1 << (nBits * offset)) - 1; +} + + template<int nBits> inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem) { @@ -119,64 +126,45 @@ Foam::PackedList<nBits>::clone() const // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * // +// iteratorBase + template<int nBits> -inline Foam::PackedList<nBits>::const_iterator::const_iterator -( - const PackedList<nBits>* lst, - const label i -) +inline Foam::PackedList<nBits>::iteratorBase::iteratorBase() : - list_(const_cast<PackedList<nBits>*>(lst)), - index_(i / packing()), - offset_(i % packing()) + list_(0), + index_(0), + offset_(0) {} template<int nBits> -inline Foam::PackedList<nBits>::iterator::iterator +inline Foam::PackedList<nBits>::iteratorBase::iteratorBase ( - const PackedList<nBits>* lst, - const label i + const iteratorBase& iter ) : - const_iterator(lst, i) + list_(iter.list_), + index_(iter.index_), + offset_(iter.offset_) {} template<int nBits> -inline Foam::PackedList<nBits>::const_iterator::const_iterator +inline Foam::PackedList<nBits>::iteratorBase::iteratorBase ( - const iterator& it + const PackedList<nBits>* lst, + const label i ) : - list_(it.list_), - index_(it.index_), - offset_(it.offset_) + list_(const_cast<PackedList<nBits>*>(lst)), + index_(i / packing()), + offset_(i % packing()) {} template<int nBits> -inline bool Foam::PackedList<nBits>::const_iterator::operator== -( - const const_iterator& iter -) const -{ - return index_ == iter.index_ && offset_ == iter.offset_; -} - - -template<int nBits> -inline bool Foam::PackedList<nBits>::const_iterator::operator!= -( - const const_iterator& iter -) const -{ - return !(operator==(iter)); -} - - -template<int nBits> -inline unsigned int Foam::PackedList<nBits>::const_iterator::get() const +inline unsigned int +Foam::PackedList<nBits>::iteratorBase::get() const { const unsigned int& stored = list_->StorageList::operator[](index_); return (stored >> (nBits * offset_)) & max_value(); @@ -184,7 +172,8 @@ inline unsigned int Foam::PackedList<nBits>::const_iterator::get() const template<int nBits> -inline bool Foam::PackedList<nBits>::const_iterator::set(const unsigned int val) +inline bool +Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val) { unsigned int& stored = list_->StorageList::operator[](index_); const unsigned int prev = stored; @@ -195,9 +184,9 @@ inline bool Foam::PackedList<nBits>::const_iterator::set(const unsigned int val) if (val & ~max_value()) { # ifdef DEBUGList - FatalErrorIn("PackedList<T>::iterator::set(const unsigned int)") + FatalErrorIn("PackedList<T>::iteratorBase::set(const unsigned int)") << "value " << label(val) - << " out-of-range 0 ... " << label(max_value()) +w << " out-of-range 0 ... " << label(max_value()) << " representable by " << nBits << " bits" << abort(FatalError); # endif @@ -216,8 +205,8 @@ inline bool Foam::PackedList<nBits>::const_iterator::set(const unsigned int val) template<int nBits> -inline typename Foam::PackedList<nBits>::const_iterator& -Foam::PackedList<nBits>::const_iterator::operator++() +inline void +Foam::PackedList<nBits>::iteratorBase::incr() { offset_++; if (offset_ >= packing()) @@ -225,169 +214,328 @@ Foam::PackedList<nBits>::const_iterator::operator++() offset_ = 0; index_++; } +} - return *this; + +template<int nBits> +inline void +Foam::PackedList<nBits>::iteratorBase::decr() +{ + if (!offset_) + { + offset_ = packing(); + index_--; + } + offset_--; } template<int nBits> -inline typename Foam::PackedList<nBits>::iterator& -Foam::PackedList<nBits>::iterator::operator++() +inline void +Foam::PackedList<nBits>::iteratorBase::seek +( + const iteratorBase& iter +) { - this->offset_++; - if (this->offset_ >= packing()) + list_ = iter.list_; + index_ = iter.index_; + offset_ = iter.offset_; + + this->validate(); +} + + +template<int nBits> +inline bool +Foam::PackedList<nBits>::iteratorBase::valid() const +{ + label elemI = offset_ + index_ * packing(); + return (elemI < list_->size_); +} + + +template<int nBits> +inline bool +Foam::PackedList<nBits>::iteratorBase::validate() +{ + // avoid going past end() + unsigned endIdx = list_->size_ / packing(); + unsigned endOff = list_->size_ % packing(); + + if (index_ > endIdx || (index_ == endIdx && offset_ > endOff)) + { + index_ = endIdx; + offset_ = endOff; + + return false; + } + else { - this->offset_ = 0; - this->index_++; + return true; } +} - return *this; + +template<int nBits> +inline bool Foam::PackedList<nBits>::iteratorBase::operator== +( + const iteratorBase& iter +) const +{ + return this->index_ == iter.index_ && this->offset_ == iter.offset_; } template<int nBits> -inline typename Foam::PackedList<nBits>::const_iterator -Foam::PackedList<nBits>::const_iterator::operator++(int) +inline bool Foam::PackedList<nBits>::iteratorBase::operator!= +( + const iteratorBase& iter +) const { - const_iterator old = *this; - ++*this; - return old; + return this->index_ != iter.index_ || this->offset_ != iter.offset_; } template<int nBits> -inline typename Foam::PackedList<nBits>::iterator -Foam::PackedList<nBits>::iterator::operator++(int) +inline unsigned int +Foam::PackedList<nBits>::iteratorBase::operator=(const iteratorBase& iter) { - iterator old = *this; - ++*this; - return old; + const unsigned int val = iter.get(); + this->set(val); + return val; } template<int nBits> -inline typename Foam::PackedList<nBits>::const_iterator& -Foam::PackedList<nBits>::const_iterator::operator--() +inline unsigned int +Foam::PackedList<nBits>::iteratorBase::operator=(const unsigned int val) { - if (!offset_) +# ifdef DEBUGList + // lazy evaluation would be nice to keep, but really slows things down + label minsize = 1 + offset_ + index_ * packing(); + if (minsize > list_->size_) { - offset_ = packing(); - index_--; + list_->resize(minsize); } - offset_--; +#endif - return *this; + this->set(val); + return val; } template<int nBits> -inline typename Foam::PackedList<nBits>::iterator& -Foam::PackedList<nBits>::iterator::operator--() +inline Foam::PackedList<nBits>::iteratorBase::operator +unsigned int () const { - if (!this->offset_) +# ifdef DEBUGList + // lazy evaluation would be nice to keep, but really slows things down + label minsize = 1 + offset_ + index_ * packing(); + if (minsize > list_->size_) { - this->offset_ = packing(); - this->index_--; + return 0; } - this->offset_--; +#endif + + return this->get(); +} + + +// const_iterator, iterator + +template<int nBits> +inline Foam::PackedList<nBits>::iterator::iterator() +: + iteratorBase() +{} + + +template<int nBits> +inline Foam::PackedList<nBits>::const_iterator::const_iterator() +: + iteratorBase() +{} + +template<int nBits> +inline Foam::PackedList<nBits>::iterator::iterator +( + const iteratorBase& iter +) +: + iteratorBase(iter) +{ + this->validate(); +} + + +template<int nBits> +inline Foam::PackedList<nBits>::const_iterator::const_iterator +( + const iteratorBase& iter +) +: + iteratorBase(iter) +{ + this->validate(); +} + + +template<int nBits> +inline Foam::PackedList<nBits>::iterator::iterator +( + const PackedList<nBits>* lst, + const label i +) +: + iteratorBase(lst, i) +{} + + +template<int nBits> +inline Foam::PackedList<nBits>::const_iterator::const_iterator +( + const PackedList<nBits>* lst, + const label i +) +: + iteratorBase(lst, i) +{} + + +template<int nBits> +inline Foam::PackedList<nBits>::const_iterator::const_iterator +( + const iterator& iter +) +: + iteratorBase(static_cast<const iteratorBase&>(iter)) +{} + + +template<int nBits> +inline typename Foam::PackedList<nBits>::iterator& +Foam::PackedList<nBits>::iterator::operator=(const iteratorBase& iter) +{ + this->seek(iter); return *this; } template<int nBits> -inline typename Foam::PackedList<nBits>::const_iterator -Foam::PackedList<nBits>::const_iterator::operator--(int) +inline typename Foam::PackedList<nBits>::const_iterator& +Foam::PackedList<nBits>::const_iterator::operator=(const iteratorBase& iter) { - const_iterator old = *this; - --*this; - return old; + this->seek(iter); + return *this; +} + + +template<int nBits> +inline typename Foam::PackedList<nBits>::iterator& +Foam::PackedList<nBits>::iterator::operator++() +{ + this->incr(); + return *this; +} + + +template<int nBits> +inline typename Foam::PackedList<nBits>::const_iterator& +Foam::PackedList<nBits>::const_iterator::operator++() +{ + this->incr(); + return *this; } template<int nBits> inline typename Foam::PackedList<nBits>::iterator -Foam::PackedList<nBits>::iterator::operator--(int) +Foam::PackedList<nBits>::iterator::operator++(int) { iterator old = *this; - --*this; + this->incr(); return old; } template<int nBits> -inline unsigned int -Foam::PackedList<nBits>::const_iterator::operator*() const +inline typename Foam::PackedList<nBits>::const_iterator +Foam::PackedList<nBits>::const_iterator::operator++(int) { - return get(); + const_iterator old = *this; + this->incr(); + return old; } template<int nBits> -inline unsigned int -Foam::PackedList<nBits>::const_iterator::operator()() const +inline typename Foam::PackedList<nBits>::iterator& +Foam::PackedList<nBits>::iterator::operator--() { - return get(); + this->decr(); + return *this; } template<int nBits> -inline typename Foam::PackedList<nBits>::iterator::iteratorProxy -Foam::PackedList<nBits>::iterator::operator*() +inline typename Foam::PackedList<nBits>::const_iterator& +Foam::PackedList<nBits>::const_iterator::operator--() { - return iteratorProxy(this); + this->decr(); + return *this; } template<int nBits> -inline typename Foam::PackedList<nBits>::iterator::iteratorProxy -Foam::PackedList<nBits>::iterator::operator()() +inline typename Foam::PackedList<nBits>::iterator +Foam::PackedList<nBits>::iterator::operator--(int) { - return iteratorProxy(this); + iterator old = *this; + this->decr(); + return old; } template<int nBits> -inline void -Foam::PackedList<nBits>::iterator::operator=(const unsigned int val) +inline typename Foam::PackedList<nBits>::const_iterator +Foam::PackedList<nBits>::const_iterator::operator--(int) { - set(val); + const_iterator old = *this; + this->decr(); + return old; } template<int nBits> -inline Foam::PackedList<nBits>::const_iterator::operator -unsigned int () const +inline typename Foam::PackedList<nBits>::iteratorBase& +Foam::PackedList<nBits>::iterator::operator*() { - return get(); + return static_cast<iteratorBase&>(*this); } template<int nBits> -inline Foam::PackedList<nBits>::iterator::iteratorProxy::iteratorProxy -( - PackedList<nBits>::iterator* it -) -: - iter_(it) -{} +inline typename Foam::PackedList<nBits>::iteratorBase& +Foam::PackedList<nBits>::iterator::operator()() +{ + return static_cast<iteratorBase&>(*this); +} template<int nBits> -inline Foam::PackedList<nBits>::iterator::iteratorProxy::operator -unsigned int () const +inline unsigned int +Foam::PackedList<nBits>::const_iterator::operator*() const { - return iter_->get(); + return this->get(); } template<int nBits> -inline void Foam::PackedList<nBits>::iterator::iteratorProxy::operator= -( - const unsigned int val -) +inline unsigned int +Foam::PackedList<nBits>::const_iterator::operator()() const { - iter_->set(val); + return this->get(); } @@ -427,7 +575,7 @@ template<int nBits> inline typename Foam::PackedList<nBits>::const_iterator Foam::PackedList<nBits>::end() const { - return iterator(this, this->size()); + return const_iterator(this, this->size()); } @@ -435,7 +583,7 @@ template<int nBits> inline typename Foam::PackedList<nBits>::const_iterator Foam::PackedList<nBits>::cend() const { - return iterator(this, this->size()); + return const_iterator(this, this->size()); } @@ -500,7 +648,7 @@ inline void Foam::PackedList<nBits>::resize // partial chunk, preserve existing value if (begOff) { - unsigned int maskOld = (0x1 << (nBits * begOff)) - 1; + unsigned int maskOld = maskLower(begOff); StorageList::operator[](begIdx) &= maskOld; StorageList::operator[](begIdx) |= ~maskOld & fill; @@ -628,7 +776,7 @@ inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst) template<int nBits> -inline Foam::Xfer<Foam::PackedList<nBits> > +inline Foam::Xfer< Foam::PackedList<nBits> > Foam::PackedList<nBits>::xfer() { return xferMove(*this); @@ -642,7 +790,7 @@ inline unsigned int Foam::PackedList<nBits>::get(const label i) const checkIndex(i); # endif - return const_iterator(this, i).get(); + return iteratorBase(this, i).get(); } @@ -651,7 +799,7 @@ inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const { if (i < size_) { - return const_iterator(this, i).get(); + return iteratorBase(this, i).get(); } else { @@ -679,8 +827,7 @@ inline bool Foam::PackedList<nBits>::set << abort(FatalError); } # endif - - return iterator(this, i).set(val); + return iteratorBase(this, i).set(val); } @@ -691,7 +838,7 @@ inline void Foam::PackedList<nBits>::append(const unsigned int val) reserve(elemI + 1); size_++; - iterator(this, elemI).set(val); + iteratorBase(this, elemI).set(val); } @@ -707,7 +854,7 @@ inline unsigned int Foam::PackedList<nBits>::remove() } label elemI = size_ - 1; - const unsigned int val = const_iterator(this, elemI).get(); + const unsigned int val = iteratorBase(this, elemI).get(); resize(elemI); return val; @@ -715,15 +862,10 @@ inline unsigned int Foam::PackedList<nBits>::remove() template<int nBits> -inline typename Foam::PackedList<nBits>::iterator +inline typename Foam::PackedList<nBits>::iteratorBase Foam::PackedList<nBits>::operator[](const label i) { - if (i >= size_) - { - resize(i + 1); - } - - return iterator(this, i); + return iteratorBase(this, i); } diff --git a/src/OpenFOAM/primitives/Lists/PackedBoolList.H b/src/OpenFOAM/primitives/Lists/PackedBoolList.H index 84d99561362dec03dbeecaf34154f9f97ba3e686..1c2f3179457ddf6082fbb354e78f317ebd8881b9 100644 --- a/src/OpenFOAM/primitives/Lists/PackedBoolList.H +++ b/src/OpenFOAM/primitives/Lists/PackedBoolList.H @@ -40,7 +40,7 @@ Description namespace Foam { - typedef PackedList<1> PackedBoolList; + typedef PackedList<> PackedBoolList; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //