PackedList gets functionality akin to DynamicList

This commit is contained in:
Mark Olesen
2009-01-22 16:24:05 +01:00
parent 6d57bb4e7b
commit 173607fd2d
4 changed files with 356 additions and 190 deletions

View File

@ -56,8 +56,9 @@ void printPackedList(const PackedList<nBits>& L)
{ {
cout<< L[i] << ' '; cout<< L[i] << ' ';
} }
cout<< ")\n\n"; cout<< ")\n";
// using std:bitset for output works, but annoys valgrind
cout<< "storage: " << stor.size() << "( "; cout<< "storage: " << stor.size() << "( ";
forAll(stor, i) forAll(stor, i)
{ {
@ -99,6 +100,41 @@ int main(int argc, char *argv[])
list1.resize(8); list1.resize(8);
printPackedList(list1); printPackedList(list1);
list1.append(2);
list1.append(3);
list1.append(4);
printPackedList(list1);
list1.reserve(32);
printPackedList(list1);
list1.shrink();
printPackedList(list1);
list1.setSize(15);
printPackedList(list1);
list1.setSize(32);
printPackedList(list1);
// test assignment
list1[16] = 5;
printPackedList(list1);
// auto-vivify
list1[36] = list1.max_value();
printPackedList(list1);
list1.setSize(4);
printPackedList(list1);
PackedList<3> list2(list1);
list2.append(4);
cout << "after copy + append\n";
printPackedList(list1);
printPackedList(list2);
return 0; return 0;
} }

View File

@ -38,21 +38,6 @@ Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
} }
template<int nBits>
Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
:
List<unsigned int>(lst),
size_(lst.size())
{}
template<int nBits>
Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
{
transfer(lst());
}
template<int nBits> template<int nBits>
Foam::PackedList<nBits>::PackedList(const UList<label>& lst) Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
: :
@ -66,77 +51,11 @@ Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
} }
template<int nBits>
Foam::autoPtr<Foam::PackedList<nBits> > Foam::PackedList<nBits>::clone() const
{
return autoPtr<PackedList<nBits> >(new PackedList<nBits>(*this));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<int nBits> template<int nBits>
void Foam::PackedList<nBits>::setSize(const label newSize) Foam::labelList Foam::PackedList<nBits>::values() const
{
List<unsigned int>::setSize(storageSize(newSize), 0);
size_ = newSize;
}
template<int nBits>
void Foam::PackedList<nBits>::setSize
(
const label newSize,
const unsigned int& val
)
{
# ifdef DEBUGList
checkValue(val);
# endif
List<unsigned int>::setSize(storageSize(newSize), 0);
if (val && newSize > size_)
{
// fill new elements
for (label i = size_; i < newSize; i++)
{
set(i, val);
}
}
size_ = newSize;
}
template<int nBits>
void Foam::PackedList<nBits>::clear()
{
List<unsigned int>::clear();
size_ = 0;
}
template<int nBits>
void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
{
size_ = lst.size();
List<unsigned int>::transfer(lst);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<int nBits>
void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
{
setSize(lst.size());
List<unsigned int>::operator=(lst);
}
template<int nBits>
Foam::labelList Foam::PackedList<nBits>::operator()() const
{ {
labelList elems(size()); labelList elems(size());
@ -148,6 +67,29 @@ Foam::labelList Foam::PackedList<nBits>::operator()() const
} }
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<int nBits>
void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
{
setCapacity(lst.size());
List<unsigned int>::operator=(lst);
}
template<int nBits>
void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
{
setCapacity(lst.size());
forAll(lst, i)
{
set(i, lst[i]);
}
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
//template<int nBits> //template<int nBits>

View File

@ -26,14 +26,21 @@ Class
Foam::PackedList Foam::PackedList
Description Description
List of packed unsigned ints. A Dynamically allocatable list of packed unsigned ints.
Gets given the number of bits per item. Gets given the number of bits per item.
Note
The list resizing is similar to DynamicList, thus the methods clear()
and setSize() behave like their DynamicList counterparts and the methods
reserve() and setCapacity() can be used to influence the allocation.
SeeAlso
Foam::DynamicList
ToDo ToDo
Add checks for bad template parameters (ie, nBits=0, nBits too large). Add checks for bad template parameters (ie, nBits=0, nBits too large).
Could make PackedBitRef an iterator and use for traversing as well. Could make PackedBitRef an iterator and use for traversing as well.
It could be useful to make PackedList behave a bit like DynamicList.
SourceFiles SourceFiles
PackedListI.H PackedListI.H
@ -52,6 +59,13 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators
template<int nBits> class PackedList;
// template<int nBits>
// Ostream& operator<<(Ostream&, const PackedList<nBits>&);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class PackedListName Declaration Class PackedListName Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -64,42 +78,73 @@ TemplateName(PackedList);
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
//- The PackedBitRef is used for PackedList //- The PackedBitRef is used for PackedList
template <int nBits>
class PackedBitRef class PackedBitRef
{ {
private: private:
// private data // private data
// const mutable List<unsigned int>& list_;
unsigned int& elem_; unsigned int& elem_;
const label startBit_; const label startBit_;
const unsigned int mask_;
public: public:
inline PackedBitRef(unsigned int& elem, label startBit, unsigned int mask) // 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)
: :
elem_(elem), // list_(lst),
startBit_(startBit), elem_(const_cast<unsigned int&>(elem)),
mask_(mask) startBit_(startBit)
{} {}
// Members
// Assign value
inline void operator=(const unsigned int val) inline void operator=(const unsigned int val)
{ {
unsigned int shiftedMask = mask_ << startBit_; unsigned int shiftedMask = max_value() << startBit_;
unsigned int shiftedVal = (val & mask_) << startBit_; unsigned int shiftedVal = (val & max_value()) << startBit_;
elem_ = (elem_ & ~shiftedMask) | shiftedVal; elem_ = (elem_ & ~shiftedMask) | shiftedVal;
} }
inline operator unsigned int () const // return value
inline unsigned int operator()() const
{ {
return ((elem_ >> startBit_) & mask_); return ((elem_ >> startBit_) & max_value());
} }
//- Conversion operator
inline operator unsigned int () const
{
return ((elem_ >> startBit_) & max_value());
}
//- Conversion operator
inline operator bool() const inline operator bool() const
{ {
return !!((elem_ >> startBit_) & mask_); return !!((elem_ >> startBit_) & max_value());
} }
}; };
@ -139,14 +184,23 @@ public:
//- The max. number of bits that can be templated. //- The max. number of bits that can be templated.
// Might someday be useful for a template assert. // Might someday be useful for a template assert.
inline static unsigned int max_bits(); inline static unsigned int max_bits()
{
return PackedBitRef<nBits>::max_bits();
}
//- The max. value for an entry, can also be used as the mask //- The max. value for an entry, can also be used as the mask
// eg, ((1 << 2) - 1) yields 0b0011 // eg, ((1 << 2) - 1) yields 0b0011
inline static unsigned int max_value(); inline static unsigned int max_value()
{
return PackedBitRef<nBits>::max_value();
}
//- The number of entries per storage entry //- The number of entries per storage entry
inline static unsigned int packing(); inline static unsigned int packing()
{
return PackedBitRef<nBits>::packing();
}
// Constructors // Constructors
@ -154,101 +208,116 @@ public:
//- Null constructor //- Null constructor
inline PackedList(); inline PackedList();
//- Construct with given size. Note: initializes intList to 0. //- Construct with given size. Note: initializes list to 0.
inline PackedList(const label size); inline PackedList(const label size);
//- Construct with given size and value for all elements. //- Construct with given size and value for all elements.
PackedList(const label size, const unsigned val); PackedList(const label size, const unsigned val);
//- Copy constructor. //- Copy constructor.
PackedList(const PackedList<nBits>& PList); inline PackedList(const PackedList<nBits>&);
//- Construct by transferring the parameter contents //- Construct by transferring the parameter contents
PackedList(const Xfer<PackedList<nBits> >&); inline PackedList(const Xfer<PackedList<nBits> >&);
//- Construct from a list of labels //- Construct from a list of labels
PackedList(const UList<label>&); PackedList(const UList<label>&);
//- Clone //- Clone
inline autoPtr<PackedList<nBits> > clone() const; inline autoPtr< PackedList<nBits> > clone() const;
// Member Functions // Member Functions
// Access // Access
//- The number of elements that can be stored before resizing //- The number of elements that can be stored before resizing
inline label capacity() const; inline label capacity() const;
//- Number of packed elements //- Number of packed elements.
inline label size() const; 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., if size() == 0).
inline bool empty() const; inline bool empty() const;
//- Get value at index I //- Get value at index I.
inline unsigned int get(const label i) const; // Does not auto-vivifies elements.
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.
inline bool set(const label i, const unsigned int val); // Does not auto-vivifies elements.
inline bool set(const label i, const unsigned int val);
//- Underlying storage //- Underlying storage
inline List<unsigned int>& storage(); inline const List<unsigned int>& storage() const;
//- Underlying storage
inline const List<unsigned int>& storage() const;
//- Return as labelList
labelList values() const;
// Edit // Edit
//- Reset size of List, setting zero for any new elements. //- Alter the size of the underlying storage.
void setSize(const label); // 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 and value for new elements. //- Reset size of List, optionally specify a value for new elements.
void setSize(const label, const unsigned int& val); inline void resize(const label, const unsigned int& val = 0);
//- Reset size of List, setting zero for any new elements. //- Reset size of List, optionally specify a value for new elements.
inline void resize(const label); inline void setSize(const label, const unsigned int& val = 0);
//- Reset size of List and value for new elements. //- Reserve allocation space for at least this size.
inline void resize(const label, const unsigned int& val); // Never shrinks the allocated size.
// Optionally provide an initialization value for new elements.
inline void reserve(const label, const unsigned int& val = 0);
//- Construct with given size and value for all elements. //- Clear the list, i.e. set size to zero.
//- Does not adjust the underlying storage
inline void clear();
//- Clear the list, i.e. set size to zero. //- Clear the list and delete storage.
void clear(); inline void clearStorage();
//- Transfer the contents of the argument List into this List //- Shrink the allocated space to what is used.
// and annull the argument list. inline void shrink();
void transfer(PackedList<nBits>&);
//- Transfer contents to the Xfer container //- Transfer the contents of the argument List into this List
inline Xfer<PackedList<nBits> > xfer(); // and annull the argument list.
inline void transfer(PackedList<nBits>&);
//- Transfer contents to the Xfer container
inline Xfer<PackedList<nBits> > xfer();
// Member operators // Member operators
//- Get value at index i //- Append a value at the end of the list. Return true if value changed.
inline unsigned int operator[](const label i) const; inline bool append(const unsigned int val);
//- Set value at index i. //- Get value at index I
// Returns proxy to perform the actual operation // Does not auto-vivifies elements.
inline ::Foam::PackedBitRef operator[](const label i); inline unsigned int operator[](const label i) const;
//- Assignment operator. Takes linear time. //- Set value at index I.
void operator=(const PackedList<nBits>&); // Returns proxy to perform the actual operation.
// Auto-vivifies any new values to zero.
inline ::Foam::PackedBitRef<nBits> operator[](const label i);
//- Assignment of all entries to the given value. //- Assignment of all entries to the given value.
// Does set on all elements. // Does set on all elements.
inline void operator=(const unsigned int val); inline void operator=(const unsigned int val);
//- Return as labelList //- Assignment operator. Takes linear time.
labelList operator()() const; void operator=(const PackedList<nBits>&);
//- Assignment operator. Takes linear time.
void operator=(const UList<label>&);
// Ostream operator // Ostream operator
// // Write PackedList to Ostream. // // Write PackedList to Ostream.
// friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&); // friend Ostream& operator<< <nBits> (Ostream&, const PackedList<nBits>&);
}; };
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -33,21 +33,21 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<int nBits> template<int nBits>
inline unsigned int Foam::PackedList<nBits>::max_bits() inline unsigned int Foam::PackedBitRef<nBits>::max_bits()
{ {
return sizeof(unsigned int)*8 - 1; return sizeof(unsigned int)*8 - 1;
} }
template<int nBits> template<int nBits>
inline unsigned int Foam::PackedList<nBits>::max_value() inline unsigned int Foam::PackedBitRef<nBits>::max_value()
{ {
return ((1u << nBits) - 1); return ((1u << nBits) - 1);
} }
template<int nBits> template<int nBits>
inline unsigned int Foam::PackedList<nBits>::packing() inline unsigned int Foam::PackedBitRef<nBits>::packing()
{ {
return sizeof(unsigned int)*8 / nBits; return sizeof(unsigned int)*8 / nBits;
} }
@ -114,7 +114,7 @@ inline void Foam::PackedList<nBits>::checkIndex(const label i) const
template<int nBits> template<int nBits>
inline Foam::PackedList<nBits>::PackedList() inline Foam::PackedList<nBits>::PackedList()
: :
List<unsigned int>(0), List<unsigned int>(),
size_(0) size_(0)
{} {}
@ -128,33 +128,31 @@ inline Foam::PackedList<nBits>::PackedList(const label size)
{} {}
template<int nBits>
inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
:
List<unsigned int>(lst),
size_(lst.size())
{}
template<int nBits>
inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
{
transfer(lst());
}
template<int nBits>
inline Foam::autoPtr<Foam::PackedList<nBits> > Foam::PackedList<nBits>::clone() const
{
return autoPtr<PackedList<nBits> >(new PackedList<nBits>(*this));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<int nBits>
inline void Foam::PackedList<nBits>::resize(const label newSize)
{
setSize(newSize);
}
template<int nBits>
inline void Foam::PackedList<nBits>::resize
(
const label newSize,
const unsigned int& val
)
{
setSize(newSize, val);
}
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::capacity() const
{
return packing() * List<unsigned int>::size();
}
template<int nBits> template<int nBits>
inline Foam::label Foam::PackedList<nBits>::size() const inline Foam::label Foam::PackedList<nBits>::size() const
{ {
@ -169,6 +167,102 @@ inline bool Foam::PackedList<nBits>::empty() const
} }
template<int nBits>
inline void Foam::PackedList<nBits>::resize
(
const label newSize,
const unsigned int& val
)
{
reserve(newSize, val);
size_ = newSize;
}
template<int nBits>
inline void Foam::PackedList<nBits>::setSize
(
const label newSize,
const unsigned int& val
)
{
resize(newSize, val);
}
template<int nBits>
inline Foam::label Foam::PackedList<nBits>::capacity() const
{
return packing() * List<unsigned int>::size();
}
template<int nBits>
inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
{
List<unsigned int>::setSize(storageSize(nElem), 0);
for (label i = size_; i < nElem; i++)
{
set(i, 0);
}
size_ = nElem;
}
template<int nBits>
inline void Foam::PackedList<nBits>::reserve
(
const label nElem,
const unsigned int& val
)
{
label rawSize = storageSize(nElem);
// need more capacity?
if (rawSize > List<unsigned int>::size())
{
List<unsigned int>::setSize(rawSize, 0);
}
// fill new elements, don't rely on List::setSize
for (label i = size_; i < nElem; i++)
{
set(i, val);
}
}
template<int nBits>
inline void Foam::PackedList<nBits>::clear()
{
size_ = 0;
}
template<int nBits>
inline void Foam::PackedList<nBits>::clearStorage()
{
List<unsigned int>::clear();
size_ = 0;
}
template<int nBits>
inline void Foam::PackedList<nBits>::shrink()
{
label rawSize = storageSize(size_);
// we have unused space?
if (rawSize < List<unsigned int>::size())
{
List<unsigned int>::setSize(rawSize);
}
}
// Get value at i // Get value at i
template<int nBits> template<int nBits>
inline unsigned int Foam::PackedList<nBits>::get(const label i) const inline unsigned int Foam::PackedList<nBits>::get(const label i) const
@ -183,6 +277,10 @@ inline unsigned int Foam::PackedList<nBits>::get(const label i) const
location(i, startBit) location(i, startBit)
); );
// PackedBitRef<nBits> iter(*this, elem, startBit);
// return PackedBitRef<nBits>(*this, elem, startBit)();
return (elem >> startBit) & max_value(); return (elem >> startBit) & max_value();
} }
@ -221,9 +319,13 @@ inline bool Foam::PackedList<nBits>::set(const label i, const unsigned int val)
template<int nBits> template<int nBits>
inline Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() inline bool Foam::PackedList<nBits>::append(const unsigned int val)
{ {
return static_cast<List<unsigned int>&>(*this); label elemI = size_;
reserve(elemI + 1);
size_++;
return set(elemI, val);
} }
@ -234,6 +336,17 @@ inline const Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() const
} }
template<int nBits>
inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
{
size_ = lst.size_;
lst.size_ = 0;
List<unsigned int>::transfer(lst);
}
template<int nBits> template<int nBits>
inline Foam::Xfer<Foam::PackedList<nBits> > inline Foam::Xfer<Foam::PackedList<nBits> >
Foam::PackedList<nBits>::xfer() Foam::PackedList<nBits>::xfer()
@ -244,12 +357,13 @@ Foam::PackedList<nBits>::xfer()
template<int nBits> template<int nBits>
inline Foam::PackedBitRef inline typename Foam::PackedBitRef<nBits>
Foam::PackedList<nBits>::operator[](const label i) Foam::PackedList<nBits>::operator[](const label i)
{ {
# ifdef DEBUGList if (i >= size_)
checkIndex(i); {
# endif setSize(i + 1);
}
label startBit; label startBit;
unsigned int& elem = List<unsigned int>::operator[] unsigned int& elem = List<unsigned int>::operator[]
@ -257,7 +371,12 @@ Foam::PackedList<nBits>::operator[](const label i)
location(i, startBit) location(i, startBit)
); );
return ::Foam::PackedBitRef(elem, startBit, max_value()); return ::Foam::PackedBitRef<nBits>
(
// *this,
elem,
startBit
);
} }
@ -269,17 +388,17 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
checkValue(val); checkValue(val);
# endif # endif
if (val == 0) if (val)
{ {
List<unsigned int>::operator=(val); forAll(*this, i)
}
else
{
for (label i = 0; i < size_; i++)
{ {
set(i, val); set(i, val);
} }
} }
else
{
List<unsigned int>::operator=(val);
}
} }