Commit 3cbf3994 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

BUG: failed swap/transfer for DynamicList with different sizing parameters

- now use public functions instead of direct access of private 'capacity_'
  information
parent 2269294d
......@@ -46,6 +46,14 @@ void printInfo
if (showSize)
{
Info<< " size=\"" << lst.size() << "\"";
if (lst.cdata())
{
Info<< " ptr=\"" << long(lst.cdata()) << "\"";
}
else
{
Info<< " ptr=\"nullptr\"";
}
}
Info<< ">" << nl << flatOutput(lst) << nl << "</" << tag << ">" << endl;
}
......@@ -64,6 +72,14 @@ void printInfo
{
Info<< " size=\"" << lst.size()
<< "\" capacity=\"" << lst.capacity() << "\"";
if (lst.cdata())
{
Info<< " ptr=\"" << long(lst.cdata()) << "\"";
}
else
{
Info<< " ptr=\"nullptr\"";
}
}
Info<< ">" << nl << flatOutput(lst) << nl << "</" << tag << ">" << endl;
}
......@@ -284,6 +300,19 @@ int main(int argc, char *argv[])
<< flatOutput(input1) << " / "
<< flatOutput(input2) << nl;
Info<< "test move dissimilar sizing:" << nl;
list1 = list2;
list1.reserve(100);
// DynamicList<label,1000> list3; // (std::move(list1));
DynamicList<label,1000> list3(std::move(list1));
Info<< "orig: " << flatOutput(list1) << nl;
// list3.swap(list1);
// list3 = std::move(list1);
printInfo("input", list1, true);
printInfo("output", list3, true);
input1 = list2;
......
......@@ -158,6 +158,10 @@ public:
//- Move construct.
inline DynamicList(DynamicList<T, SizeMin>&& lst);
//- Move construct with different sizing parameters
template<int AnySizeMin>
inline DynamicList(DynamicList<T, AnySizeMin>&& lst);
//- Move construct from List
inline DynamicList(List<T>&& lst);
......@@ -212,6 +216,10 @@ public:
//- Clear the list and delete storage.
inline void clearStorage();
//- Expand the addressable size to fit the allocated capacity.
// Returns the previous addressable size.
inline label expandStorage();
//- Shrink the allocated space to the number of elements used.
// Returns a reference to the DynamicList.
inline DynamicList<T, SizeMin>& shrink();
......
......@@ -206,6 +206,19 @@ inline Foam::DynamicList<T, SizeMin>::DynamicList
}
template<class T, int SizeMin>
template<int AnySizeMin>
inline Foam::DynamicList<T, SizeMin>::DynamicList
(
DynamicList<T, AnySizeMin>&& lst
)
:
capacity_(0)
{
transfer(lst);
}
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>::DynamicList
(
......@@ -360,6 +373,18 @@ inline void Foam::DynamicList<T, SizeMin>::clearStorage()
}
template<class T, int SizeMin>
inline Foam::label Foam::DynamicList<T, SizeMin>::expandStorage()
{
const label nextFree = List<T>::size();
// Allow addressing into the entire list
List<T>::size(capacity_);
return nextFree;
}
template<class T, int SizeMin>
inline Foam::DynamicList<T, SizeMin>&
Foam::DynamicList<T, SizeMin>::shrink()
......@@ -386,8 +411,26 @@ inline void Foam::DynamicList<T, SizeMin>::swap
DynamicList<T, AnySizeMin>& lst
)
{
Foam::Swap(static_cast<UList<T>&>(*this), static_cast<UList<T>&>(lst));
Foam::Swap(capacity_, lst.capacity_);
DynamicList<T, SizeMin>& cur = *this;
// Make addressable size identical to the allocated capacity
const label oldSize1 = cur.expandStorage();
const label oldSize2 = lst.expandStorage();
// Swap storage
Foam::Swap
(
static_cast<UList<T>&>(cur),
static_cast<UList<T>&>(lst)
);
// Match capacity to the underlying allocated list size
cur.setCapacity(cur.size());
lst.setCapacity(lst.size());
// Set addressable size
cur.setSize(oldSize2);
lst.setSize(oldSize1);
}
......@@ -409,10 +452,12 @@ Foam::DynamicList<T, SizeMin>::transfer
DynamicList<T, AnySizeMin>& lst
)
{
// Take over storage as-is (without shrink), clear addressing for lst.
capacity_ = lst.capacity_;
lst.capacity_ = 0;
// Take over storage as-is (without shrink, without using SizeMin)
// clear addressing and storage for old lst.
capacity_ = lst.capacity();
List<T>::transfer(static_cast<List<T>&>(lst));
lst.clearStorage(); // Ensure capacity=0
}
......@@ -565,7 +610,7 @@ Foam::DynamicList<T, SizeMin>::append
)
{
append(std::move(static_cast<List<T>&>(lst)));
lst.clearStorage(); // Ensure capacity=0 too
lst.clearStorage(); // Ensure capacity=0
return *this;
}
......@@ -579,7 +624,7 @@ Foam::DynamicList<T, SizeMin>::append
)
{
append(std::move(static_cast<List<T>&>(lst)));
lst.clearStorage(); // Ensure capacity=0 too
lst.clearStorage(); // Ensure capacity=0
return *this;
}
......
......@@ -103,17 +103,17 @@ public:
inline DynamicField();
//- Construct given size.
explicit inline DynamicField(const label);
explicit inline DynamicField(const label nElem);
//- Construct from UList. Size set to UList size.
// Also constructs from DynamicField with different sizing parameters.
explicit inline DynamicField(const UList<T>&);
explicit inline DynamicField(const UList<T>& lst);
//- Construct by transferring the parameter contents
explicit inline DynamicField(const Xfer<List<T>>&);
explicit inline DynamicField(const Xfer<List<T>>& lst);
//- Construct by transferring the parameter contents
explicit inline DynamicField(const Xfer<Field<T>>&);
explicit inline DynamicField(const Xfer<Field<T>>& lst);
//- Construct by 1 to 1 mapping from the given field
inline DynamicField
......@@ -138,16 +138,16 @@ public:
);
//- Construct copy
inline DynamicField(const DynamicField<T, SizeMin>&);
inline DynamicField(const DynamicField<T, SizeMin>& lst);
//- Construct by transferring the Field contents
inline DynamicField
(
const Xfer<DynamicField<T, SizeMin>>&
const Xfer<DynamicField<T, SizeMin>>& lst
);
//- Construct from Istream. Size set to size of list read.
explicit DynamicField(Istream&);
explicit DynamicField(Istream& is);
//- Clone
tmp<DynamicField<T, SizeMin>> clone() const;
......@@ -166,31 +166,31 @@ public:
// 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);
inline void setCapacity(const label nElem);
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
inline void setSize(const label);
inline void setSize(const label nElem);
//- Alter the addressed list size and fill new space with a
// constant.
inline void setSize(const label, const T&);
inline void setSize(const label nElem, const T& val);
//- Alter the addressed list size.
// New space will be allocated if required.
// Use this to resize the list prior to using the operator[] for
// setting values (as per List usage).
inline void resize(const label);
inline void resize(const label nElem);
//- Alter the addressed list size and fill new space with a
// constant.
inline void resize(const label, const T& val);
inline void resize(const label nElem, const T& val);
//- Reserve allocation space for at least this size.
// Never shrinks the allocated size, use setCapacity() for that.
inline void reserve(const label);
inline void reserve(const label nElem);
//- Clear the addressed list, i.e. set the size to zero.
// Allocated size does not change
......@@ -222,19 +222,19 @@ public:
//- Return non-const access to an element, resizing list if
// necessary
inline T& operator()(const label);
inline T& operator()(const label elemI);
//- Assignment of all addressed entries to the given value
inline void operator=(const T&);
inline void operator=(const T& val);
//- Assignment to DynamicField
inline void operator=
(
const DynamicField<T, SizeMin>&
const DynamicField<T, SizeMin>& lst
);
//- Assignment to UList
inline void operator=(const UList<T>&);
inline void operator=(const UList<T>& lst);
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment