mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
PackedList - activated lazy evaluation
- moving back to original flat addressing in iterators means there is no performance issue with using lazy evaluation - set() method now has ~0 for a default value. We can thus simply write 'set(i) to trun on all of the bits. This means we can use it just like labelHashSet::set(i) - added flip() method for inverting bits. I don't know where we might need it, but the STL has it so we might as well too.
This commit is contained in:
@ -52,13 +52,25 @@ int main(int argc, char *argv[])
|
||||
list1 = -1;
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\ntest zero\n";
|
||||
list1 = 0;
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\ntest set() with default argument (max_value)\n";
|
||||
list1.set(3);
|
||||
list1.print(Info);
|
||||
|
||||
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[0] = list1[4] = 1;
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\ntest assign between references, with chaining and auto-vivify\n";
|
||||
list1[1] = list1[8] = list1[10] = list1[14] = 2;
|
||||
list1.print(Info);
|
||||
|
||||
{
|
||||
@ -91,6 +103,14 @@ int main(int argc, char *argv[])
|
||||
list1.resize(8, list1.max_value());
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\ntest flip() function\n";
|
||||
list1.flip();
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\nre-flip()\n";
|
||||
list1.flip();
|
||||
list1.print(Info);
|
||||
|
||||
Info<< "\ntest set() function\n";
|
||||
list1.set(1, 5);
|
||||
list1.print(Info);
|
||||
@ -188,15 +208,23 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
Info<< "\ntest assignment of iterator\n";
|
||||
list1.print(Info);
|
||||
PackedList<3>::iterator cit = list1[25];
|
||||
cit.print(Info);
|
||||
Info<< "cend()\n";
|
||||
list1.end().print(Info);
|
||||
PackedList<3>::iterator cit = list1[100];
|
||||
Info<< "out-of-range: ";
|
||||
cit.print(Info);
|
||||
cit = list1[15];
|
||||
Info<< "in-range: ";
|
||||
cit.print(Info);
|
||||
Info<< "out-of-range: ";
|
||||
cit = list1[1000];
|
||||
cit.print(Info);
|
||||
}
|
||||
|
||||
|
||||
for
|
||||
(
|
||||
PackedList<3>::iterator cit = list1[5];
|
||||
PackedList<3>::iterator cit = list1[30];
|
||||
cit != list1.end();
|
||||
++cit
|
||||
)
|
||||
@ -204,14 +232,19 @@ int main(int argc, char *argv[])
|
||||
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";
|
||||
Info<< "size:" << list1.size() << "\n";
|
||||
|
||||
const unsigned int val = list1[45];
|
||||
|
||||
Info<< "list[45]:" << val << "\n";
|
||||
Info<< "size after read:" << list1.size() << "\n";
|
||||
|
||||
list1[45] = list1.max_value();
|
||||
Info<< "size after write:" << list1.size() << "\n";
|
||||
Info<< "list[45]:" << list1[45] << "\n";
|
||||
list1[49] = list1[100];
|
||||
list1.print(Info);
|
||||
|
||||
|
||||
Info<< "\ntest copy constructor + append\n";
|
||||
|
||||
@ -83,25 +83,25 @@ unsigned int Foam::PackedList<nBits>::count() const
|
||||
|
||||
if (size_)
|
||||
{
|
||||
// mask value for complete chunks
|
||||
// mask value for complete segments
|
||||
unsigned int mask = maskLower(packing());
|
||||
|
||||
unsigned int endIdx = size_ / packing();
|
||||
unsigned int endOff = size_ % packing();
|
||||
const unsigned int endSeg = size_ / packing();
|
||||
const unsigned int endOff = size_ % packing();
|
||||
|
||||
// count bits in complete elements
|
||||
for (unsigned i = 0; i < endIdx; ++i)
|
||||
// count bits in complete segments
|
||||
for (unsigned i = 0; i < endSeg; ++i)
|
||||
{
|
||||
register unsigned int bits = StorageList::operator[](i) & mask;
|
||||
COUNT_PACKEDBITS(c, bits);
|
||||
}
|
||||
|
||||
// count bits in partial chunk
|
||||
// count bits in partial segment
|
||||
if (endOff)
|
||||
{
|
||||
mask = maskLower(endOff);
|
||||
|
||||
register unsigned int bits = StorageList::operator[](endIdx) & mask;
|
||||
register unsigned int bits = StorageList::operator[](endSeg) & mask;
|
||||
COUNT_PACKEDBITS(c, bits);
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ bool Foam::PackedList<nBits>::trim()
|
||||
return false;
|
||||
}
|
||||
|
||||
// mask value for complete chunks
|
||||
// mask value for complete segments
|
||||
unsigned int mask = maskLower(packing());
|
||||
|
||||
label currElem = packedLength(size_) - 1;
|
||||
@ -130,7 +130,7 @@ bool Foam::PackedList<nBits>::trim()
|
||||
StorageList::operator[](currElem) &= maskLower(endOff);
|
||||
}
|
||||
|
||||
// test entire chunk
|
||||
// test entire segment
|
||||
while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
|
||||
{
|
||||
currElem--;
|
||||
@ -162,10 +162,22 @@ bool Foam::PackedList<nBits>::trim()
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
void Foam::PackedList<nBits>::flip()
|
||||
{
|
||||
label packLen = packedLength(size_);
|
||||
|
||||
for (label i=0; i < packLen; i++)
|
||||
{
|
||||
StorageList::operator[](i) = ~StorageList::operator[](i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
Foam::labelList Foam::PackedList<nBits>::values() const
|
||||
{
|
||||
labelList elems(size());
|
||||
labelList elems(size_);
|
||||
|
||||
forAll(*this, i)
|
||||
{
|
||||
@ -178,10 +190,11 @@ Foam::labelList Foam::PackedList<nBits>::values() const
|
||||
template<unsigned nBits>
|
||||
Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
|
||||
{
|
||||
os << "iterator<" << label(nBits) << "> ["
|
||||
<< (index_ * packing() + offset_) << "]"
|
||||
<< " index:" << index_ << " offset:" << offset_
|
||||
<< " value:" << unsigned(*this)
|
||||
os << "iterator<" << label(nBits) << "> ["
|
||||
<< this->index_ << "]"
|
||||
<< " segment:" << label(this->index_ / packing())
|
||||
<< " offset:" << label(this->index_ % packing())
|
||||
<< " value:" << this->get()
|
||||
<< nl;
|
||||
|
||||
return os;
|
||||
@ -194,7 +207,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
||||
os << "PackedList<" << label(nBits) << ">"
|
||||
<< " max_value:" << max_value()
|
||||
<< " packing:" << packing() << nl
|
||||
<< "values: " << size() << "/" << capacity() << "( ";
|
||||
<< "values: " << size_ << "/" << capacity() << "( ";
|
||||
forAll(*this, i)
|
||||
{
|
||||
os << get(i) << ' ';
|
||||
@ -205,17 +218,17 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
||||
os << ")\n"
|
||||
<< "storage: " << packLen << "/" << StorageList::size() << "( ";
|
||||
|
||||
// mask value for complete chunks
|
||||
// mask value for complete segments
|
||||
unsigned int mask = maskLower(packing());
|
||||
|
||||
for (label i=0; i < packLen; i++)
|
||||
{
|
||||
const StorageType& rawBits = StorageList::operator[](i);
|
||||
|
||||
// the final storage may not be full, modify mask accordingly
|
||||
// the final segment may not be full, modify mask accordingly
|
||||
if (i+1 == packLen)
|
||||
{
|
||||
unsigned endOff = size_ % packing();
|
||||
unsigned int endOff = size_ % packing();
|
||||
|
||||
if (endOff)
|
||||
{
|
||||
@ -229,7 +242,7 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
|
||||
|
||||
for (unsigned int testBit = (1 << max_bits()); testBit; testBit >>= 1)
|
||||
{
|
||||
if (testBit & mask)
|
||||
if (mask & testBit)
|
||||
{
|
||||
if (rawBits & testBit)
|
||||
{
|
||||
|
||||
@ -44,9 +44,9 @@ Note
|
||||
Using the iteratorBase as a proxy allows assignment of values
|
||||
between list elements. Thus the following bit of code works as expected:
|
||||
@code
|
||||
blist[1] = blist[5]; // value assignment, not iterator position
|
||||
blist[2] = blist[5] = 4; // propagates value
|
||||
blist[1] = blist[5] = blist[6]; // propagates value
|
||||
list[1] = list[5]; // value assignment, not iterator position
|
||||
list[2] = list[5] = 4; // propagates value
|
||||
list[1] = list[5] = list[6]; // propagates value
|
||||
@endcode
|
||||
|
||||
Using get() or the '[]' operator are similarly fast. Looping and reading
|
||||
@ -58,11 +58,21 @@ Note
|
||||
useful for branching on changed values.
|
||||
|
||||
@code
|
||||
blist[5] = 4;
|
||||
changed = blist.set(5, 8);
|
||||
list[5] = 4;
|
||||
changed = list.set(5, 8);
|
||||
if (changed) ...
|
||||
@endcode
|
||||
|
||||
The lazy evaluation used means that reading an out-of-range element
|
||||
returns zero, but does not affect the list size. Even in a non-const
|
||||
context, only the assigment causes the element to be created.
|
||||
For example,
|
||||
@code
|
||||
list.resize(4);
|
||||
Info<< list[10] << "\n"; // print zero, but doesn't adjust list
|
||||
list[8] = 1;
|
||||
@endcode
|
||||
|
||||
SeeAlso
|
||||
Foam::DynamicList
|
||||
|
||||
@ -120,9 +130,6 @@ class PackedList
|
||||
//- Calculate the list length when packed
|
||||
inline static label packedLength(const label);
|
||||
|
||||
//- Check index I is within valid range [ 0 .. max_value() ]
|
||||
inline void checkIndex(const label) const;
|
||||
|
||||
public:
|
||||
|
||||
// Public data
|
||||
@ -172,22 +179,23 @@ public:
|
||||
|
||||
// Access
|
||||
|
||||
//- The number of elements that can be stored before resizing
|
||||
//- The number of elements that can be stored before reallocating
|
||||
inline label capacity() const;
|
||||
|
||||
//- Number of entries.
|
||||
inline label size() const;
|
||||
|
||||
//- Return true if the list is empty (i.e., if size() == 0).
|
||||
//- Return true if the list is empty (i.e., size() == 0).
|
||||
inline bool empty() const;
|
||||
|
||||
//- Get value at index I.
|
||||
// Does not auto-vivify entries.
|
||||
// Never auto-vivify entries.
|
||||
inline unsigned int get(const label) const;
|
||||
|
||||
//- Set value at index I. Return true if value changed.
|
||||
// Does not auto-vivify entries.
|
||||
inline bool set(const label, const unsigned int val);
|
||||
// Does auto-vivify for non-existent entries.
|
||||
// Default value set is the max_value.
|
||||
inline bool set(const label, const unsigned int val = ~0u);
|
||||
|
||||
//- Return the underlying packed storage
|
||||
inline List<unsigned int>& storage();
|
||||
@ -200,9 +208,6 @@ public:
|
||||
// http://en.wikipedia.org/wiki/Hamming_weight
|
||||
unsigned int count() const;
|
||||
|
||||
//- Trim any trailing zero elements
|
||||
bool trim();
|
||||
|
||||
//- Return the values as a labelList
|
||||
labelList values() const;
|
||||
|
||||
@ -211,6 +216,12 @@ public:
|
||||
|
||||
// Edit
|
||||
|
||||
//- Trim any trailing zero elements
|
||||
bool trim();
|
||||
|
||||
//- Invert the bits in the addressable region.
|
||||
void flip();
|
||||
|
||||
//- Alter the size of the underlying storage.
|
||||
// The addressed size will be truncated if needed to fit, but will
|
||||
// remain otherwise untouched.
|
||||
@ -255,12 +266,12 @@ public:
|
||||
inline unsigned int remove();
|
||||
|
||||
//- Get value at index I
|
||||
// Does not auto-vivify entries.
|
||||
// Never auto-vivify entries.
|
||||
inline unsigned int operator[](const label) const;
|
||||
|
||||
//- Set value at index I.
|
||||
// Returns iterator to perform the actual operation.
|
||||
// Does not auto-vivify entries.
|
||||
// Does not auto-vivify entries, but will when assigned to.
|
||||
inline iteratorBase operator[](const label);
|
||||
|
||||
//- Assignment of all entries to the given value. Takes linear time.
|
||||
@ -294,52 +305,27 @@ public:
|
||||
// This also lets us use the default bitwise copy/assignment
|
||||
PackedList* list_;
|
||||
|
||||
//- Element index within storage
|
||||
unsigned index_;
|
||||
|
||||
//- Offset within storage element
|
||||
unsigned offset_;
|
||||
//- Element index
|
||||
label index_;
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Get value as unsigned
|
||||
//- Get value as unsigned, no range-checking
|
||||
inline unsigned int get() const;
|
||||
|
||||
//- Set value, returning true if changed
|
||||
//- Set value, returning true if changed, no range-checking
|
||||
inline bool set(unsigned int);
|
||||
|
||||
//- Increment to new position
|
||||
inline void incr();
|
||||
|
||||
//- Decrement to new position
|
||||
inline void decr();
|
||||
|
||||
//- Move to new position, but not beyond end()
|
||||
inline void seek(const iteratorBase&);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
inline iteratorBase();
|
||||
|
||||
//- Copy construct
|
||||
inline iteratorBase(const iteratorBase&);
|
||||
|
||||
//- Construct from base list and position index
|
||||
inline iteratorBase(const PackedList*, const label);
|
||||
|
||||
public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return true if the element is within addressable range
|
||||
inline bool valid() 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
|
||||
|
||||
//- Compare positions
|
||||
@ -350,10 +336,12 @@ public:
|
||||
// This allows packed[0] = packed[3] for assigning values
|
||||
inline unsigned int operator=(const iteratorBase&);
|
||||
|
||||
//- Assign value
|
||||
//- Assign value.
|
||||
// A non-existent entry will be auto-vivified.
|
||||
inline unsigned int operator=(const unsigned int val);
|
||||
|
||||
//- Conversion operator
|
||||
// Never auto-vivify entries.
|
||||
inline operator unsigned int () const;
|
||||
|
||||
//- Print value and information
|
||||
@ -378,6 +366,8 @@ public:
|
||||
inline iterator();
|
||||
|
||||
//- Construct from iterator base, eg iter(packedlist[i])
|
||||
// but also "iterator iter = packedlist[i];"
|
||||
// An out-of-range iterator is assigned end()
|
||||
inline iterator(const iteratorBase&);
|
||||
|
||||
//- Construct from base list and position index
|
||||
@ -386,6 +376,7 @@ public:
|
||||
// Member Operators
|
||||
|
||||
//- Assign from iteratorBase, eg iter = packedlist[i]
|
||||
// An out-of-range iterator is assigned end()
|
||||
inline iterator& operator=(const iteratorBase&);
|
||||
|
||||
//- Return value
|
||||
@ -427,7 +418,9 @@ public:
|
||||
//- Construct null
|
||||
inline const_iterator();
|
||||
|
||||
//- Construct from iterator base
|
||||
//- Construct from iterator base, eg iter(packedlist[i])
|
||||
// but also "const_iterator iter = packedlist[i];"
|
||||
// An out-of-range iterator is assigned end()
|
||||
inline const_iterator(const iteratorBase&);
|
||||
|
||||
//- Construct from base list and position index
|
||||
@ -439,7 +432,7 @@ public:
|
||||
// Member operators
|
||||
|
||||
//- Assign from iteratorBase or derived
|
||||
// eg, iter = packedlist[i] or iter = [non-const]list.begin()
|
||||
// eg, iter = packedlist[i] or even iter = list.begin()
|
||||
inline const_iterator& operator=(const iteratorBase&);
|
||||
|
||||
//- Return referenced value directly
|
||||
|
||||
@ -65,24 +65,6 @@ inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline void Foam::PackedList<nBits>::checkIndex(const label i) const
|
||||
{
|
||||
if (!size_)
|
||||
{
|
||||
FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
|
||||
<< "attempt to access element from zero-sized list"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
else if (i < 0 || i >= size_)
|
||||
{
|
||||
FatalErrorIn("PackedList<nBits>::checkIndex(const label)")
|
||||
<< "index " << i << " out of range 0 ... " << size_-1
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<unsigned nBits>
|
||||
@ -105,7 +87,7 @@ template<unsigned nBits>
|
||||
inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
|
||||
:
|
||||
StorageList(lst),
|
||||
size_(lst.size())
|
||||
size_(lst.size_)
|
||||
{}
|
||||
|
||||
|
||||
@ -132,20 +114,7 @@ template<unsigned nBits>
|
||||
inline Foam::PackedList<nBits>::iteratorBase::iteratorBase()
|
||||
:
|
||||
list_(0),
|
||||
index_(0),
|
||||
offset_(0)
|
||||
{}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
|
||||
(
|
||||
const iteratorBase& iter
|
||||
)
|
||||
:
|
||||
list_(iter.list_),
|
||||
index_(iter.index_),
|
||||
offset_(iter.offset_)
|
||||
index_(0)
|
||||
{}
|
||||
|
||||
|
||||
@ -157,8 +126,7 @@ inline Foam::PackedList<nBits>::iteratorBase::iteratorBase
|
||||
)
|
||||
:
|
||||
list_(const_cast<PackedList<nBits>*>(lst)),
|
||||
index_(i / packing()),
|
||||
offset_(i % packing())
|
||||
index_(i)
|
||||
{}
|
||||
|
||||
|
||||
@ -166,8 +134,11 @@ template<unsigned nBits>
|
||||
inline unsigned int
|
||||
Foam::PackedList<nBits>::iteratorBase::get() const
|
||||
{
|
||||
const unsigned int& stored = list_->StorageList::operator[](index_);
|
||||
return (stored >> (nBits * offset_)) & max_value();
|
||||
const unsigned int seg = index_ / packing();
|
||||
const unsigned int off = index_ % packing();
|
||||
|
||||
const unsigned int& stored = list_->StorageList::operator[](seg);
|
||||
return (stored >> (nBits * off)) & max_value();
|
||||
}
|
||||
|
||||
|
||||
@ -175,114 +146,37 @@ template<unsigned nBits>
|
||||
inline bool
|
||||
Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
|
||||
{
|
||||
unsigned int& stored = list_->StorageList::operator[](index_);
|
||||
const unsigned int seg = index_ / packing();
|
||||
const unsigned int off = index_ % packing();
|
||||
|
||||
unsigned int& stored = list_->StorageList::operator[](seg);
|
||||
const unsigned int prev = stored;
|
||||
|
||||
const unsigned int startBit = nBits * offset_;
|
||||
const unsigned int startBit = nBits * off;
|
||||
const unsigned int maskNew = max_value() << startBit;
|
||||
|
||||
if (val & ~max_value())
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
FatalErrorIn("PackedList<T>::iteratorBase::set(const unsigned int)")
|
||||
<< "value " << label(val)
|
||||
w << " out-of-range 0 ... " << label(max_value())
|
||||
<< " representable by " << nBits << " bits"
|
||||
<< abort(FatalError);
|
||||
# endif
|
||||
|
||||
// treat overflow as max_value
|
||||
// overflow is max_value, fill everything
|
||||
stored |= maskNew;
|
||||
}
|
||||
else
|
||||
{
|
||||
stored = (stored & ~maskNew) | (maskNew & (val << startBit));
|
||||
stored &= ~maskNew;
|
||||
stored |= maskNew & (val << startBit);
|
||||
}
|
||||
|
||||
return prev != stored;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline void
|
||||
Foam::PackedList<nBits>::iteratorBase::incr()
|
||||
{
|
||||
offset_++;
|
||||
if (offset_ >= packing())
|
||||
{
|
||||
offset_ = 0;
|
||||
index_++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline void
|
||||
Foam::PackedList<nBits>::iteratorBase::decr()
|
||||
{
|
||||
if (!offset_)
|
||||
{
|
||||
offset_ = packing();
|
||||
index_--;
|
||||
}
|
||||
offset_--;
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline void
|
||||
Foam::PackedList<nBits>::iteratorBase::seek
|
||||
(
|
||||
const iteratorBase& iter
|
||||
)
|
||||
{
|
||||
list_ = iter.list_;
|
||||
index_ = iter.index_;
|
||||
offset_ = iter.offset_;
|
||||
|
||||
this->validate();
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline bool
|
||||
Foam::PackedList<nBits>::iteratorBase::valid() const
|
||||
{
|
||||
label elemI = offset_ + index_ * packing();
|
||||
return (elemI < list_->size_);
|
||||
}
|
||||
|
||||
|
||||
template<unsigned 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
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline bool Foam::PackedList<nBits>::iteratorBase::operator==
|
||||
(
|
||||
const iteratorBase& iter
|
||||
) const
|
||||
{
|
||||
return this->index_ == iter.index_ && this->offset_ == iter.offset_;
|
||||
return this->index_ == iter.index_;
|
||||
}
|
||||
|
||||
|
||||
@ -292,7 +186,7 @@ inline bool Foam::PackedList<nBits>::iteratorBase::operator!=
|
||||
const iteratorBase& iter
|
||||
) const
|
||||
{
|
||||
return this->index_ != iter.index_ || this->offset_ != iter.offset_;
|
||||
return this->index_ != iter.index_;
|
||||
}
|
||||
|
||||
|
||||
@ -310,14 +204,11 @@ template<unsigned nBits>
|
||||
inline unsigned int
|
||||
Foam::PackedList<nBits>::iteratorBase::operator=(const unsigned int val)
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
// lazy evaluation would be nice to keep, but really slows things down
|
||||
label minsize = 1 + offset_ + index_ * packing();
|
||||
if (minsize > list_->size_)
|
||||
// lazy evaluation - increase size on assigment
|
||||
if (index_ >= list_->size_)
|
||||
{
|
||||
list_->resize(minsize);
|
||||
list_->resize(index_ + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
this->set(val);
|
||||
return val;
|
||||
@ -328,14 +219,11 @@ template<unsigned nBits>
|
||||
inline Foam::PackedList<nBits>::iteratorBase::operator
|
||||
unsigned int () const
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
// lazy evaluation would be nice to keep, but really slows things down
|
||||
label minsize = 1 + offset_ + index_ * packing();
|
||||
if (minsize > list_->size_)
|
||||
// lazy evaluation - return 0 for out-of-range
|
||||
if (index_ >= list_->size_)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return this->get();
|
||||
}
|
||||
@ -365,7 +253,12 @@ inline Foam::PackedList<nBits>::iterator::iterator
|
||||
:
|
||||
iteratorBase(iter)
|
||||
{
|
||||
this->validate();
|
||||
// avoid going past end()
|
||||
// eg, iter = iterator(list, Inf)
|
||||
if (this->index_ > this->list_->size_)
|
||||
{
|
||||
this->index_ = this->list_->size_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -377,7 +270,12 @@ inline Foam::PackedList<nBits>::const_iterator::const_iterator
|
||||
:
|
||||
iteratorBase(iter)
|
||||
{
|
||||
this->validate();
|
||||
// avoid going past end()
|
||||
// eg, iter = iterator(list, Inf)
|
||||
if (this->index_ > this->list_->size_)
|
||||
{
|
||||
this->index_ = this->list_->size_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -417,7 +315,16 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::iterator&
|
||||
Foam::PackedList<nBits>::iterator::operator=(const iteratorBase& iter)
|
||||
{
|
||||
this->seek(iter);
|
||||
this->list_ = iter.list_;
|
||||
this->index_ = iter.index_;
|
||||
|
||||
// avoid going past end()
|
||||
// eg, iter = iterator(list, Inf)
|
||||
if (this->index_ > this->list_->size_)
|
||||
{
|
||||
this->index_ = this->list_->size_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -426,7 +333,16 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::const_iterator&
|
||||
Foam::PackedList<nBits>::const_iterator::operator=(const iteratorBase& iter)
|
||||
{
|
||||
this->seek(iter);
|
||||
this->list_ = iter.list_;
|
||||
this->index_ = iter.index_;
|
||||
|
||||
// avoid going past end()
|
||||
// eg, iter = iterator(list, Inf)
|
||||
if (this->index_ > this->list_->size_)
|
||||
{
|
||||
this->index_ = this->list_->size_;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -435,7 +351,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::iterator&
|
||||
Foam::PackedList<nBits>::iterator::operator++()
|
||||
{
|
||||
this->incr();
|
||||
++this->index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -444,7 +360,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::const_iterator&
|
||||
Foam::PackedList<nBits>::const_iterator::operator++()
|
||||
{
|
||||
this->incr();
|
||||
++this->index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -454,7 +370,7 @@ inline typename Foam::PackedList<nBits>::iterator
|
||||
Foam::PackedList<nBits>::iterator::operator++(int)
|
||||
{
|
||||
iterator old = *this;
|
||||
this->incr();
|
||||
++this->index_;
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -464,7 +380,7 @@ inline typename Foam::PackedList<nBits>::const_iterator
|
||||
Foam::PackedList<nBits>::const_iterator::operator++(int)
|
||||
{
|
||||
const_iterator old = *this;
|
||||
this->incr();
|
||||
++this->index_;
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -473,7 +389,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::iterator&
|
||||
Foam::PackedList<nBits>::iterator::operator--()
|
||||
{
|
||||
this->decr();
|
||||
--this->index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -482,7 +398,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::const_iterator&
|
||||
Foam::PackedList<nBits>::const_iterator::operator--()
|
||||
{
|
||||
this->decr();
|
||||
--this->index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -492,7 +408,7 @@ inline typename Foam::PackedList<nBits>::iterator
|
||||
Foam::PackedList<nBits>::iterator::operator--(int)
|
||||
{
|
||||
iterator old = *this;
|
||||
this->decr();
|
||||
--this->index_;
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -502,7 +418,7 @@ inline typename Foam::PackedList<nBits>::const_iterator
|
||||
Foam::PackedList<nBits>::const_iterator::operator--(int)
|
||||
{
|
||||
const_iterator old = *this;
|
||||
this->decr();
|
||||
--this->index_;
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -567,7 +483,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::iterator
|
||||
Foam::PackedList<nBits>::end()
|
||||
{
|
||||
return iterator(this, this->size());
|
||||
return iterator(this, size_);
|
||||
}
|
||||
|
||||
|
||||
@ -575,7 +491,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::const_iterator
|
||||
Foam::PackedList<nBits>::end() const
|
||||
{
|
||||
return const_iterator(this, this->size());
|
||||
return const_iterator(this, size_);
|
||||
}
|
||||
|
||||
|
||||
@ -583,7 +499,7 @@ template<unsigned nBits>
|
||||
inline typename Foam::PackedList<nBits>::const_iterator
|
||||
Foam::PackedList<nBits>::cend() const
|
||||
{
|
||||
return const_iterator(this, this->size());
|
||||
return const_iterator(this, size_);
|
||||
}
|
||||
|
||||
|
||||
@ -617,20 +533,12 @@ inline void Foam::PackedList<nBits>::resize
|
||||
// fill new elements or newly exposed elements
|
||||
if (size_)
|
||||
{
|
||||
// fill value for complete chunks
|
||||
// fill value for complete segments
|
||||
unsigned int fill = val;
|
||||
|
||||
if (fill & ~max_value())
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
FatalErrorIn("PackedList<T>::resize(label, const unsigned int)")
|
||||
<< "value " << label(val)
|
||||
<< " out-of-range 0 ... " << label(max_value())
|
||||
<< " representable by " << nBits << " bits"
|
||||
<< abort(FatalError);
|
||||
# endif
|
||||
|
||||
// treat overflow as max_value, fill everything
|
||||
// overflow is max_value, fill everything
|
||||
fill = ~0;
|
||||
}
|
||||
else
|
||||
@ -641,26 +549,26 @@ inline void Foam::PackedList<nBits>::resize
|
||||
}
|
||||
}
|
||||
|
||||
unsigned begIdx = size_ / packing();
|
||||
unsigned begOff = size_ % packing();
|
||||
unsigned endIdx = nElem / packing();
|
||||
unsigned int seg = size_ / packing();
|
||||
unsigned int off = size_ % packing();
|
||||
|
||||
// partial chunk, preserve existing value
|
||||
if (begOff)
|
||||
// partial segment, preserve existing value
|
||||
if (off)
|
||||
{
|
||||
unsigned int maskOld = maskLower(begOff);
|
||||
unsigned int maskOld = maskLower(off);
|
||||
|
||||
StorageList::operator[](begIdx) &= maskOld;
|
||||
StorageList::operator[](begIdx) |= ~maskOld & fill;
|
||||
StorageList::operator[](seg) &= maskOld;
|
||||
StorageList::operator[](seg) |= ~maskOld & fill;
|
||||
|
||||
// continue with the next chunk
|
||||
begIdx++;
|
||||
// continue with the next segment
|
||||
seg++;
|
||||
}
|
||||
|
||||
unsigned int endSeg = nElem / packing();
|
||||
// fill in complete elements
|
||||
while (begIdx < endIdx)
|
||||
while (seg < endSeg)
|
||||
{
|
||||
StorageList::operator[](begIdx++) = fill;
|
||||
StorageList::operator[](seg++) = fill;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -786,17 +694,31 @@ Foam::PackedList<nBits>::xfer()
|
||||
template<unsigned nBits>
|
||||
inline unsigned int Foam::PackedList<nBits>::get(const label i) const
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
checkIndex(i);
|
||||
# ifdef FULLDEBUG
|
||||
if (i < 0)
|
||||
{
|
||||
FatalErrorIn("PackedList<nBits>::get(const label)")
|
||||
<< "negative index " << i << " max=" << size_-1
|
||||
<< abort(FatalError);
|
||||
}
|
||||
# endif
|
||||
|
||||
return iteratorBase(this, i).get();
|
||||
// lazy evaluation - return 0 for out-of-range
|
||||
if (i < size_)
|
||||
{
|
||||
return iteratorBase(this, i).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<unsigned nBits>
|
||||
inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
|
||||
{
|
||||
// lazy evaluation - return 0 for out-of-range
|
||||
if (i < size_)
|
||||
{
|
||||
return iteratorBase(this, i).get();
|
||||
@ -815,18 +737,21 @@ inline bool Foam::PackedList<nBits>::set
|
||||
const unsigned int val
|
||||
)
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
checkIndex(i);
|
||||
|
||||
if (val & ~max_value())
|
||||
# ifdef FULLDEBUG
|
||||
if (i < 0)
|
||||
{
|
||||
FatalErrorIn("PackedList<T>::set(const label, const unsigned int)")
|
||||
<< "value " << label(val)
|
||||
<< " out-of-range 0 ... " << label(max_value())
|
||||
<< " representable by " << nBits << " bits"
|
||||
FatalErrorIn("PackedList<nBits>::set(const label)")
|
||||
<< "negative index " << i << " max=" << size_-1
|
||||
<< abort(FatalError);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// lazy evaluation - increase size on assigment
|
||||
if (i >= size_)
|
||||
{
|
||||
resize(i + 1);
|
||||
}
|
||||
|
||||
return iteratorBase(this, i).set(val);
|
||||
}
|
||||
|
||||
@ -879,14 +804,6 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
|
||||
|
||||
if (fill & ~max_value())
|
||||
{
|
||||
# ifdef DEBUGList
|
||||
FatalErrorIn("PackedList<T>::operator=(const unsigned int)")
|
||||
<< "value " << label(val)
|
||||
<< " out-of-range 0 ... " << label(max_value())
|
||||
<< " representable by " << nBits << " bits"
|
||||
<< abort(FatalError);
|
||||
# endif
|
||||
|
||||
// treat overflow as max_value
|
||||
fill = ~0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user