DynamicList re-visited:

- shrink() should now correctly actually shrink
 - List::transfer(DynamicList&) invokes shrink() before transferring
   contents: otherwise the ununsed allocated space is never recovered
   until much, much later.
 - DynamicList::transfer(List&) no longer throws a FatalError when
   transferring in a smaller list. The original list contents are getting
   tossed away anyhow!
This commit is contained in:
Mark Olesen
2008-10-20 16:30:48 +02:00
parent bb5bc16457
commit b22ada09b7
4 changed files with 43 additions and 54 deletions

View File

@ -115,39 +115,36 @@ public:
// Access // Access
//- Size of the underlying storage. //- Size of the underlying storage.
inline label allocSize() const; inline label allocSize() const;
// Edit // Edit
//- Alter the list size. //- Alter the list size.
// When the new size is greater than the addressed list size, the // When the new size is greater than the addressed list size, the
// allocated list sizes is adjusted and the // allocated list sizes is adjusted and the
// addressed size does not change. // addressed size does not change.
// Otherwise the addressed list size is just reduced and the // Otherwise the addressed list size is just reduced and the
// allocated size does not change. // allocated size does not change.
inline void setSize(const label); inline void setSize(const label);
//- Clear the list, i.e. set the size to zero. //- Clear the list, i.e. set the size to zero.
// Allocated size does not change // Allocated size does not change
inline void clear(); inline void clear();
//- Clear the list and delete storage. //- Clear the list and delete storage.
inline void clearStorage(); inline void clearStorage();
//- Shrink the List<T> to the number of elements used //- Shrink the allocated space to the number of elements used.
inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& shrink(); // Returns a reference to the DynamicList.
inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& shrink();
//- Transfer the contents of the argument List into this List //- Transfer contents of the argument List into this DynamicList
// and annull the argument list. Is same as List::transfer except inline void transfer(List<T>&);
// checks that you're not changing the underlying list to something
// smaller than allocSize_.
inline void transfer(List<T>&);
//- Transfer the contents of the argument DynamicList into this //- Transfer contents of the argument DynamicList into this DynamicList
// DynamicList and annull the argument list. inline void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
inline void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
// Member Operators // Member Operators
@ -158,8 +155,7 @@ public:
//- Remove and return the top element //- Remove and return the top element
inline T remove(); inline T remove();
//- Return non-const access to an element, //- Return non-const access to an element, resizing list if necessary
// resizing the list if necessary
inline T& operator()(const label); inline T& operator()(const label);
//- Assignment of all addressed entries to the given value //- Assignment of all addressed entries to the given value

View File

@ -26,7 +26,6 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct null
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList() inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
: :
@ -37,7 +36,6 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
} }
//- Construct given size
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
( (
@ -51,15 +49,14 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
} }
//- Construct given size
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
( (
const UList<T>& s const UList<T>& lst
) )
: :
List<T>(s), List<T>(lst),
allocSize_(s.size()) allocSize_(lst.size())
{} {}
@ -114,31 +111,24 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink() Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink()
{ {
allocSize_ = List<T>::size(); if (allocSize_ > List<T>::size())
List<T>::setSize(allocSize_); {
allocSize_ = List<T>::size();
// force re-allocation/copying in List<T>::setSize() by temporarily
// faking a larger list size that will be truncated
List<T>::size(allocSize_+1);
List<T>::setSize(allocSize_);
}
return *this; return *this;
} }
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void inline void
Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& l) Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst)
{ {
if (l.size() < List<T>::size()) allocSize_ = lst.size();
{ List<T>::transfer(lst); // take over storage, null lst
FatalErrorIn
(
"void DynamicList<T, SizeInc, SizeMult"
", SizeDiv>::transfer(List<T>&)"
) << "Cannot replace the underlying storage of this DynamicList"
<< " of which " << List<T>::size() << " elements are used" << nl
<< "with a List of size " << l.size() << abort(FatalError);
}
else
{
allocSize_ = l.size();
List<T>::transfer(l); // take over storage
}
} }
@ -146,11 +136,11 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
inline void inline void
Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer
( (
DynamicList<T, SizeInc, SizeMult, SizeDiv>& l DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
) )
{ {
allocSize_ = l.allocSize(); allocSize_ = lst.allocSize();
List<T>::transfer(l); // take over storage. Null l. List<T>::transfer(lst); // take over storage, null lst.
} }

View File

@ -430,6 +430,9 @@ template<class T>
template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv> template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
void Foam::List<T>::transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a) void Foam::List<T>::transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a)
{ {
// shrink the allocated space to the number of elements used
a.shrink();
if (this->v_) delete[] this->v_; if (this->v_) delete[] this->v_;
this->size_ = a.size_; this->size_ = a.size_;
this->v_ = a.v_; this->v_ = a.v_;

View File

@ -45,7 +45,7 @@ void Foam::UList<T>::assign(const UList<T>& a)
{ {
if (a.size_ != this->size_) if (a.size_ != this->size_)
{ {
FatalErrorIn("UList<T>::operator=(const UList<T>&)") FatalErrorIn("UList<T>::assign(const UList<T>&)")
<< "ULists have different sizes: " << "ULists have different sizes: "
<< this->size_ << " " << a.size_ << this->size_ << " " << a.size_
<< abort(FatalError); << abort(FatalError);