Commit dfa89cf8 authored by Henry Weller's avatar Henry Weller
Browse files

tmp: Improved diagnostics in case of inappropriate reuse

parent acac7d78
......@@ -27,6 +27,10 @@ Class
Description
Reference counter for various OpenFOAM components.
SeeAlso
Foam::tmp
Foam::token::compound
\*---------------------------------------------------------------------------*/
#ifndef refCount_H
......@@ -49,6 +53,7 @@ class refCount
int count_;
// Private Member Functions
//- Dissallow copy
......@@ -58,26 +63,27 @@ class refCount
void operator=(const refCount&);
public:
protected:
// Constructors
//- Construct null with zero count
//- Construct null initializing count to 0
refCount()
:
count_(0)
{}
public:
// Member Functions
//- Return the reference count
//- Return the current reference count
int count() const
{
return count_;
}
//- Return true if the reference count is zero
bool unique() const
{
......@@ -85,13 +91,6 @@ public:
}
//- Reset the reference count to zero
void resetRefCount()
{
count_ = 0;
}
// Member Operators
//- Increment the reference count
......
......@@ -30,13 +30,17 @@ Description
SourceFiles
tmpI.H
SeeAlso
Foam::refCount
Foam::autoPtr
\*---------------------------------------------------------------------------*/
#ifndef tmp_H
#define tmp_H
#include "refCount.H"
#include <cstddef>
#include "word.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -102,6 +106,11 @@ public:
// ie, it is a reference or a temporary that has been allocated
inline bool valid() const;
//- Return the type name of the tmp
// constructed from the type name of T
inline word typeName() const;
// Edit
//- Return non-const reference or generate a fatal error
......
......@@ -33,7 +33,15 @@ inline Foam::tmp<T>::tmp(T* tPtr)
:
type_(TMP),
ptr_(tPtr)
{}
{
if (tPtr && !tPtr->unique())
{
FatalErrorInFunction
<< "Attempted construction of a " << typeName()
<< " from non-unique pointer"
<< abort(FatalError);
}
}
template<class T>
......@@ -59,8 +67,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t)
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< "Attempted copy of a deallocated " << typeName()
<< abort(FatalError);
}
}
......@@ -88,8 +95,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
else
{
FatalErrorInFunction
<< "Attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< "Attempted copy of a deallocated " << typeName()
<< abort(FatalError);
}
}
......@@ -100,18 +106,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
template<class T>
inline Foam::tmp<T>::~tmp()
{
if (isTmp() && ptr_)
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
}
clear();
}
......@@ -138,27 +133,34 @@ inline bool Foam::tmp<T>::valid() const
}
template<class T>
inline Foam::word Foam::tmp<T>::typeName() const
{
return "tmp<" + word(typeid(T).name()) + '>';
}
template<class T>
inline T& Foam::tmp<T>::ref()
{
if (type_ == TMP)
if (isTmp())
{
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< typeName() << " deallocated"
<< abort(FatalError);
}
return *ptr_;
}
else
{
FatalErrorInFunction
<< "Attempt to acquire non-const reference to const object"
<< " from a " << typeName()
<< abort(FatalError);
return *ptr_;
}
return *ptr_;
}
......@@ -170,7 +172,7 @@ inline T* Foam::tmp<T>::ptr() const
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< typeName() << " deallocated"
<< abort(FatalError);
}
......@@ -178,7 +180,7 @@ inline T* Foam::tmp<T>::ptr() const
{
FatalErrorInFunction
<< "Attempt to acquire pointer to object referred to"
" by multiple 'tmp's"
<< " by multiple temporaries of type " << typeName()
<< abort(FatalError);
}
......@@ -219,23 +221,19 @@ inline void Foam::tmp<T>::clear() const
template<class T>
inline T& Foam::tmp<T>::operator()()
{
if (type_ == TMP)
if (isTmp())
{
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< typeName() << " deallocated"
<< abort(FatalError);
}
return *ptr_;
}
else
{
// Const-ness is automatically cast-away which is why this operator is
// deprecated. Use ref() where non-const access is required.
return *ptr_;
}
// Const-ness is automatically cast-away which is why this operator is
// deprecated. Use ref() where non-const access is required.
return *ptr_;
}
#endif
......@@ -243,22 +241,18 @@ inline T& Foam::tmp<T>::operator()()
template<class T>
inline const T& Foam::tmp<T>::operator()() const
{
if (type_ == TMP)
if (isTmp())
{
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< typeName() << " deallocated"
<< abort(FatalError);
}
return *ptr_;
}
else
{
// Return const reference
return *ptr_;
}
// Return const reference
return *ptr_;
}
......@@ -274,91 +268,67 @@ inline T* Foam::tmp<T>::operator->()
{
if (isTmp())
{
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError);
}
return ptr_;
if (!ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< abort(FatalError);
}
}
else
{
FatalErrorInFunction << "Const object cast to non-const"
FatalErrorInFunction
<< "Attempt to cast const object to non-const for a " << typeName()
<< abort(FatalError);
return ptr_;
}
return ptr_;
}
template<class T>
inline const T* Foam::tmp<T>::operator->() const
{
if (isTmp())
if (isTmp() && !ptr_)
{
if (!ptr_)
{
FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError);
}
return ptr_;
}
else
{
return ptr_;
FatalErrorInFunction
<< typeName() << " deallocated"
<< abort(FatalError);
}
return ptr_;
}
template<class T>
inline void Foam::tmp<T>::operator=(T* tPtr)
{
if (isTmp() && ptr_)
clear();
if (!tPtr)
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
FatalErrorInFunction
<< "Attempted copy of a deallocated " << typeName()
<< abort(FatalError);
}
type_ = TMP;
if (!tPtr)
if (tPtr && !tPtr->unique())
{
FatalErrorInFunction
<< "Attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< "Attempted assignment of a " << typeName()
<< " to non-unique pointer"
<< abort(FatalError);
}
type_ = TMP;
ptr_ = tPtr;
ptr_->resetRefCount();
}
template<class T>
inline void Foam::tmp<T>::operator=(const tmp<T>& t)
{
if (isTmp() && ptr_)
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
}
clear();
if (t.isTmp())
{
......@@ -367,8 +337,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
if (!t.ptr_)
{
FatalErrorInFunction
<< "Attempted assignment to a deallocated temporary"
<< " of type " << typeid(T).name()
<< "Attempted assignment to a deallocated " << typeName()
<< abort(FatalError);
}
......@@ -379,7 +348,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
else
{
FatalErrorInFunction
<< "Attempted assignment to a const reference to constant object"
<< "Attempted assignment to a const reference to an object"
<< " of type " << typeid(T).name()
<< abort(FatalError);
}
......
Markdown is supported
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