Commit 23ea498c authored by Mark Olesen's avatar Mark Olesen
Browse files

BUG: inconsistent check in non-const '->' dereference (tmp, refPtr)

- old code just checked for pointer vs non-pointer.
  Should actually treat CREF and REF types differently
  Overseen in commit be058bec. Only affects develop branch

ENH: improved naming consistency in tmp, refPtr

- also use long-form to check for pointer type instead of the isTmp()
  method. Makes differences between PTR, CREF, REF easier to spot.

STYLE: typeName() for tmp, refPtr is static
parent e56e195a
......@@ -123,13 +123,13 @@ public:
inline refPtr(const T& obj) noexcept;
//- Move construct, transferring ownership.
inline refPtr(refPtr<T>&& t) noexcept;
inline refPtr(refPtr<T>&& rhs) noexcept;
//- Copy construct
inline refPtr(const refPtr<T>& t);
inline refPtr(const refPtr<T>& rhs);
//- Copy construct. Optionally reusing pointer.
inline refPtr(const refPtr<T>& t, bool reuse);
//- Copy/move construct. Optionally reusing pointer.
inline refPtr(const refPtr<T>& rhs, bool reuse);
//- Destructor: deletes managed pointer
......@@ -138,6 +138,10 @@ public:
// Member Functions
//- The type-name, constructed from type-name of T
inline static word typeName();
// Query
//- Deprecated(2020-07) True if a null managed pointer
......@@ -152,15 +156,12 @@ public:
//- True if this is a managed pointer (not a reference)
bool is_pointer() const noexcept { return type_ == PTR; }
//- True if this is a managed pointer (not a reference)
//- Identical to is_pointer()
bool isTmp() const noexcept { return type_ == PTR; }
//- True if this is a non-null managed pointer
inline bool movable() const noexcept;
//- Return type-name of the tmp, constructed from type-name of T
inline word typeName() const;
// Access
......@@ -180,9 +181,8 @@ public:
// Fatal for a null managed pointer or if the object is const.
inline T& ref() const;
//- Non-const dereference, even if the object is const.
// This is similar to ref(), but applies a const_cast to access
// const objects.
//- Return non-const reference to the object or to the contents
//- of a (non-null) managed pointer, with an additional const_cast.
// Fatal for a null managed pointer.
inline T& constCast() const;
......@@ -245,14 +245,14 @@ public:
//- Reset via assignment from literal nullptr
inline void operator=(std::nullptr_t) noexcept;
//- Conversion to tmp - releases pointer or copies reference
//- Conversion to tmp, releases pointer or shallow-copies reference
inline operator tmp<T>();
};
// Global Functions
//- Specializes the Swap algorithm for refPtr.
//- Specialized Swap algorithm for refPtr.
// Swaps the pointers and types of lhs and rhs. Calls \c lhs.swap(rhs)
template<class T>
void Swap(refPtr<T>& lhs, refPtr<T>& rhs)
......
......@@ -47,6 +47,13 @@ inline Foam::refPtr<T> Foam::refPtr<T>::NewFrom(Args&&... args)
}
template<class T>
inline Foam::word Foam::refPtr<T>::typeName()
{
return "refPtr<" + word(typeid(T).name()) + '>';
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
......@@ -82,32 +89,33 @@ inline Foam::refPtr<T>::refPtr(const T& obj) noexcept
template<class T>
inline Foam::refPtr<T>::refPtr(refPtr<T>&& t) noexcept
inline Foam::refPtr<T>::refPtr(refPtr<T>&& rhs) noexcept
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
t.ptr_ = nullptr;
t.type_ = PTR;
rhs.ptr_ = nullptr;
rhs.type_ = PTR;
}
template<class T>
inline Foam::refPtr<T>::refPtr(const refPtr<T>& t)
inline Foam::refPtr<T>::refPtr(const refPtr<T>& rhs)
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
if (isTmp())
if (type_ == PTR)
{
if (ptr_)
{
t.type_ = CREF;
rhs.type_ = REF; // (shallow copy)
}
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< "Attempted copy of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
}
......@@ -115,28 +123,30 @@ inline Foam::refPtr<T>::refPtr(const refPtr<T>& t)
template<class T>
inline Foam::refPtr<T>::refPtr(const refPtr<T>& t, bool reuse)
inline Foam::refPtr<T>::refPtr(const refPtr<T>& rhs, bool reuse)
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
if (isTmp())
if (type_ == PTR)
{
if (ptr_)
{
if (reuse)
{
t.ptr_ = nullptr; // t.type_ already set as PTR
rhs.ptr_ = nullptr;
// Note: rhs.type_ already set as PTR
}
else
{
t.type_ = CREF;
rhs.type_ = REF; // (shallow copy)
}
}
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< "Attempted copy of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
}
......@@ -159,22 +169,15 @@ inline bool Foam::refPtr<T>::movable() const noexcept
}
template<class T>
inline Foam::word Foam::refPtr<T>::typeName() const
{
return "refPtr<" + word(typeid(T).name()) + '>';
}
template<class T>
inline const T& Foam::refPtr<T>::cref() const
{
if (isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
......@@ -186,12 +189,12 @@ inline const T& Foam::refPtr<T>::cref() const
template<class T>
inline T& Foam::refPtr<T>::ref() const
{
if (isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
......@@ -199,7 +202,7 @@ inline T& Foam::refPtr<T>::ref() const
{
FatalErrorInFunction
<< "Attempted non-const reference to const object from a "
<< typeName()
<< this->typeName()
<< abort(FatalError);
}
......@@ -220,12 +223,13 @@ inline T* Foam::refPtr<T>::ptr() const
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
if (isTmp())
if (type_ == PTR)
{
// Release pointer
T* p = ptr_;
ptr_ = nullptr;
......@@ -239,7 +243,7 @@ inline T* Foam::refPtr<T>::ptr() const
template<class T>
inline void Foam::refPtr<T>::clear() const noexcept
{
if (isTmp() && ptr_)
if (type_ == PTR && ptr_)
{
delete ptr_;
ptr_ = nullptr;
......@@ -299,7 +303,7 @@ inline void Foam::refPtr<T>::swap(refPtr<T>& other) noexcept
return; // Self-swap is a no-op
}
// Copy/assign for pointer types
// Swap is just copy/assign for pointer and enum types
T* p = ptr_;
ptr_ = other.ptr_;
other.ptr_ = p;
......@@ -329,12 +333,15 @@ inline Foam::refPtr<T>::operator const T&() const
template<class T>
inline const T* Foam::refPtr<T>::operator->() const
{
if (!ptr_ && isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
return ptr_;
}
......@@ -343,19 +350,20 @@ inline const T* Foam::refPtr<T>::operator->() const
template<class T>
inline T* Foam::refPtr<T>::operator->()
{
if (isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
else
else if (type_ == CREF)
{
FatalErrorInFunction
<< "Attempt to cast const object to non-const for a " << typeName()
<< "Attempt to cast const object to non-const for a "
<< this->typeName()
<< abort(FatalError);
}
......@@ -364,33 +372,34 @@ inline T* Foam::refPtr<T>::operator->()
template<class T>
inline void Foam::refPtr<T>::operator=(const refPtr<T>& t)
inline void Foam::refPtr<T>::operator=(const refPtr<T>& other)
{
if (&t == this)
if (&other == this)
{
return; // Self-assignment is a no-op
}
clear();
if (t.isTmp())
if (other.type_ == PTR)
{
ptr_ = t.ptr_;
ptr_ = other.ptr_;
type_ = PTR;
t.ptr_ = nullptr;
other.ptr_ = nullptr;
if (!ptr_)
{
FatalErrorInFunction
<< "Attempted assignment to a deallocated " << typeName()
<< "Attempted assignment of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
}
else
{
FatalErrorInFunction
<< "Attempted assignment to a const reference to an object"
<< " of type " << typeid(T).name()
<< "Attempted assignment of an object reference of type "
<< typeid(T).name()
<< abort(FatalError);
}
}
......@@ -419,7 +428,8 @@ inline void Foam::refPtr<T>::operator=(T* p)
if (!p)
{
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< "Attempted copy of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
......@@ -437,7 +447,7 @@ inline void Foam::refPtr<T>::operator=(std::nullptr_t) noexcept
template<class T>
inline Foam::refPtr<T>::operator tmp<T>()
{
if (isTmp())
if (type_ == PTR)
{
return tmp<T>(ptr());
}
......
......@@ -139,19 +139,19 @@ public:
//- Move construct, transferring ownership.
// Does not affect ref-count
inline tmp(tmp<T>&& t) noexcept;
inline tmp(tmp<T>&& rhs) noexcept;
//- Move construct, transferring ownership.
// Does not affect ref-count
// \note Non-standard definition - should be non-const
inline tmp(const tmp<T>&& t) noexcept;
inline tmp(const tmp<T>&& rhs) noexcept;
//- Copy construct, incrementing ref-count of managed pointer.
// \note Non-standard definition - should be non-const
inline tmp(const tmp<T>& t);
inline tmp(const tmp<T>& rhs);
//- Copy construct. Optionally reusing ref-counted pointer.
inline tmp(const tmp<T>& t, bool reuse);
//- Copy/move construct. Optionally reusing ref-counted pointer.
inline tmp(const tmp<T>& rhs, bool reuse);
//- Destructor: deletes managed pointer when the ref-count is 0
......@@ -160,6 +160,10 @@ public:
// Member Functions
//- The type-name, constructed from type-name of T
inline static word typeName();
// Query
//- Deprecated(2020-07) True if a null managed pointer
......@@ -174,15 +178,12 @@ public:
//- True if this is a managed pointer (not a reference)
bool is_pointer() const noexcept { return type_ == PTR; }
//- True if this is a managed pointer (not a reference)
//- Identical to is_pointer()
bool isTmp() const noexcept { return type_ == PTR; }
//- True if this is a non-null managed pointer with a unique ref-count
inline bool movable() const noexcept;
//- Return type-name of the tmp, constructed from type-name of T
inline word typeName() const;
// Access
......@@ -202,9 +203,8 @@ public:
// Fatal for a null managed pointer or if the object is const.
inline T& ref() const;
//- Non-const dereference, even if the object is const.
// This is similar to ref(), but applies a const_cast to access
// const objects.
//- Return non-const reference to the object or to the contents
//- of a (non-null) managed pointer, with an additional const_cast.
// Fatal for a null pointer.
inline T& constCast() const;
......@@ -255,7 +255,7 @@ public:
//- Transfer ownership of the managed pointer.
// Fatal for a null managed pointer or if the object is const.
inline void operator=(const tmp<T>& t);
inline void operator=(const tmp<T>& other);
//- Clear existing and transfer ownership.
inline void operator=(tmp<T>&& other) noexcept;
......@@ -271,7 +271,7 @@ public:
// Global Functions
//- Specializes the Swap algorithm for tmp.
//- Specialized Swap algorithm for tmp.
// Swaps the pointers and types of lhs and rhs. Calls \c lhs.swap(rhs)
template<class T>
void Swap(tmp<T>& lhs, tmp<T>& rhs)
......
......@@ -40,7 +40,8 @@ inline void Foam::tmp<T>::incrCount()
{
FatalErrorInFunction
<< "Attempt to create more than 2 tmp's referring to"
" the same object of type " << typeName()
" the same object of type "
<< tmp<T>::typeName()
<< abort(FatalError);
}
}
......@@ -64,6 +65,13 @@ inline Foam::tmp<T> Foam::tmp<T>::NewFrom(Args&&... args)
}
template<class T>
inline Foam::word Foam::tmp<T>::typeName()
{
return "tmp<" + word(typeid(T).name()) + '>';
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
......@@ -91,7 +99,8 @@ inline Foam::tmp<T>::tmp(T* p)
if (p && !p->unique())
{
FatalErrorInFunction
<< "Attempted construction of a " << typeName()
<< "Attempted construction of a "
<< this->typeName()
<< " from non-unique pointer"
<< abort(FatalError);
}
......@@ -107,34 +116,34 @@ inline Foam::tmp<T>::tmp(const T& obj) noexcept
template<class T>
inline Foam::tmp<T>::tmp(tmp<T>&& t) noexcept
inline Foam::tmp<T>::tmp(tmp<T>&& rhs) noexcept
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
t.ptr_ = nullptr;
t.type_ = PTR;
rhs.ptr_ = nullptr;
rhs.type_ = PTR;
}
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>&& t) noexcept
inline Foam::tmp<T>::tmp(const tmp<T>&& rhs) noexcept
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
t.ptr_ = nullptr;
t.type_ = PTR;
rhs.ptr_ = nullptr;
rhs.type_ = PTR;
}
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>& t)
inline Foam::tmp<T>::tmp(const tmp<T>& rhs)
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
if (isTmp())
if (type_ == PTR)
{
if (ptr_)
{
......@@ -143,7 +152,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t)
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< "Attempted copy of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
}
......@@ -151,18 +161,19 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t)
template<class T>
inline Foam::tmp<T>::tmp(const tmp<T>& t, bool reuse)
inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
:
ptr_(t.ptr_),
type_(t.type_)
ptr_(rhs.ptr_),
type_(rhs.type_)
{
if (isTmp())
if (type_ == PTR)
{
if (ptr_)
{
if (reuse)
{
t.ptr_ = nullptr; // t.type_ already set as PTR
rhs.ptr_ = nullptr;
// Note: rhs.type_ already set as PTR
}
else
{
......@@ -172,7 +183,8 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool reuse)
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< "Attempted copy of a deallocated "
<< this->typeName()
<< abort(FatalError);
}
}
......@@ -195,22 +207,15 @@ inline bool Foam::tmp<T>::movable() const noexcept
}
template<class T>
inline Foam::word Foam::tmp<T>::typeName() const
{
return "tmp<" + word(typeid(T).name()) + '>';
}
template<class T>
inline const T& Foam::tmp<T>::cref() const
{
if (isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
......@@ -222,12 +227,12 @@ inline const T& Foam::tmp<T>::cref() const
template<class T>
inline T& Foam::tmp<T>::ref() const
{
if (isTmp())
if (type_ == PTR)
{
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
}
......@@ -235,7 +240,7 @@ inline T& Foam::tmp<T>::ref() const
{
FatalErrorInFunction
<< "Attempted non-const reference to const object from a "
<< typeName()
<< this->typeName()
<< abort(FatalError);
}
......@@ -256,20 +261,22 @@ inline T* Foam::tmp<T>::ptr() const
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< this->typeName() << " deallocated"
<< abort(FatalError);
}
if (isTmp())
if (type_ == PTR)
{
if (!ptr_->unique())
{
FatalErrorInFunction
<< "Attempt to acquire pointer to object referred to"
<< " by multiple temporaries of type " << typeName()
<< " by multiple temporaries of type "
<< this->typeName()
<< abort(FatalError);
}
// Release pointer