BUG: non-lazy PackedList (fixes #484)

- The unset() method never auto-vivifies, whereas the set() method
  always auto-vivifies. In the case where set() is called with a zero
  for its argument - eg, set(index, 0) - this should behave
  identically to an unset() and not auto-vivify out-of-range entries.
This commit is contained in:
Mark Olesen
2017-05-26 21:02:28 +02:00
parent 8f1a4f792d
commit dd54aa3018
6 changed files with 279 additions and 268 deletions

View File

@ -84,6 +84,12 @@ int main(int argc, char *argv[])
packed.resize(n, 1); packed.resize(n, 1);
} }
Info<< "resize/shrink/resize:" << timer.cpuTimeIncrement() << " s\n\n"; Info<< "resize/shrink/resize:" << timer.cpuTimeIncrement() << " s\n\n";
Info<< "packed bool size=" << packed.size() << nl;
// Neither of these should affect the size
packed.unset(2*n-1);
packed.set(2*n-1, 0);
Info<< "packed bool size=" << packed.size() << nl;
// set every other bit on: // set every other bit on:
Info<< "set every other bit on and count\n"; Info<< "set every other bit on and count\n";
@ -99,8 +105,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Counting brute-force:" << timer.cpuTimeIncrement() Info<< "Counting brute-force:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Count packed // Count packed
@ -110,8 +116,8 @@ int main(int argc, char *argv[])
sum += packed.count(); sum += packed.count();
} }
Info<< "Counting via count():" << timer.cpuTimeIncrement() Info<< "Counting via count():" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Dummy addition // Dummy addition
@ -123,8 +129,8 @@ int main(int argc, char *argv[])
sum += i + 1; sum += i + 1;
} }
} }
Info<< "Dummy loop:" << timer.cpuTimeIncrement() << " s" << endl; Info<< "Dummy loop:" << timer.cpuTimeIncrement() << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << " (sum is meaningless)" << endl;
// //
// Read // Read
@ -139,8 +145,8 @@ int main(int argc, char *argv[])
sum += stlVector[i]; sum += stlVector[i];
} }
} }
Info<< "Reading stl:" << timer.cpuTimeIncrement() << " s" << endl; Info<< "Reading stl:" << timer.cpuTimeIncrement() << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read unpacked // Read unpacked
@ -152,8 +158,8 @@ int main(int argc, char *argv[])
sum += unpacked[i]; sum += unpacked[i];
} }
} }
Info<< "Reading unpacked:" << timer.cpuTimeIncrement() << " s" << endl; Info<< "Reading unpacked:" << timer.cpuTimeIncrement() << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read packed // Read packed
@ -166,8 +172,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading packed using get:" << timer.cpuTimeIncrement() Info<< "Reading packed using get:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read packed // Read packed
@ -180,8 +186,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading packed using reference:" << timer.cpuTimeIncrement() Info<< "Reading packed using reference:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read via iterator // Read via iterator
@ -194,8 +200,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading packed using iterator:" << timer.cpuTimeIncrement() Info<< "Reading packed using iterator:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read via iterator // Read via iterator
@ -208,8 +214,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading packed using const_iterator():" << timer.cpuTimeIncrement() Info<< "Reading packed using const_iterator():" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read empty hash // Read empty hash
@ -222,8 +228,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading empty labelHashSet:" << timer.cpuTimeIncrement() Info<< "Reading empty labelHashSet:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read full hash // Read full hash
@ -236,8 +242,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading full labelHashSet:" << timer.cpuTimeIncrement() Info<< "Reading full labelHashSet:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
// Read empty static hash // Read empty static hash
@ -250,8 +256,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading empty StaticHash:" << timer.cpuTimeIncrement() Info<< "Reading empty StaticHash:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
#if 0 #if 0
// we can skip this test - it is usually quite slow // we can skip this test - it is usually quite slow
@ -265,8 +271,8 @@ int main(int argc, char *argv[])
} }
} }
Info<< "Reading full StaticHash:" << timer.cpuTimeIncrement() Info<< "Reading full StaticHash:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << nl
Info<< " sum " << sum << endl; << " sum " << sum << endl;
#endif #endif
Info<< "Starting write tests" << endl; Info<< "Starting write tests" << endl;
@ -319,7 +325,6 @@ int main(int argc, char *argv[])
Info<< "Writing packed using set:" << timer.cpuTimeIncrement() Info<< "Writing packed using set:" << timer.cpuTimeIncrement()
<< " s" << endl; << " s" << endl;
// Write packed // Write packed
for (label iter = 0; iter < nIters; ++iter) for (label iter = 0; iter < nIters; ++iter)
{ {

View File

@ -286,7 +286,7 @@ Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
void Foam::PackedBoolList::operator=(const Foam::UList<bool>& lst) void Foam::PackedBoolList::operator=(const UList<bool>& lst)
{ {
this->setSize(lst.size()); this->setSize(lst.size());

View File

@ -94,7 +94,7 @@ public:
inline PackedBoolList(); inline PackedBoolList();
//- Construct from Istream //- Construct from Istream
PackedBoolList(Istream&); PackedBoolList(Istream& is);
//- Construct with given size, initializes list to 0 //- Construct with given size, initializes list to 0
explicit inline PackedBoolList(const label size); explicit inline PackedBoolList(const label size);
@ -103,19 +103,19 @@ public:
inline PackedBoolList(const label size, const bool val); inline PackedBoolList(const label size, const bool val);
//- Copy constructor //- Copy constructor
inline PackedBoolList(const PackedBoolList&); inline PackedBoolList(const PackedBoolList& lst);
//- Copy constructor //- Copy constructor
explicit inline PackedBoolList(const PackedList<1>&); explicit inline PackedBoolList(const PackedList<1>& lst);
//- Construct by transferring the parameter contents //- Construct by transferring the parameter contents
inline PackedBoolList(const Xfer<PackedBoolList>&); inline PackedBoolList(const Xfer<PackedBoolList>& lst);
//- Construct by transferring the parameter contents //- Construct by transferring the parameter contents
inline PackedBoolList(const Xfer<PackedList<1>>&); inline PackedBoolList(const Xfer<PackedList<1>>& lst);
//- Construct from a list of bools //- Construct from a list of bools
explicit inline PackedBoolList(const Foam::UList<bool>&); explicit inline PackedBoolList(const UList<bool>& lst);
//- Construct from a list of labels //- Construct from a list of labels
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
@ -131,132 +131,132 @@ public:
// Member Functions // Member Functions
// Access // Access
using PackedList<1>::set; using PackedList<1>::set;
using PackedList<1>::unset; using PackedList<1>::unset;
//- Set specified bits. //- Set specified bits.
void set(const PackedList<1>&); void set(const PackedList<1>& lst);
//- Set the listed indices. Return number of elements changed. //- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
label set(const labelUList& indices); label set(const labelUList& indices);
//- Set the listed indices. Return number of elements changed. //- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
label set(const UIndirectList<label>& indices); label set(const UIndirectList<label>& indices);
//- Unset specified bits. //- Unset specified bits.
void unset(const PackedList<1>&); void unset(const PackedList<1>& lst);
//- Unset the listed indices. Return number of elements changed. //- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries. // Never auto-vivify entries.
label unset(const labelUList& indices); label unset(const labelUList& indices);
//- Unset the listed indices. Return number of elements changed. //- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries. // Never auto-vivify entries.
label unset(const UIndirectList<label>& indices); label unset(const UIndirectList<label>& indices);
//- Subset with the specified list. //- Subset with the specified list.
void subset(const PackedList<1>&); void subset(const PackedList<1>& lst);
//- Subset with the listed indices. //- Subset with the listed indices.
// Return number of elements subsetted. // Return number of elements subsetted.
label subset(const labelUList& indices); label subset(const labelUList& indices);
//- Subset with the listed indices. //- Subset with the listed indices.
// Return number of elements subsetted. // Return number of elements subsetted.
label subset(const UIndirectList<label>& indices); label subset(const UIndirectList<label>& indices);
//- Return indices of the used (true) elements as a list of labels //- Return indices of the used (true) elements as a list of labels
Xfer<labelList> used() const; Xfer<labelList> used() const;
// Edit // Edit
//- Transfer the contents of the argument list into this list //- Transfer the contents of the argument list into this list
// and annul the argument list. // and annul the argument list.
inline void transfer(PackedBoolList&); inline void transfer(PackedBoolList& lst);
//- Transfer the contents of the argument list into this list //- Transfer the contents of the argument list into this list
// and annul the argument list. // and annul the argument list.
inline void transfer(PackedList<1>&); inline void transfer(PackedList<1>& lst);
//- Transfer contents to the Xfer container //- Transfer contents to the Xfer container
inline Xfer<PackedBoolList> xfer(); inline Xfer<PackedBoolList> xfer();
// Member Operators // Member Operators
//- Assignment of all entries to the given value. //- Assignment of all entries to the given value.
inline void operator=(const bool val); inline void operator=(const bool val);
//- Assignment operator. //- Assignment operator.
inline void operator=(const PackedBoolList&); inline void operator=(const PackedBoolList& lst);
//- Assignment operator. //- Assignment operator.
inline void operator=(const PackedList<1>&); inline void operator=(const PackedList<1>& lst);
//- Assignment operator. //- Assignment operator.
void operator=(const Foam::UList<bool>&); void operator=(const UList<bool>& lst);
//- Assignment operator, //- Assignment operator,
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline void operator=(const labelUList& indices); inline void operator=(const labelUList& indices);
//- Assignment operator, //- Assignment operator,
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline void operator=(const UIndirectList<label>&); inline void operator=(const UIndirectList<label>& indices);
//- Complement operator //- Complement operator
inline PackedBoolList operator~() const; inline PackedBoolList operator~() const;
//- And operator (lists may be dissimilar sizes) //- And operator (lists may be dissimilar sizes)
inline PackedBoolList& operator&=(const PackedList<1>&); inline PackedBoolList& operator&=(const PackedList<1>& lst);
//- And operator (lists may be dissimilar sizes) //- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline PackedBoolList& operator&=(const labelUList& indices); inline PackedBoolList& operator&=(const labelUList& indices);
//- And operator (lists may be dissimilar sizes) //- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline PackedBoolList& operator&=(const UIndirectList<label>&); inline PackedBoolList& operator&=(const UIndirectList<label>& indices);
//- Xor operator (lists may be dissimilar sizes) //- Xor operator (lists may be dissimilar sizes)
// Retains unique entries // Retains unique entries
PackedBoolList& operator^=(const PackedList<1>&); PackedBoolList& operator^=(const PackedList<1>& lst);
//- Or operator (lists may be dissimilar sizes) //- Or operator (lists may be dissimilar sizes)
inline PackedBoolList& operator|=(const PackedList<1>&); inline PackedBoolList& operator|=(const PackedList<1>& lst);
//- Or operator (lists may be dissimilar sizes), //- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline PackedBoolList& operator|=(const labelUList& indices); inline PackedBoolList& operator|=(const labelUList& indices);
//- Or operator (lists may be dissimilar sizes), //- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
inline PackedBoolList& operator|=(const UIndirectList<label>&); inline PackedBoolList& operator|=(const UIndirectList<label>& indices);
//- Add entries to this list, synonymous with the or operator //- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const PackedList<1>&); inline PackedBoolList& operator+=(const PackedList<1>& lst);
//- Add entries to this list, synonymous with the or operator //- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const labelUList& indices); inline PackedBoolList& operator+=(const labelUList& indices);
//- Add entries to this list, synonymous with the or operator //- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const UIndirectList<label>&); inline PackedBoolList& operator+=(const UIndirectList<label>& indices);
//- Remove entries from this list - unset the specified bits //- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const PackedList<1>&); inline PackedBoolList& operator-=(const PackedList<1>& lst);
//- Remove entries from this list - unset the specified bits //- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const labelUList& indices); inline PackedBoolList& operator-=(const labelUList& indices);
//- Remove entries from this list - unset the specified bits //- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const UIndirectList<label>&); inline PackedBoolList& operator-=(const UIndirectList<label>& indices);
}; };

View File

@ -73,7 +73,7 @@ inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1>>& lst)
{} {}
inline Foam::PackedBoolList::PackedBoolList(const Foam::UList<bool>& lst) inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst)
: :
PackedList<1>() PackedList<1>()
{ {

View File

@ -118,9 +118,9 @@ class Ostream;
template<unsigned nBits> class PackedList; template<unsigned nBits> class PackedList;
template<unsigned nBits> template<unsigned nBits>
Istream& operator>>(Istream&, PackedList<nBits>&); Istream& operator>>(Istream& is, PackedList<nBits>& lst);
template<unsigned nBits> template<unsigned nBits>
Ostream& operator<<(Ostream&, const PackedList<nBits>&); Ostream& operator<<(Ostream& os, const PackedList<nBits>& lst);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -160,11 +160,11 @@ protected:
inline static label packedLength(const label); inline static label packedLength(const label);
//- Read a list entry (allows for specialization) //- Read a list entry (allows for specialization)
inline static unsigned int readValue(Istream&); inline static unsigned int readValue(Istream& is);
//- Read an index/value pair and set accordingly. //- Read an index/value pair and set accordingly.
// For bool specialization, read a single index value // For bool specialization, read a single index value
inline void setPair(Istream&); inline void setPair(Istream& is);
private: private:
@ -252,167 +252,167 @@ public:
// Member Functions // Member Functions
// Access // Access
//- The number of elements that can be stored before reallocating //- The number of elements that can be stored before reallocating
inline label capacity() const; inline label capacity() const;
//- Number of entries. //- Number of entries.
inline label size() const; inline label size() const;
//- Return true if the list is empty (ie, size() is zero). //- Return true if the list is empty (ie, size() is zero).
inline bool empty() const; inline bool empty() const;
//- Get value at index I. //- Get value at index I.
// Never auto-vivify entries. // Never auto-vivify entries.
inline unsigned int get(const label i) const; inline unsigned int get(const label i) const;
//- Set value at index I. Return true if value changed. //- Set value at index I. Return true if value changed.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent, non-zero entries.
// Default value set is the max_value. // Default value set is the max_value.
inline bool set(const label i, const unsigned int val = ~0u); inline bool set(const label i, const unsigned int val = ~0u);
//- Unset the entry at index I. Return true if value changed. //- Unset the entry at index I. Return true if value changed.
// Never auto-vivify entries. // Never auto-vivify entries.
inline bool unset(const label i); inline bool unset(const label i);
//- Return the underlying packed storage //- Return the underlying packed storage
// Manipulate with utmost caution // Manipulate with utmost caution
inline List<unsigned int>& storage(); inline List<unsigned int>& storage();
//- Return the underlying packed storage //- Return the underlying packed storage
inline const List<unsigned int>& storage() const; inline const List<unsigned int>& storage() const;
//- The list length when packed //- The list length when packed
inline label packedLength() const; inline label packedLength() const;
//- Return the binary size in number of characters //- Return the binary size in number of characters
// used in the underlying storage // used in the underlying storage
inline std::streamsize byteSize() const; inline std::streamsize byteSize() const;
//- Count number of bits set, O(log(n)) //- Count number of bits set, O(log(n))
// Uses the Hamming weight (population count) method // Uses the Hamming weight (population count) method
// http://en.wikipedia.org/wiki/Hamming_weight // http://en.wikipedia.org/wiki/Hamming_weight
unsigned int count() const; unsigned int count() const;
//- Return the values as a list of labels //- Return the values as a list of labels
Xfer<labelList> values() const; Xfer<labelList> values() const;
//- Print bit patterns, optionally output unused elements //- Print bit patterns, optionally output unused elements
// //
// addressable bits: // addressable bits:
// on: '1', off: '-' // on: '1', off: '-'
// //
// non-addressable bits: // non-addressable bits:
// on: '!', off: '.' // on: '!', off: '.'
// //
Ostream& printBits(Ostream&, const bool fullOutput=false) const; Ostream& printBits(Ostream& os, const bool fullOutput=false) const;
//- Print information and bit patterns (with printBits) //- Print information and bit patterns (with printBits)
Ostream& printInfo(Ostream&, const bool fullOutput=false) const; Ostream& printInfo(Ostream& os, const bool fullOutput=false) const;
// Edit // Edit
//- Trim any trailing zero elements //- Trim any trailing zero elements
bool trim(); bool trim();
//- Invert the bits in the addressable region //- Invert the bits in the addressable region
void flip(); void flip();
//- Clear all bits //- Clear all bits
inline void reset(); inline void reset();
//- Alter the size of the underlying storage. //- Alter the size of the underlying storage.
// The addressed size will be truncated if needed to fit, but will // The addressed size will be truncated if needed to fit, but will
// remain otherwise untouched. // remain otherwise untouched.
inline void setCapacity(const label); inline void setCapacity(const label nElem);
//- Reset addressable list size, does not shrink the allocated size. //- Reset addressable list size, does not shrink the allocated size.
// Optionally specify a value for new elements. // Optionally specify a value for new elements.
inline void resize(const label, const unsigned int val = 0u); inline void resize(const label nElem, const unsigned int val = 0u);
//- Alias for resize() //- Alias for resize()
inline void setSize(const label, const unsigned int val = 0u); inline void setSize(const label nElem, const unsigned int val = 0u);
//- Reserve allocation space for at least this size. //- Reserve allocation space for at least this size.
// Never shrinks the allocated size. // Never shrinks the allocated size.
// The list size is adjusted as per DynamicList with // The list size is adjusted as per DynamicList with
// SizeInc=0, SizeMult=2, SizeDiv=1 // SizeInc=0, SizeMult=2, SizeDiv=1
inline void reserve(const label); inline void reserve(const label nElem);
//- Clear the list, i.e. set addressable size to zero. //- Clear the list, i.e. set addressable size to zero.
// Does not adjust the underlying storage // Does not adjust the underlying storage
inline void clear(); inline void clear();
//- Clear the list and delete storage. //- Clear the list and delete storage.
inline void clearStorage(); inline void clearStorage();
//- Shrink the allocated space to what is actually used. //- Shrink the allocated space to what is actually used.
inline void shrink(); inline void shrink();
//- Transfer the contents of the argument list into this list //- Transfer the contents of the argument list into this list
// and annul the argument list. // and annul the argument list.
inline void transfer(PackedList<nBits>&); inline void transfer(PackedList<nBits>& lst);
//- Transfer contents to the Xfer container //- Transfer contents to the Xfer container
inline Xfer<PackedList<nBits>> xfer(); inline Xfer<PackedList<nBits>> xfer();
// IO // IO
//- Clear list and read from stream //- Clear list and read from stream
Istream& read(Istream& is); Istream& read(Istream& is);
//- Write the List, with line-breaks in ASCII if the list length //- Write the List, with line-breaks in ASCII if the list length
// exceeds shortListLen. Using '0' suppresses line-breaks entirely. // exceeds shortListLen. Using '0' suppresses line-breaks entirely.
// A special indexed output (ASCII only) is triggered by specifying // A special indexed output (ASCII only) is triggered by specifying
// a negative value for shortListLen. // a negative value for shortListLen.
// //
// The indexed output may be convenient in some situations. // The indexed output may be convenient in some situations.
// The general format is a group of index/value pairs: // The general format is a group of index/value pairs:
// \verbatim // \verbatim
// { (index1 value1) (index2 value2) (index3 value3) } // { (index1 value1) (index2 value2) (index3 value3) }
// \endverbatim // \endverbatim
// The bool specialization just uses the indices corresponding to // The bool specialization just uses the indices corresponding to
// non-zero entries instead of a index/value pair: // non-zero entries instead of a index/value pair:
// \verbatim // \verbatim
// { index1 index2 index3 } // { index1 index2 index3 }
// \endverbatim // \endverbatim
Ostream& writeList(Ostream& os, const label shortListLen=0) const; Ostream& writeList(Ostream& os, const label shortListLen=0) const;
//- Write as a dictionary entry with keyword //- Write as a dictionary entry with keyword
void writeEntry(const word& keyword, Ostream& os) const; void writeEntry(const word& keyword, Ostream& os) const;
// Member operators // Member operators
//- Append a value at the end of the list //- Append a value at the end of the list
inline PackedList<nBits>& append(const unsigned int val); inline PackedList<nBits>& append(const unsigned int val);
//- Remove and return the last element //- Remove and return the last element
inline unsigned int remove(); inline unsigned int remove();
//- Get value at index I //- Get value at index I
// Never auto-vivify entries. // Never auto-vivify entries.
inline unsigned int operator[](const label i) const; inline unsigned int operator[](const label i) const;
//- Set value at index I. //- Set value at index I.
// Returns iterator to perform the actual operation. // Returns iterator to perform the actual operation.
// Does not auto-vivify entries, but will when assigned to. // Does not auto-vivify entries, but will when assigned to.
inline iteratorBase operator[](const label i); inline iteratorBase operator[](const label i);
//- Assignment of all entries to the given value. Takes linear time. //- Assignment of all entries to the given value. Takes linear time.
inline void operator=(const unsigned int val); inline void operator=(const unsigned int val);
//- Assignment operator. //- Assignment operator.
void operator=(const PackedList<nBits>& lst); void operator=(const PackedList<nBits>& lst);
//- Assignment operator. //- Assignment operator.
void operator=(const labelUList& lst); void operator=(const labelUList& lst);
//- Assignment operator. //- Assignment operator.
void operator=(const UIndirectList<label>& lst); void operator=(const UIndirectList<label>& lst);
// Iterators and helpers // Iterators and helpers
@ -442,7 +442,7 @@ public:
inline unsigned int get() const; inline unsigned int get() const;
//- Set value, returning true if changed, no range-checking //- Set value, returning true if changed, no range-checking
inline bool set(unsigned int); inline bool set(unsigned int val);
// Constructors // Constructors
@ -451,7 +451,7 @@ public:
inline iteratorBase(); inline iteratorBase();
//- Construct from base list and position index //- Construct from base list and position index
inline iteratorBase(const PackedList*, const label); inline iteratorBase(const PackedList* lst, const label i);
public: public:
@ -463,17 +463,17 @@ public:
//- Write index/value for a non-zero entry //- Write index/value for a non-zero entry
// The bool specialization writes the index only // The bool specialization writes the index only
inline bool writeIfSet(Ostream&) const; inline bool writeIfSet(Ostream& os) const;
// Member Operators // Member Operators
//- Compare values (not positions) //- Compare values (not positions)
inline bool operator==(const iteratorBase&) const; inline bool operator==(const iteratorBase& iter) const;
inline bool operator!=(const iteratorBase&) const; inline bool operator!=(const iteratorBase& iter) const;
//- Assign value, not position. //- Assign value, not position.
// This allows packed[0] = packed[3] for assigning values // This allows packed[0] = packed[3] for assigning values
inline void operator=(const iteratorBase&); inline void operator=(const iteratorBase& iter);
//- Assign value. //- Assign value.
// A non-existent entry will be auto-vivified. // A non-existent entry will be auto-vivified.
@ -484,7 +484,7 @@ public:
inline operator unsigned int () const; inline operator unsigned int () const;
//- Print information and values //- Print information and values
Ostream& printInfo(Ostream&) const; Ostream& printInfo(Ostream& os) const;
}; };
@ -496,11 +496,11 @@ public:
//- Disallow copy constructor from const_iterator //- Disallow copy constructor from const_iterator
// This would violate const-ness! // This would violate const-ness!
iterator(const const_iterator&); iterator(const const_iterator& iter);
//- Disallow assignment from const_iterator //- Disallow assignment from const_iterator
// This would violate const-ness! // This would violate const-ness!
void operator=(const const_iterator&); void operator=(const const_iterator& iter);
public: public:
@ -513,21 +513,21 @@ public:
//- Construct from iterator base, eg iter(packedlist[i]) //- Construct from iterator base, eg iter(packedlist[i])
// but also "iterator iter = packedlist[i];" // but also "iterator iter = packedlist[i];"
// An out-of-range iterator is assigned end() // An out-of-range iterator is assigned end()
inline iterator(const iteratorBase&); inline iterator(const iteratorBase& iter);
//- Construct from base list and position index //- Construct from base list and position index
inline iterator(const PackedList*, const label); inline iterator(const PackedList* lst, const label i);
// Member Operators // Member Operators
//- Compare positions (not values) //- Compare positions (not values)
inline bool operator==(const iteratorBase&) const; inline bool operator==(const iteratorBase& iter) const;
inline bool operator!=(const iteratorBase&) const; inline bool operator!=(const iteratorBase& iter) const;
//- Assign from iteratorBase, eg iter = packedlist[i] //- Assign from iteratorBase, eg iter = packedlist[i]
// An out-of-range iterator is assigned end() // An out-of-range iterator is assigned end()
inline void operator=(const iteratorBase&); inline void operator=(const iteratorBase& iter);
//- Return value //- Return value
inline unsigned int operator*() const; inline unsigned int operator*() const;
@ -571,24 +571,24 @@ public:
//- Construct from iterator base, eg iter(packedlist[i]) //- Construct from iterator base, eg iter(packedlist[i])
// but also "const_iterator iter = packedlist[i];" // but also "const_iterator iter = packedlist[i];"
// An out-of-range iterator is assigned cend() // An out-of-range iterator is assigned cend()
inline const_iterator(const iteratorBase&); inline const_iterator(const iteratorBase& iter);
//- Construct from base list and position index //- Construct from base list and position index
inline const_iterator(const PackedList*, const label); inline const_iterator(const PackedList* lst, const label i);
//- Construct from iterator //- Construct from iterator
inline const_iterator(const iterator&); inline const_iterator(const iterator& iter);
// Member operators // Member operators
//- Compare positions (not values) //- Compare positions (not values)
inline bool operator==(const iteratorBase&) const; inline bool operator==(const iteratorBase& iter) const;
inline bool operator!=(const iteratorBase&) const; inline bool operator!=(const iteratorBase& iter) const;
//- Assign from iteratorBase or derived //- Assign from iteratorBase or derived
// eg, iter = packedlist[i] or even iter = list.begin() // eg, iter = packedlist[i] or even iter = list.begin()
inline void operator=(const iteratorBase&); inline void operator=(const iteratorBase& iter);
//- Return referenced value directly //- Return referenced value directly
inline unsigned int operator*() const; inline unsigned int operator*() const;
@ -621,14 +621,14 @@ public:
friend Istream& operator>> <nBits> friend Istream& operator>> <nBits>
( (
Istream&, Istream& is,
PackedList<nBits>& PackedList<nBits>& lst
); );
friend Ostream& operator<< <nBits> friend Ostream& operator<< <nBits>
( (
Ostream&, Ostream& os,
const PackedList<nBits>& const PackedList<nBits>& lst
); );
}; };

View File

@ -267,7 +267,7 @@ Foam::PackedList<nBits>::clone() const
template<unsigned nBits> template<unsigned nBits>
inline Foam::PackedList<nBits>::iteratorBase::iteratorBase() inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
: :
list_(0), list_(nullptr),
index_(0) index_(0)
{} {}
@ -1002,6 +1002,12 @@ inline bool Foam::PackedList<nBits>::set
} }
else if (i >= size_) else if (i >= size_)
{ {
if (!val)
{
// Same as unset out-of-bounds = noop
return false;
}
// Lazy evaluation - increase size on assigment // Lazy evaluation - increase size on assigment
resize(i + 1); resize(i + 1);
} }
@ -1013,7 +1019,7 @@ inline bool Foam::PackedList<nBits>::set
template<unsigned nBits> template<unsigned nBits>
inline bool Foam::PackedList<nBits>::unset(const label i) inline bool Foam::PackedList<nBits>::unset(const label i)
{ {
// lazy evaluation - ignore out-of-bounds // Unset out-of-bounds = noop
if (i < 0 || i >= size_) if (i < 0 || i >= size_)
{ {
return false; return false;