tmp: Improved diagnostics in case of inappropriate reuse

This commit is contained in:
Henry Weller
2016-02-25 11:48:15 +00:00
parent a34fae3240
commit 6d785bca2c
3 changed files with 87 additions and 110 deletions

View File

@ -27,6 +27,10 @@ Class
Description Description
Reference counter for various OpenFOAM components. Reference counter for various OpenFOAM components.
SeeAlso
Foam::tmp
Foam::token::compound
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef refCount_H #ifndef refCount_H
@ -49,6 +53,7 @@ class refCount
int count_; int count_;
// Private Member Functions // Private Member Functions
//- Dissallow copy //- Dissallow copy
@ -58,26 +63,27 @@ class refCount
void operator=(const refCount&); void operator=(const refCount&);
public: protected:
// Constructors // Constructors
//- Construct null with zero count //- Construct null initializing count to 0
refCount() refCount()
: :
count_(0) count_(0)
{} {}
public:
// Member Functions // Member Functions
//- Return the reference count //- Return the current reference count
int count() const int count() const
{ {
return count_; return count_;
} }
//- Return true if the reference count is zero //- Return true if the reference count is zero
bool unique() const bool unique() const
{ {
@ -85,13 +91,6 @@ public:
} }
//- Reset the reference count to zero
void resetRefCount()
{
count_ = 0;
}
// Member Operators // Member Operators
//- Increment the reference count //- Increment the reference count

View File

@ -30,13 +30,17 @@ Description
SourceFiles SourceFiles
tmpI.H tmpI.H
SeeAlso
Foam::refCount
Foam::autoPtr
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef tmp_H #ifndef tmp_H
#define tmp_H #define tmp_H
#include "refCount.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 // ie, it is a reference or a temporary that has been allocated
inline bool valid() const; inline bool valid() const;
//- Return the type name of the tmp
// constructed from the type name of T
inline word typeName() const;
// Edit // Edit
//- Return non-const reference or generate a fatal error //- Return non-const reference or generate a fatal error

View File

@ -33,7 +33,15 @@ inline Foam::tmp<T>::tmp(T* tPtr)
: :
type_(TMP), type_(TMP),
ptr_(tPtr) ptr_(tPtr)
{} {
if (tPtr && !tPtr->unique())
{
FatalErrorInFunction
<< "Attempted construction of a " << typeName()
<< " from non-unique pointer"
<< abort(FatalError);
}
}
template<class T> template<class T>
@ -59,8 +67,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t)
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted copy of a deallocated temporary" << "Attempted copy of a deallocated " << typeName()
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -88,8 +95,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted copy of a deallocated temporary" << "Attempted copy of a deallocated " << typeName()
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -100,18 +106,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
template<class T> template<class T>
inline Foam::tmp<T>::~tmp() inline Foam::tmp<T>::~tmp()
{ {
if (isTmp() && ptr_) clear();
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
}
} }
@ -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> template<class T>
inline T& Foam::tmp<T>::ref() inline T& Foam::tmp<T>::ref()
{ {
if (type_ == TMP) if (isTmp())
{ {
if (!ptr_) if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
return *ptr_;
} }
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempt to acquire non-const reference to const object" << "Attempt to acquire non-const reference to const object"
<< " from a " << typeName()
<< abort(FatalError); << abort(FatalError);
return *ptr_;
} }
return *ptr_;
} }
@ -170,7 +172,7 @@ inline T* Foam::tmp<T>::ptr() const
if (!ptr_) if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -178,7 +180,7 @@ inline T* Foam::tmp<T>::ptr() const
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempt to acquire pointer to object referred to" << "Attempt to acquire pointer to object referred to"
" by multiple 'tmp's" << " by multiple temporaries of type " << typeName()
<< abort(FatalError); << abort(FatalError);
} }
@ -219,47 +221,39 @@ inline void Foam::tmp<T>::clear() const
template<class T> template<class T>
inline T& Foam::tmp<T>::operator()() inline T& Foam::tmp<T>::operator()()
{ {
if (type_ == TMP) if (isTmp())
{ {
if (!ptr_) if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
return *ptr_;
} }
else
{
// Const-ness is automatically cast-away which is why this operator is // Const-ness is automatically cast-away which is why this operator is
// deprecated. Use ref() where non-const access is required. // deprecated. Use ref() where non-const access is required.
return *ptr_; return *ptr_;
} }
}
#endif #endif
template<class T> template<class T>
inline const T& Foam::tmp<T>::operator()() const inline const T& Foam::tmp<T>::operator()() const
{ {
if (type_ == TMP) if (isTmp())
{ {
if (!ptr_) if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
return *ptr_;
} }
else
{
// Return const reference // Return const reference
return *ptr_; return *ptr_;
} }
}
template<class T> template<class T>
@ -277,88 +271,64 @@ inline T* Foam::tmp<T>::operator->()
if (!ptr_) if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError);
}
}
else
{
FatalErrorInFunction
<< "Attempt to cast const object to non-const for a " << typeName()
<< abort(FatalError); << abort(FatalError);
} }
return ptr_; return ptr_;
} }
else
{
FatalErrorInFunction << "Const object cast to non-const"
<< abort(FatalError);
return ptr_;
}
}
template<class T> template<class T>
inline const T* Foam::tmp<T>::operator->() const inline const T* Foam::tmp<T>::operator->() const
{ {
if (isTmp()) if (isTmp() && !ptr_)
{
if (!ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Temporary of type " << typeid(T).name() << " deallocated" << typeName() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
return ptr_; return ptr_;
} }
else
{
return ptr_;
}
}
template<class T> template<class T>
inline void Foam::tmp<T>::operator=(T* tPtr) inline void Foam::tmp<T>::operator=(T* tPtr)
{ {
if (isTmp() && ptr_) clear();
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
}
type_ = TMP;
if (!tPtr) if (!tPtr)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted copy of a deallocated temporary" << "Attempted copy of a deallocated " << typeName()
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
if (tPtr && !tPtr->unique())
{
FatalErrorInFunction
<< "Attempted assignment of a " << typeName()
<< " to non-unique pointer"
<< abort(FatalError);
}
type_ = TMP;
ptr_ = tPtr; ptr_ = tPtr;
ptr_->resetRefCount();
} }
template<class T> template<class T>
inline void Foam::tmp<T>::operator=(const tmp<T>& t) inline void Foam::tmp<T>::operator=(const tmp<T>& t)
{ {
if (isTmp() && ptr_) clear();
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
}
}
if (t.isTmp()) if (t.isTmp())
{ {
@ -367,8 +337,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
if (!t.ptr_) if (!t.ptr_)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted assignment to a deallocated temporary" << "Attempted assignment to a deallocated " << typeName()
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
@ -379,7 +348,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Attempted assignment to a const reference to constant object" << "Attempted assignment to a const reference to an object"
<< " of type " << typeid(T).name() << " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }