ENH: disallow implicit cast of autoPtr to non-const pointer

- permitting a cast to a non-const pointer adds uncertainty of
  ownership.

- adjust PtrDynList transfer. Remove the unused 'PtrDynList::remove()'
  method, which is better handled with pop().
This commit is contained in:
Mark Olesen 2023-05-11 14:14:35 +02:00
parent 521043094e
commit a581a8cb8d
6 changed files with 49 additions and 69 deletions

View File

@ -325,6 +325,22 @@ int main(int argc, char *argv[])
{
list1.set(i, new Scalar(1.3*i));
}
{
auto ptr = autoPtr<Scalar>::New(10);
Info<< "add: " << Foam::name(ptr.get());
list1.set(0, ptr);
Info<< "ptrlist: " << Foam::name(list1.get(0)) << nl;
Info<< "now: " << Foam::name(ptr.get()) << nl;
ptr = autoPtr<Scalar>::New(20);
list1.append(ptr);
// Delete method: list1.push_back(ptr);
// list1.push_back(std::move(ptr));
}
PtrList<Scalar> list2(15);
Info<< "Emplace set " << list2.size() << " values" << nl;

View File

@ -172,9 +172,6 @@ public:
//- Reduce size by 1 or more elements. Can be called on an empty list.
inline void pop_back(label n = 1);
//- Remove and return the top element. Can be called on an empty list.
inline autoPtr<T> remove();
//- Construct and set a new element at given position,
//- (discard old element at that location).
//- Return reference to the new list element.
@ -230,10 +227,14 @@ public:
// Housekeeping
//- Disallow push_back with autoPtr without std::move
void push_back(autoPtr<T>& ptr) = delete;
//- Set element to given autoPtr and return old element
//FOAM_DEPRECATED_FOR(2022-10, "set(autoPtr&&))")
autoPtr<T> set(const label i, autoPtr<T>& ptr)
{
return this->set(i, std::move(ptr));
return this->set(i, ptr.release());
}
//- Same as resize()

View File

@ -217,19 +217,20 @@ inline void Foam::PtrDynList<T, SizeMin>::swap
template<class T, int SizeMin>
inline void Foam::PtrDynList<T, SizeMin>::transfer(PtrList<T>& other)
inline void Foam::PtrDynList<T, SizeMin>::transfer(PtrList<T>& list)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self assignment is a no-op
}
UPtrList<T>::swap(other);
other.clear();
// Take over storage, clear addressing for list
capacity_ = list.size();
PtrList<T>::transfer(list);
}
@ -237,20 +238,22 @@ template<class T, int SizeMin>
template<int AnySizeMin>
inline void Foam::PtrDynList<T, SizeMin>::transfer
(
PtrDynList<T, AnySizeMin>& other
PtrDynList<T, AnySizeMin>& list
)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&other)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self assignment is a no-op
}
this->swap(other);
other.clear();
// Take over storage as-is (without shrink, without using SizeMin)
capacity_ = list.capacity();
PtrList<T>::transfer(list);
list.clearStorage(); // Ensure capacity=0
}
@ -364,25 +367,6 @@ inline void Foam::PtrDynList<T, SizeMin>::pop_back(label n)
}
template<class T, int SizeMin>
inline Foam::autoPtr<T> Foam::PtrDynList<T, SizeMin>::remove()
{
// Location of last element and simultaneously the new size
const label idx = (this->size() - 1);
if (idx < 0)
{
return nullptr; // List is empty
}
autoPtr<T> old(this->ptrs_[idx]);
this->ptrs_[idx] = nullptr;
PtrList<T>::setAddressableSize(idx);
return old;
}
template<class T, int SizeMin>
template<class... Args>
inline T& Foam::PtrDynList<T, SizeMin>::emplace
@ -528,14 +512,7 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
PtrList<T>&& list
)
{
if (this == &list)
{
return; // Self-assignment is a no-op
}
PtrList<T>::transfer(list);
capacity_ = PtrList<T>::size();
list.clearStorage();
this->transfer(list);
}
@ -545,14 +522,7 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
PtrDynList<T, SizeMin>&& list
)
{
if (this == &list)
{
return; // Self-assignment is a no-op
}
PtrList<T>::transfer(list);
capacity_ = list.capacity();
list.clearStorage();
this->transfer(list);
}
@ -563,18 +533,7 @@ inline void Foam::PtrDynList<T, SizeMin>::operator=
PtrDynList<T, AnySizeMin>&& list
)
{
if
(
static_cast<const PtrList<T>*>(this)
== static_cast<const PtrList<T>*>(&list)
)
{
return; // Self-assignment is a no-op
}
PtrList<T>::transfer(list);
capacity_ = list.capacity();
list.clearStorage();
this->transfer(list);
}

View File

@ -223,17 +223,22 @@ public:
// Housekeeping
//- Disallow push_back with autoPtr without std::move
void push_back(autoPtr<T>& ptr) = delete;
//- Set element to given autoPtr and return old element
//FOAM_DEPRECATED_FOR(2022-10, "set(autoPtr&&))")
autoPtr<T> set(const label i, autoPtr<T>& ptr)
{
return this->set(i, std::move(ptr));
return this->set(i, ptr.release());
}
//- Same as resize()
void setSize(const label newLen) { this->resize(newLen); }
//- Move append an element to the end of the list
void append(autoPtr<T>& ptr) { this->push_back(std::move(ptr)); }
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")
void append(autoPtr<T>& ptr) { this->push_back(ptr.release()); }
//- Append an element to the end of the list
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")
@ -243,12 +248,12 @@ public:
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")
void append(std::unique_ptr<T>&& ptr)
{
this->push_back(std::move(ptr));
this->push_back(ptr.release());
}
//- Move append an element to the end of the list
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")
void append(autoPtr<T>&& ptr) { this->push_back(std::move(ptr)); }
void append(autoPtr<T>&& ptr) { this->push_back(ptr.release()); }
//- Move or clone append a tmp to the end of the list
//FOAM_DEPRECATED_FOR(2022-10, "push_back()")

View File

@ -1185,7 +1185,7 @@ bool Foam::functionObjectList::read()
// Insert active functionObject into the list
if (objPtr)
{
newPtrs.set(nFunc, objPtr);
newPtrs.set(nFunc, std::move(objPtr));
newIndices.insert(key, nFunc);
++nFunc;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd.
Copyright (C) 2016-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -261,12 +261,11 @@ public:
//- True if pointer/reference is non-null. Same as good()
explicit operator bool() const noexcept { return bool(ptr_); }
//- Cast to pointer type
//- Implicit cast to \em const pointer type.
// \note no cast to non-const pointer,
// since this would add uncertainty of ownership.
operator const T*() const noexcept { return ptr_; }
//- Cast to pointer type
operator T*() noexcept { return ptr_; }
//- Deprecated(2019-01) Automatic cast conversion to underlying type
// FatalError if no pointer is managed
// \deprecated(2019-01) Can result in inadvertent conversions