mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
BUG: failed swap/transfer for DynamicList with different sizing parameters
- now use public functions instead of direct access of private 'capacity_' information
This commit is contained in:
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user