PackedList: encapsulate calculations in an iterator

- eliminated previous PackedBitRef class, the iterator does all of that and
  can also be used to (forward) traverse the list
- no const_iterator yet

- Note that PackedList is also a bit like DynamicList in terms of storage
  management and the append() method. Since the underlying storage in
  integer, any auto-vivified elements will also flood-fill the gaps with
  zero.
This commit is contained in:
Mark Olesen
2009-01-23 01:40:55 +01:00
parent 173607fd2d
commit cc4cd0a171
4 changed files with 527 additions and 349 deletions

View File

@ -28,112 +28,144 @@ Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "IOstreams.H"
#include "IStringStream.H"
#include "scalar.H"
#include "vector.H"
#include "ListOps.H"
#include "List.H"
#include "PackedBoolList.H"
#include <bitset>
using namespace Foam;
template <int nBits>
void printPackedList(const PackedList<nBits>& L)
{
const List<unsigned int>& stor = L.storage();
cout<< "PackedList<" << nBits << ">"
<< " max_bits:" << L.max_bits()
<< " max_value:" << L.max_value()
<< " packing:" << L.packing() << nl;
cout<< "values: " << L.size() << "/" << L.capacity() << " ( ";
forAll(L, i)
{
cout<< L[i] << ' ';
}
cout<< ")\n";
// using std:bitset for output works, but annoys valgrind
cout<< "storage: " << stor.size() << "( ";
forAll(stor, i)
{
cout<< std::bitset<32>(stor[i]) << ' ';
}
cout<< ")\n" << nl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
cout<< "PackedList::max_bits() = " << PackedList<0>::max_bits() << nl;
{
bool changed;
Info<< "PackedList max_bits() = " << PackedList<0>::max_bits() << nl;
Info<< "\ntest allocation with value\n";
PackedList<3> list1(5,1);
list1.print(Info);
printPackedList(list1);
Info<< "\ntest assign uniform value\n";
list1 = 2;
printPackedList(list1);
list1.print(Info);
Info<< "\ntest resize with value (without reallocation)\n";
list1.resize(6, 3);
printPackedList(list1);
list1.print(Info);
Info<< "\ntest set() function\n";
list1.set(1, 5);
list1.print(Info);
Info<< "\ntest assign bool\n";
list1 = false;
printPackedList(list1);
list1.print(Info);
Info<< "\ntest assign bool\n";
list1 = true;
printPackedList(list1);
list1.print(Info);
Info<< "\ntest resize without value (with reallocation)\n";
list1.resize(12);
printPackedList(list1);
list1.print(Info);
Info<< "\ntest resize with value (with reallocation)\n";
list1.resize(25, list1.max_value());
printPackedList(list1);
list1.print(Info);
Info<< "\ntest resize smaller (should not touch allocation)\n";
list1.resize(8);
printPackedList(list1);
list1.print(Info);
Info<< "\ntest append() operation\n";
list1.append(2);
list1.append(3);
list1.append(4);
printPackedList(list1);
list1.print(Info);
Info<< "\ntest reserve() operation\n";
list1.reserve(32);
printPackedList(list1);
list1.print(Info);
Info<< "\ntest shrink() operation\n";
list1.shrink();
printPackedList(list1);
list1.print(Info);
list1.setSize(15);
printPackedList(list1);
Info<< "\ntest setCapacity() operation\n";
list1.setCapacity(15);
list1.print(Info);
list1.setSize(32);
printPackedList(list1);
Info<< "\ntest setCapacity() operation\n";
list1.setCapacity(30);
list1.print(Info);
// test assignment
Info<< "\ntest operator[] assignment\n";
list1[16] = 5;
printPackedList(list1);
list1.print(Info);
// auto-vivify
Info<< "\ntest operator[] assignment with auto-vivify\n";
list1[36] = list1.max_value();
printPackedList(list1);
list1.print(Info);
list1.setSize(4);
printPackedList(list1);
Info<< "\ntest setCapacity smaller\n";
list1.setCapacity(32);
list1.print(Info);
// add in some misc values
list1[31] = 1;
list1[32] = 2;
list1[33] = 3;
Info<< "\ntest iterator\n";
PackedList<3>::iterator iter = list1.begin();
Info<< "iterator:" << iter() << "\n";
iter.print(Info) << "\n";
Info<< "\ntest iterator operator=\n";
changed = (iter = 5);
Info<< "iterator:" << iter() << "\n";
Info<< "changed:" << changed << "\n";
changed = (iter = 5);
Info<< "changed:" << changed << "\n";
list1.print(Info);
Info<< "\ntest get() method\n";
Info<< "get(10):" << list1.get(10)
<< " and list[10]:" << unsigned(list1[10]) << "\n";
list1.print(Info);
Info<< "\ntest iterator indexing\n";
Info<< "end() ";
list1.end().print(Info) << "\n";
for (iter = list1[31]; iter != list1.end(); ++iter)
{
iter.print(Info);
}
Info<< "\ntest operator[] auto-vivify\n";
const unsigned int val = list1[45];
Info<< "list[45]:" << val << "\n";
list1.print(Info);
Info<< "\ntest copy constructor + append\n";
PackedList<3> list2(list1);
list2.append(4);
Info<< "source list:\n";
list1.print(Info);
Info<< "destination list:\n";
list2.print(Info);
cout << "after copy + append\n";
printPackedList(list1);
printPackedList(list2);
Info<< "\ntest pattern that fills all bits\n";
PackedList<4> list3(8, 8);
list3[list3.size()-2] = 0;
list3[list3.size()-1] = list3.max_value();
list3.print(Info);
Info<< "\n\nDone.\n";
return 0;
}

View File

@ -31,7 +31,7 @@ License
template<int nBits>
Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
:
List<unsigned int>(storageSize(size)),
List<PackedStorage>(packedLength(size), 0u),
size_(size)
{
operator=(val);
@ -41,7 +41,7 @@ Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
template<int nBits>
Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
:
List<unsigned int>(storageSize(lst.size()), 0),
List<PackedStorage>(packedLength(lst.size()), 0u),
size_(lst.size())
{
forAll(lst, i)
@ -51,7 +51,6 @@ Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<int nBits>
@ -67,13 +66,81 @@ Foam::labelList Foam::PackedList<nBits>::values() const
}
template<int nBits>
Foam::Ostream& Foam::PackedList<nBits>::iterator::print(Ostream& os) const
{
os << "iterator<" << nBits << "> [" << position() << "]"
<< " elem:" << elem_ << " offset:" << offset_
<< " value:" << unsigned(*this)
<< nl;
return os;
}
template<int nBits>
Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
{
os << "PackedList<" << nBits << ">"
<< " max_value:" << max_value()
<< " packing:" << packing() << nl
<< "values: " << size() << "/" << capacity() << "( ";
forAll(*this, i)
{
os << get(i) << ' ';
}
os << ")\n"
<< "storage: " << storage().size() << "( ";
label count = size();
forAll(storage(), i)
{
const PackedStorage& rawBits = storage()[i];
// create mask for unaddressed bits
unsigned int addressed = 0;
for (unsigned packI = 0; count && packI < packing(); packI++, count--)
{
addressed <<= nBits;
addressed |= max_value();
}
for (unsigned int testBit = 0x1 << max_bits(); testBit; testBit >>= 1)
{
if (testBit & addressed)
{
if (rawBits & testBit)
{
os << '1';
}
else
{
os << '0';
}
}
else
{
os << '_';
}
}
cout << ' ';
}
os << ")\n";
return os;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<int nBits>
void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
{
setCapacity(lst.size());
List<unsigned int>::operator=(lst);
List<PackedStorage>::operator=(lst);
}

View File

@ -40,7 +40,7 @@ SeeAlso
ToDo
Add checks for bad template parameters (ie, nBits=0, nBits too large).
Could make PackedBitRef an iterator and use for traversing as well.
The missing const_iterator might eventually still be needed.
SourceFiles
PackedListI.H
@ -52,7 +52,6 @@ SourceFiles
#define PackedList_H
#include "labelList.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -72,84 +71,6 @@ template<int nBits> class PackedList;
TemplateName(PackedList);
/*---------------------------------------------------------------------------*\
Class PackedBitRef Declaration
\*---------------------------------------------------------------------------*/
//- The PackedBitRef is used for PackedList
template <int nBits>
class PackedBitRef
{
private:
// private data
// const mutable List<unsigned int>& list_;
unsigned int& elem_;
const label startBit_;
public:
// Static Public Members
//- The max. number of bits that can be templated.
// Might someday be useful for a template assert.
inline static unsigned int max_bits();
//- The max. value for an entry, can also be used as the mask
// eg, ((1 << 2) - 1) yields 0b0011
inline static unsigned int max_value();
//- The number of entries per storage entry
inline static unsigned int packing();
// Constructors
inline PackedBitRef
(
// const List<unsigned int>& lst
const unsigned int& elem, label startBit)
:
// list_(lst),
elem_(const_cast<unsigned int&>(elem)),
startBit_(startBit)
{}
// Members
// Assign value
inline void operator=(const unsigned int val)
{
unsigned int shiftedMask = max_value() << startBit_;
unsigned int shiftedVal = (val & max_value()) << startBit_;
elem_ = (elem_ & ~shiftedMask) | shiftedVal;
}
// return value
inline unsigned int operator()() const
{
return ((elem_ >> startBit_) & max_value());
}
//- Conversion operator
inline operator unsigned int () const
{
return ((elem_ >> startBit_) & max_value());
}
//- Conversion operator
inline operator bool() const
{
return !!((elem_ >> startBit_) & max_value());
}
};
/*---------------------------------------------------------------------------*\
Class PackedList Declaration
\*---------------------------------------------------------------------------*/
@ -159,6 +80,8 @@ class PackedList
:
private List<unsigned int>
{
typedef unsigned int PackedStorage;
// Private data
//- Number of nBits entries
@ -166,16 +89,10 @@ class PackedList
// Private Member Functions
//- Calculate underlying list size
inline static label storageSize(const label);
//- Calculate the list length when packed
inline static label packedLength(const label);
//- Calculate element index and offset (start) bit within storage
inline static label location(const label, label& offset);
//- Check if value is representable in nBits
inline static void checkValue(const unsigned int);
//- Check index i is within valid range (0 ... size-1).
//- Check index I is within valid range [ 0 .. max_value() ]
inline void checkIndex(const label) const;
public:
@ -184,23 +101,18 @@ public:
//- The max. number of bits that can be templated.
// Might someday be useful for a template assert.
inline static unsigned int max_bits()
{
return PackedBitRef<nBits>::max_bits();
}
inline static unsigned int max_bits();
//- The max. value for an entry, can also be used as the mask
//- The max. value for an entry, which simultaneously the bit-mask
// eg, ((1 << 2) - 1) yields 0b0011
inline static unsigned int max_value()
{
return PackedBitRef<nBits>::max_value();
}
inline static unsigned int max_value();
//- The number of entries per storage entry
inline static unsigned int packing()
{
return PackedBitRef<nBits>::packing();
}
//- The number of entries per packed storage element
inline static unsigned int packing();
// Forward declaration of iterator
class iterator;
friend class iterator;
// Constructors
@ -208,7 +120,7 @@ public:
//- Null constructor
inline PackedList();
//- Construct with given size. Note: initializes list to 0.
//- Construct with given size, initializes list to 0.
inline PackedList(const label size);
//- Construct with given size and value for all elements.
@ -233,38 +145,41 @@ public:
//- The number of elements that can be stored before resizing
inline label capacity() const;
//- Number of packed elements.
//- Number of entries.
inline label size() const;
//- Return true if the list is empty (i.e., if size() == 0).
inline bool empty() const;
//- Get value at index I.
// Does not auto-vivifies elements.
inline unsigned int get(const label i) const;
// Does not auto-vivifies entries.
inline unsigned int get(const label) const;
//- Set value at index I. Return true if value changed.
// Does not auto-vivifies elements.
inline bool set(const label i, const unsigned int val);
// Does not auto-vivifies entries.
inline bool set(const label, const unsigned int val);
//- Underlying storage
//- Return the underlying packed storage
inline const List<unsigned int>& storage() const;
//- Return as labelList
//- Return the values as a labelList
labelList values() const;
//- Print values and information
Ostream& print(Ostream&) const;
// Edit
//- Alter the size of the underlying storage.
// The addressed size will be truncated if needed to fit, but will
// remain otherwise untouched.
// Use this or reserve() in combination with append().
inline void setCapacity(const label);
//- Reset size of List, optionally specify a value for new elements.
//- Reset addressable list size, does not shrink the allocated size.
// Optionally specify a value for new elements.
inline void resize(const label, const unsigned int& val = 0);
//- Reset size of List, optionally specify a value for new elements.
//- Alias for resize()
inline void setSize(const label, const unsigned int& val = 0);
//- Reserve allocation space for at least this size.
@ -272,8 +187,8 @@ public:
// Optionally provide an initialization value for new elements.
inline void reserve(const label, const unsigned int& val = 0);
//- Clear the list, i.e. set size to zero.
//- Does not adjust the underlying storage
//- Clear the list, i.e. set addressable size to zero.
// Does not adjust the underlying storage
inline void clear();
//- Clear the list and delete storage.
@ -282,7 +197,7 @@ public:
//- Shrink the allocated space to what is used.
inline void shrink();
//- Transfer the contents of the argument List into this List
//- Transfer the contents of the argument list into this list
// and annull the argument list.
inline void transfer(PackedList<nBits>&);
@ -291,17 +206,17 @@ public:
// Member operators
//- Append a value at the end of the list. Return true if value changed.
inline bool append(const unsigned int val);
//- Append a value at the end of the list
inline void append(const unsigned int val);
//- Get value at index I
// Does not auto-vivifies elements.
inline unsigned int operator[](const label i) const;
// Auto-vivifies any new values to zero.
inline unsigned int operator[](const label) const;
//- Set value at index I.
// Returns proxy to perform the actual operation.
// Auto-vivifies any new values to zero.
inline ::Foam::PackedBitRef<nBits> operator[](const label i);
inline iterator operator[](const label);
//- Assignment of all entries to the given value.
// Does set on all elements.
@ -318,6 +233,71 @@ public:
// // Write PackedList to Ostream.
// friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
//- The iterator-like class used for PackedList
class iterator
{
friend class PackedList;
// Private Data
//- Reference to original list
PackedList& list_;
//- Element index within storage
unsigned elem_;
//- Offset within storage element
unsigned offset_;
//- Return the raw storage element
inline PackedStorage& chunk() const;
//- Return the position in the PackedList
inline label position() const;
public:
// Constructors
//- Construct from base list and position index
inline iterator(const PackedList&, const label i);
// Members
//- Assign value, returns true if the value changed
inline bool operator=(const unsigned int val);
//- Conversion operator
inline operator unsigned int () const;
//- Conversion operator
inline operator bool() const;
// Member operators
inline void operator=(const iterator&);
inline bool operator==(const iterator&) const;
inline bool operator!=(const iterator&) const;
//- Return referenced value
inline unsigned int operator()() const;
inline iterator& operator++();
inline iterator operator++(int);
//- Print value and information
Ostream& print(Ostream&) const;
};
//- iterator set to the begining of the PackedList
inline iterator begin();
//- iterator set to beyond the end of the HashTable
inline iterator end();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -25,71 +25,38 @@ License
\*---------------------------------------------------------------------------*/
#ifndef PackedListI_H
#define PackedListI_H
#include "IOstreams.H"
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<int nBits>
inline unsigned int Foam::PackedBitRef<nBits>::max_bits()
inline unsigned int Foam::PackedList<nBits>::max_bits()
{
return sizeof(unsigned int)*8 - 1;
return sizeof(PackedStorage)*8 - 1;
}
template<int nBits>
inline unsigned int Foam::PackedBitRef<nBits>::max_value()
inline unsigned int Foam::PackedList<nBits>::max_value()
{
return ((1u << nBits) - 1);
}
template<int nBits>
inline unsigned int Foam::PackedBitRef<nBits>::packing()
inline unsigned int Foam::PackedList<nBits>::packing()
{
return sizeof(unsigned int)*8 / nBits;
}
// Calculate underlying list size
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::storageSize(const label sz)
{
return (sz + packing() - 1) / packing();
return sizeof(PackedStorage)*8 / nBits;
}
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::location
(
const label i,
label& offset
)
inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
{
// the offset is the start bit within the storage element
offset = nBits * (i % packing());
return i / packing();
return (nElem + packing() - 1) / packing();
}
// Check value is representable in nBits
template<int nBits>
inline void Foam::PackedList<nBits>::checkValue(const unsigned int val)
{
if (val > max_value())
{
FatalErrorIn("PackedList<T>::checkValue(const unsigned int)")
<< "value " << label(val) << " out of range 0 ... "
<< label(max_value())
<< " representable by " << nBits << " bits"
<< abort(FatalError);
}
}
// Check index i is within valid range (0 ... size-1).
template<int nBits>
inline void Foam::PackedList<nBits>::checkIndex(const label i) const
{
@ -110,20 +77,18 @@ inline void Foam::PackedList<nBits>::checkIndex(const label i) const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Null constructor
template<int nBits>
inline Foam::PackedList<nBits>::PackedList()
:
List<unsigned int>(),
List<PackedStorage>(),
size_(0)
{}
// Construct with given size.
template<int nBits>
inline Foam::PackedList<nBits>::PackedList(const label size)
:
List<unsigned int>(storageSize(size), 0u),
List<PackedStorage>(packedLength(size), 0u),
size_(size)
{}
@ -131,7 +96,7 @@ inline Foam::PackedList<nBits>::PackedList(const label size)
template<int nBits>
inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
:
List<unsigned int>(lst),
List<PackedStorage>(lst),
size_(lst.size())
{}
@ -143,14 +108,161 @@ inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
}
template<int nBits>
inline Foam::autoPtr<Foam::PackedList<nBits> > Foam::PackedList<nBits>::clone() const
inline Foam::autoPtr<Foam::PackedList<nBits> >
Foam::PackedList<nBits>::clone() const
{
return autoPtr<PackedList<nBits> >(new PackedList<nBits>(*this));
}
// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
template<int nBits>
inline Foam::PackedList<nBits>::iterator::iterator
(
const PackedList<nBits>& lst,
const label i
)
:
list_(const_cast<PackedList<nBits>&>(lst)),
elem_(i / packing()),
offset_(i % packing())
{}
template<int nBits>
inline void Foam::PackedList<nBits>::iterator::operator=
(
const iterator& iter
)
{
elem_ = iter.elem_;
offset_ = iter.offset_;
}
template<int nBits>
inline bool Foam::PackedList<nBits>::iterator::operator==
(
const iterator& iter
) const
{
return elem_ == iter.elem_ && offset_ == iter.offset_;
}
template<int nBits>
inline bool Foam::PackedList<nBits>::iterator::operator!=
(
const iterator& iter
) const
{
return !(operator==(iter));
}
template<int nBits>
inline bool Foam::PackedList<nBits>::iterator::operator=
(
const unsigned int val
)
{
const unsigned int startBit = nBits * offset_;
const unsigned int mask = max_value() << startBit;
unsigned int& stored = chunk();
const unsigned int old = stored;
stored &= ~mask;
stored |= (val << startBit) & mask;
return (old != stored);
}
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::iterator::position() const
{
return (elem_ * packing() + offset_);
}
template<int nBits>
inline unsigned int& Foam::PackedList<nBits>::iterator::chunk() const
{
return list_.List<PackedStorage>::operator[](elem_);
}
template<int nBits>
inline typename Foam::PackedList<nBits>::iterator&
Foam::PackedList<nBits>::iterator::operator++()
{
if (position() < list_.size())
{
offset_++;
if (offset_ >= packing())
{
elem_++;
offset_ = 0;
}
}
return *this;
}
template<int nBits>
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::iterator::operator++(int)
{
iterator old = *this;
++*this;
return old;
}
template<int nBits>
inline unsigned int
Foam::PackedList<nBits>::iterator::operator()() const
{
return (chunk() >> (nBits * offset_)) & max_value();
}
template<int nBits>
inline Foam::PackedList<nBits>::iterator::operator
unsigned int () const
{
return (chunk() >> (nBits * offset_)) & max_value();
}
template<int nBits>
inline Foam::PackedList<nBits>::iterator::operator
bool() const
{
return !!(chunk() >> (nBits * offset_)) & max_value();
}
template<int nBits>
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::begin()
{
return iterator(*this, 0);
}
template<int nBits>
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::end()
{
return iterator(*this, size());
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<int nBits>
@ -170,12 +282,12 @@ inline bool Foam::PackedList<nBits>::empty() const
template<int nBits>
inline void Foam::PackedList<nBits>::resize
(
const label newSize,
const label nElem,
const unsigned int& val
)
{
reserve(newSize, val);
size_ = newSize;
reserve(nElem, val);
size_ = nElem;
}
@ -194,21 +306,35 @@ inline void Foam::PackedList<nBits>::setSize
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::capacity() const
{
return packing() * List<unsigned int>::size();
return packing() * List<PackedStorage>::size();
}
template<int nBits>
inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
{
List<unsigned int>::setSize(storageSize(nElem), 0);
List<PackedStorage>::setSize(packedLength(nElem), 0u);
for (label i = size_; i < nElem; i++)
// truncates addressable section too
if (size_ > nElem)
{
set(i, 0);
# ifdef DEBUGList
// clear old values (purely cosmetics for string output)
for (label i = nElem; i < size_; i++)
{
set(i, 0);
}
# endif
size_ = nElem;
}
else
{
// fill new elements
for (label i = size_; i < nElem; i++)
{
set(i, 0);
}
}
size_ = nElem;
}
@ -219,15 +345,15 @@ inline void Foam::PackedList<nBits>::reserve
const unsigned int& val
)
{
label rawSize = storageSize(nElem);
label len = packedLength(nElem);
// need more capacity?
if (rawSize > List<unsigned int>::size())
if (len > List<PackedStorage>::size())
{
List<unsigned int>::setSize(rawSize, 0);
List<PackedStorage>::setSize(len, 0);
}
// fill new elements, don't rely on List::setSize
// fill new elements
for (label i = size_; i < nElem; i++)
{
set(i, val);
@ -245,7 +371,7 @@ inline void Foam::PackedList<nBits>::clear()
template<int nBits>
inline void Foam::PackedList<nBits>::clearStorage()
{
List<unsigned int>::clear();
List<PackedStorage>::clear();
size_ = 0;
}
@ -253,86 +379,20 @@ inline void Foam::PackedList<nBits>::clearStorage()
template<int nBits>
inline void Foam::PackedList<nBits>::shrink()
{
label rawSize = storageSize(size_);
label len = packedLength(size_);
// we have unused space?
if (rawSize < List<unsigned int>::size())
if (len < List<PackedStorage>::size())
{
List<unsigned int>::setSize(rawSize);
List<PackedStorage>::setSize(len);
}
}
// Get value at i
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::get(const label i) const
inline const Foam::List<unsigned int>&
Foam::PackedList<nBits>::storage() const
{
# ifdef DEBUGList
checkIndex(i);
# endif
label startBit;
const unsigned int& elem = List<unsigned int>::operator[]
(
location(i, startBit)
);
// PackedBitRef<nBits> iter(*this, elem, startBit);
// return PackedBitRef<nBits>(*this, elem, startBit)();
return (elem >> startBit) & max_value();
}
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
{
return get(i);
}
// Set value at i
template<int nBits>
inline bool Foam::PackedList<nBits>::set(const label i, const unsigned int val)
{
# ifdef DEBUGList
checkIndex(i);
checkValue(val);
# endif
label startBit;
unsigned int& elem = List<unsigned int>::operator[]
(
location(i, startBit)
);
unsigned int oldElem = elem;
unsigned int shiftedMask = max_value() << startBit;
unsigned int shiftedVal = (val & max_value()) << startBit;
elem = (elem & ~shiftedMask) | shiftedVal;
return elem != oldElem;
}
template<int nBits>
inline bool Foam::PackedList<nBits>::append(const unsigned int val)
{
label elemI = size_;
reserve(elemI + 1);
size_++;
return set(elemI, val);
}
template<int nBits>
inline const Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() const
{
return static_cast<const List<unsigned int>&>(*this);
return static_cast<const List<PackedStorage>&>(*this);
}
@ -342,11 +402,10 @@ inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
size_ = lst.size_;
lst.size_ = 0;
List<unsigned int>::transfer(lst);
List<PackedStorage>::transfer(lst);
}
template<int nBits>
inline Foam::Xfer<Foam::PackedList<nBits> >
Foam::PackedList<nBits>::xfer()
@ -355,9 +414,69 @@ Foam::PackedList<nBits>::xfer()
}
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::get(const label i) const
{
# ifdef DEBUGList
checkIndex(i);
# endif
return iterator(*this, i)();
}
template<int nBits>
inline typename Foam::PackedBitRef<nBits>
inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
{
if (i >= size_)
{
setSize(i + 1);
return 0;
}
else
{
return iterator(*this, i)();
}
}
template<int nBits>
inline bool Foam::PackedList<nBits>::set
(
const label i,
const unsigned int val
)
{
# ifdef DEBUGList
checkIndex(i);
if (val & ~max_value())
{
FatalErrorIn("PackedList<T>::set(const label, const unsigned int)")
<< "value " << label(val)
<< " out-of-range 0 ... " << label(max_value())
<< " representable by " << nBits << " bits"
<< abort(FatalError);
}
# endif
return (iterator(*this, i) = val);
}
template<int nBits>
inline void Foam::PackedList<nBits>::append(const unsigned int val)
{
label elemI = size_;
reserve(elemI + 1);
size_++;
iterator(*this, elemI) = val;
}
template<int nBits>
inline typename Foam::PackedList<nBits>::iterator
Foam::PackedList<nBits>::operator[](const label i)
{
if (i >= size_)
@ -365,45 +484,25 @@ Foam::PackedList<nBits>::operator[](const label i)
setSize(i + 1);
}
label startBit;
unsigned int& elem = List<unsigned int>::operator[]
(
location(i, startBit)
);
return ::Foam::PackedBitRef<nBits>
(
// *this,
elem,
startBit
);
return iterator(*this, i);
}
// Set all to val
template<int nBits>
inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
{
# ifdef DEBUGList
checkValue(val);
# endif
if (val)
{
forAll(*this, i)
forAll(*this, elemI)
{
set(i, val);
set(elemI, val);
}
}
else
{
List<unsigned int>::operator=(val);
List<PackedStorage>::operator=(val);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //