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<< ")\n\n";
cout<< ")\n";
// using std:bitset for output works, but annoys valgrind
cout<< "storage: " << stor.size() << "( ";
forAll(stor, i)
{
@ -99,6 +100,41 @@ int main(int argc, char *argv[])
list1.resize(8);
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;
}

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>
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 * * * * * * * * * * * * * //
template<int nBits>
void Foam::PackedList<nBits>::setSize(const label newSize)
{
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
Foam::labelList Foam::PackedList<nBits>::values() const
{
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 * * * * * * * * * * * * * //
//template<int nBits>

View File

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

View File

@ -33,21 +33,21 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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;
}
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::max_value()
inline unsigned int Foam::PackedBitRef<nBits>::max_value()
{
return ((1u << nBits) - 1);
}
template<int nBits>
inline unsigned int Foam::PackedList<nBits>::packing()
inline unsigned int Foam::PackedBitRef<nBits>::packing()
{
return sizeof(unsigned int)*8 / nBits;
}
@ -114,7 +114,7 @@ inline void Foam::PackedList<nBits>::checkIndex(const label i) const
template<int nBits>
inline Foam::PackedList<nBits>::PackedList()
:
List<unsigned int>(0),
List<unsigned int>(),
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 * * * * * * * * * * * * * //
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>
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
template<int nBits>
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)
);
// PackedBitRef<nBits> iter(*this, elem, startBit);
// return PackedBitRef<nBits>(*this, elem, startBit)();
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>
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>
inline Foam::Xfer<Foam::PackedList<nBits> >
Foam::PackedList<nBits>::xfer()
@ -244,12 +357,13 @@ Foam::PackedList<nBits>::xfer()
template<int nBits>
inline Foam::PackedBitRef
inline typename Foam::PackedBitRef<nBits>
Foam::PackedList<nBits>::operator[](const label i)
{
# ifdef DEBUGList
checkIndex(i);
# endif
if (i >= size_)
{
setSize(i + 1);
}
label startBit;
unsigned int& elem = List<unsigned int>::operator[]
@ -257,7 +371,12 @@ Foam::PackedList<nBits>::operator[](const label i)
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);
# endif
if (val == 0)
if (val)
{
List<unsigned int>::operator=(val);
}
else
{
for (label i = 0; i < size_; i++)
forAll(*this, i)
{
set(i, val);
}
}
else
{
List<unsigned int>::operator=(val);
}
}