ENH: support writable reference for tmp (#1775)

- improves flexibility. Can tag a tmp as allowing non-const access to
  the reference and skip additional const_cast in following code. For
  example,

      tmp<volScalarField> tfld(nullptr);
      auto* ptr = getObjectPtr<volScalarField>("field");
      if (ptr)
      {
          tfld.ref(*ptr);
      }
      else
      {
          tfld.reset(volScalarField::New(...));
      }
      auto& fld = tfld.ref();

ENH: renamed tmpNrc to refPtr

- the name 'refPtr' (reference|pointer) should be easier to remember
  than tmpNrc (tmp, but non-ref-counted).

- provide tmpNrc typedef and header for code compatibility

NOTE

- in some places refPtr and tmp can be used instead of a
  std::reference_wrapper for handling external references.

  Unlike std::reference_wrapper, it can be default constructed
  (holding nothing), whereas reference_wrapper may need a dummy
  reference. However, the lifetime extension of references _may_ be
  better with reference_wrapper.
This commit is contained in:
Mark Olesen
2020-07-21 09:11:26 +02:00
parent 5acb5f3580
commit be058bec7d
14 changed files with 206 additions and 161 deletions

View File

@ -25,13 +25,13 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::tmpNrc
Foam::refPtr
Description
A class for managing temporary objects without reference counting.
A class for managing references or pointers (no reference counting)
SourceFiles
tmpNrcI.H
refPtrI.H
See also
Foam::autoPtr
@ -39,8 +39,8 @@ See also
\*---------------------------------------------------------------------------*/
#ifndef tmpNrc_H
#define tmpNrc_H
#ifndef refPtr_H
#define refPtr_H
#include "tmp.H"
@ -50,11 +50,11 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class tmpNrc Declaration
Class refPtr Declaration
\*---------------------------------------------------------------------------*/
template<class T>
class tmpNrc
class refPtr
{
// Private Data
@ -62,7 +62,8 @@ class tmpNrc
enum refType
{
PTR, //!< Managing a pointer (not ref-counted)
CREF //!< Using (const) reference to an object
CREF, //!< Using (const) reference to an object
REF //!< Using (non-const) reference to an object
};
//- The managed pointer or address of the object (reference)
@ -76,10 +77,10 @@ public:
// STL type definitions
//- Type of object being managed
//- Type of object being managed or referenced
typedef T element_type;
//- Pointer to type of object being managed
//- Pointer to type of object being managed or referenced
typedef T* pointer;
@ -89,50 +90,50 @@ public:
// Factory Methods
//- Construct tmpNrc of T with forwarding arguments
//- Construct refPtr of T with forwarding arguments
// \param args list of arguments with which an instance of T
// will be constructed.
//
// \note Similar to std::make_shared, but the overload for
// array types is not disabled.
template<class... Args>
inline static tmpNrc<T> New(Args&&... args);
inline static refPtr<T> New(Args&&... args);
//- Construct tmpNrc from derived type with forwarding arguments
//- Construct refPtr from derived type with forwarding arguments
// \param args list of arguments with which an instance of U
// will be constructed.
//
// \note Similar to New but for derived types
template<class U, class... Args>
inline static tmpNrc<T> NewFrom(Args&&... args);
inline static refPtr<T> NewFrom(Args&&... args);
// Constructors
//- Default construct, no managed pointer.
inline constexpr tmpNrc() noexcept;
inline constexpr refPtr() noexcept;
//- Construct with no managed pointer.
inline constexpr tmpNrc(std::nullptr_t) noexcept;
inline constexpr refPtr(std::nullptr_t) noexcept;
//- Construct, taking ownership of the pointer.
inline explicit tmpNrc(T* p) noexcept;
inline explicit refPtr(T* p) noexcept;
//- Construct for a const reference to an object.
inline tmpNrc(const T& obj) noexcept;
inline refPtr(const T& obj) noexcept;
//- Move construct, transferring ownership.
inline tmpNrc(tmpNrc<T>&& t) noexcept;
inline refPtr(refPtr<T>&& t) noexcept;
//- Copy construct
inline tmpNrc(const tmpNrc<T>& t);
inline refPtr(const refPtr<T>& t);
//- Copy construct. Optionally reusing pointer.
inline tmpNrc(const tmpNrc<T>& t, bool reuse);
inline refPtr(const refPtr<T>& t, bool reuse);
//- Destructor: deletes managed pointer
inline ~tmpNrc();
inline ~refPtr();
// Member Functions
@ -148,6 +149,9 @@ public:
//- True for non-null pointer/reference
bool valid() const noexcept { return ptr_; }
//- 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)
bool isTmp() const noexcept { return type_ == PTR; }
@ -166,8 +170,8 @@ public:
//- Return const pointer without nullptr checking.
const T* get() const noexcept { return ptr_; }
//- Return the const object reference or a const reference to the
//- contents of a non-null managed pointer.
//- Return const reference to the object or to the contents
//- of a (non-null) managed pointer.
// Fatal for a null managed pointer
inline const T& cref() const;
@ -185,8 +189,7 @@ public:
// Edit
//- Return managed pointer for reuse, or clone() the const object
//- reference.
//- Return managed pointer for reuse, or clone() the object reference.
inline T* ptr() const;
//- If object pointer points to valid object:
@ -197,19 +200,21 @@ public:
inline void reset(T* p = nullptr) noexcept;
//- Clear existing and transfer ownership.
inline void reset(tmpNrc<T>&& other) noexcept;
inline void reset(refPtr<T>&& other) noexcept;
//- Delete managed temporary object and set to const reference
//- Delete managed temporary object and set to (const) reference
inline void cref(const T& obj) noexcept;
//- Delete managed temporary object and set to (non-const) reference
inline void ref(T& obj) noexcept;
//- Swaps the managed object with other.
inline void swap(tmpNrc<T>& other) noexcept;
inline void swap(refPtr<T>& other) noexcept;
// Member Operators
//- Return const reference to the object.
// Identical to cref() method.
//- Identical to cref() method.
inline const T& operator()() const;
//- Cast to underlying data type, using the cref() method.
@ -228,10 +233,10 @@ public:
//- Transfer ownership of the managed pointer.
// Fatal for a null managed pointer or if the object is const.
inline void operator=(const tmpNrc<T>& t);
inline void operator=(const refPtr<T>& t);
//- Clear existing and transfer ownership.
inline void operator=(tmpNrc<T>&& other) noexcept;
inline void operator=(refPtr<T>&& other) noexcept;
//- Take ownership of the pointer.
// Fatal for a null pointer
@ -247,10 +252,10 @@ public:
// Global Functions
//- Specializes the Swap algorithm for tmpNrc.
//- Specializes the Swap algorithm for refPtr.
// Swaps the pointers and types of lhs and rhs. Calls \c lhs.swap(rhs)
template<class T>
void Swap(tmpNrc<T>& lhs, tmpNrc<T>& rhs)
void Swap(refPtr<T>& lhs, refPtr<T>& rhs)
{
lhs.swap(rhs);
}
@ -262,7 +267,7 @@ void Swap(tmpNrc<T>& lhs, tmpNrc<T>& rhs)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "tmpNrcI.H"
#include "refPtrI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -33,24 +33,24 @@ License
template<class T>
template<class... Args>
inline Foam::tmpNrc<T> Foam::tmpNrc<T>::New(Args&&... args)
inline Foam::refPtr<T> Foam::refPtr<T>::New(Args&&... args)
{
return tmpNrc<T>(new T(std::forward<Args>(args)...));
return refPtr<T>(new T(std::forward<Args>(args)...));
}
template<class T>
template<class U, class... Args>
inline Foam::tmpNrc<T> Foam::tmpNrc<T>::NewFrom(Args&&... args)
inline Foam::refPtr<T> Foam::refPtr<T>::NewFrom(Args&&... args)
{
return tmpNrc<T>(new U(std::forward<Args>(args)...));
return refPtr<T>(new U(std::forward<Args>(args)...));
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
inline constexpr Foam::tmpNrc<T>::tmpNrc() noexcept
inline constexpr Foam::refPtr<T>::refPtr() noexcept
:
ptr_(nullptr),
type_(PTR)
@ -58,7 +58,7 @@ inline constexpr Foam::tmpNrc<T>::tmpNrc() noexcept
template<class T>
inline constexpr Foam::tmpNrc<T>::tmpNrc(std::nullptr_t) noexcept
inline constexpr Foam::refPtr<T>::refPtr(std::nullptr_t) noexcept
:
ptr_(nullptr),
type_(PTR)
@ -66,7 +66,7 @@ inline constexpr Foam::tmpNrc<T>::tmpNrc(std::nullptr_t) noexcept
template<class T>
inline Foam::tmpNrc<T>::tmpNrc(T* p) noexcept
inline Foam::refPtr<T>::refPtr(T* p) noexcept
:
ptr_(p),
type_(PTR)
@ -74,7 +74,7 @@ inline Foam::tmpNrc<T>::tmpNrc(T* p) noexcept
template<class T>
inline Foam::tmpNrc<T>::tmpNrc(const T& obj) noexcept
inline Foam::refPtr<T>::refPtr(const T& obj) noexcept
:
ptr_(const_cast<T*>(&obj)),
type_(CREF)
@ -82,7 +82,7 @@ inline Foam::tmpNrc<T>::tmpNrc(const T& obj) noexcept
template<class T>
inline Foam::tmpNrc<T>::tmpNrc(tmpNrc<T>&& t) noexcept
inline Foam::refPtr<T>::refPtr(refPtr<T>&& t) noexcept
:
ptr_(t.ptr_),
type_(t.type_)
@ -93,7 +93,7 @@ inline Foam::tmpNrc<T>::tmpNrc(tmpNrc<T>&& t) noexcept
template<class T>
inline Foam::tmpNrc<T>::tmpNrc(const tmpNrc<T>& t)
inline Foam::refPtr<T>::refPtr(const refPtr<T>& t)
:
ptr_(t.ptr_),
type_(t.type_)
@ -115,7 +115,7 @@ inline Foam::tmpNrc<T>::tmpNrc(const tmpNrc<T>& t)
template<class T>
inline Foam::tmpNrc<T>::tmpNrc(const tmpNrc<T>& t, bool reuse)
inline Foam::refPtr<T>::refPtr(const refPtr<T>& t, bool reuse)
:
ptr_(t.ptr_),
type_(t.type_)
@ -144,7 +144,7 @@ inline Foam::tmpNrc<T>::tmpNrc(const tmpNrc<T>& t, bool reuse)
template<class T>
inline Foam::tmpNrc<T>::~tmpNrc()
inline Foam::refPtr<T>::~refPtr()
{
clear();
}
@ -153,21 +153,21 @@ inline Foam::tmpNrc<T>::~tmpNrc()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T>
inline bool Foam::tmpNrc<T>::movable() const noexcept
inline bool Foam::refPtr<T>::movable() const noexcept
{
return (type_ == PTR && ptr_);
}
template<class T>
inline Foam::word Foam::tmpNrc<T>::typeName() const
inline Foam::word Foam::refPtr<T>::typeName() const
{
return "tmpNrc<" + word(typeid(T).name()) + '>';
return "refPtr<" + word(typeid(T).name()) + '>';
}
template<class T>
inline const T& Foam::tmpNrc<T>::cref() const
inline const T& Foam::refPtr<T>::cref() const
{
if (isTmp())
{
@ -184,7 +184,7 @@ inline const T& Foam::tmpNrc<T>::cref() const
template<class T>
inline T& Foam::tmpNrc<T>::ref() const
inline T& Foam::refPtr<T>::ref() const
{
if (isTmp())
{
@ -195,7 +195,7 @@ inline T& Foam::tmpNrc<T>::ref() const
<< abort(FatalError);
}
}
else // if (type_ == CREF)
else if (type_ == CREF)
{
FatalErrorInFunction
<< "Attempted non-const reference to const object from a "
@ -208,21 +208,14 @@ inline T& Foam::tmpNrc<T>::ref() const
template<class T>
inline T& Foam::tmpNrc<T>::constCast() const
inline T& Foam::refPtr<T>::constCast() const
{
if (isTmp() && !ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< abort(FatalError);
}
return const_cast<T&>(*ptr_);
return const_cast<T&>(cref());
}
template<class T>
inline T* Foam::tmpNrc<T>::ptr() const
inline T* Foam::refPtr<T>::ptr() const
{
if (!ptr_)
{
@ -244,7 +237,7 @@ inline T* Foam::tmpNrc<T>::ptr() const
template<class T>
inline void Foam::tmpNrc<T>::clear() const noexcept
inline void Foam::refPtr<T>::clear() const noexcept
{
if (isTmp() && ptr_)
{
@ -255,7 +248,7 @@ inline void Foam::tmpNrc<T>::clear() const noexcept
template<class T>
inline void Foam::tmpNrc<T>::reset(T* p) noexcept
inline void Foam::refPtr<T>::reset(T* p) noexcept
{
clear();
ptr_ = p;
@ -264,7 +257,7 @@ inline void Foam::tmpNrc<T>::reset(T* p) noexcept
template<class T>
inline void Foam::tmpNrc<T>::reset(tmpNrc<T>&& other) noexcept
inline void Foam::refPtr<T>::reset(refPtr<T>&& other) noexcept
{
if (&other == this)
{
@ -281,7 +274,7 @@ inline void Foam::tmpNrc<T>::reset(tmpNrc<T>&& other) noexcept
template<class T>
inline void Foam::tmpNrc<T>::cref(const T& obj) noexcept
inline void Foam::refPtr<T>::cref(const T& obj) noexcept
{
clear();
ptr_ = const_cast<T*>(&obj);
@ -290,7 +283,16 @@ inline void Foam::tmpNrc<T>::cref(const T& obj) noexcept
template<class T>
inline void Foam::tmpNrc<T>::swap(tmpNrc<T>& other) noexcept
inline void Foam::refPtr<T>::ref(T& obj) noexcept
{
clear();
ptr_ = &obj;
type_ = REF;
}
template<class T>
inline void Foam::refPtr<T>::swap(refPtr<T>& other) noexcept
{
if (&other == this)
{
@ -311,21 +313,21 @@ inline void Foam::tmpNrc<T>::swap(tmpNrc<T>& other) noexcept
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class T>
inline const T& Foam::tmpNrc<T>::operator()() const
inline const T& Foam::refPtr<T>::operator()() const
{
return cref();
}
template<class T>
inline Foam::tmpNrc<T>::operator const T&() const
inline Foam::refPtr<T>::operator const T&() const
{
return cref();
}
template<class T>
inline const T* Foam::tmpNrc<T>::operator->() const
inline const T* Foam::refPtr<T>::operator->() const
{
if (!ptr_ && isTmp())
{
@ -339,7 +341,7 @@ inline const T* Foam::tmpNrc<T>::operator->() const
template<class T>
inline T* Foam::tmpNrc<T>::operator->()
inline T* Foam::refPtr<T>::operator->()
{
if (isTmp())
{
@ -362,7 +364,7 @@ inline T* Foam::tmpNrc<T>::operator->()
template<class T>
inline void Foam::tmpNrc<T>::operator=(const tmpNrc<T>& t)
inline void Foam::refPtr<T>::operator=(const refPtr<T>& t)
{
if (&t == this)
{
@ -395,7 +397,7 @@ inline void Foam::tmpNrc<T>::operator=(const tmpNrc<T>& t)
template<class T>
inline void Foam::tmpNrc<T>::operator=(tmpNrc<T>&& other) noexcept
inline void Foam::refPtr<T>::operator=(refPtr<T>&& other) noexcept
{
if (&other == this)
{
@ -412,7 +414,7 @@ inline void Foam::tmpNrc<T>::operator=(tmpNrc<T>&& other) noexcept
template<class T>
inline void Foam::tmpNrc<T>::operator=(T* p)
inline void Foam::refPtr<T>::operator=(T* p)
{
if (!p)
{
@ -426,14 +428,14 @@ inline void Foam::tmpNrc<T>::operator=(T* p)
template<class T>
inline void Foam::tmpNrc<T>::operator=(std::nullptr_t) noexcept
inline void Foam::refPtr<T>::operator=(std::nullptr_t) noexcept
{
reset(nullptr);
}
template<class T>
inline Foam::tmpNrc<T>::operator tmp<T>()
inline Foam::refPtr<T>::operator tmp<T>()
{
if (isTmp())
{

View File

@ -40,6 +40,7 @@ SourceFiles
See also
Foam::autoPtr
Foam::refPtr
Foam::refCount
\*---------------------------------------------------------------------------*/
@ -69,7 +70,8 @@ class tmp
enum refType
{
PTR, //!< Managing a pointer (ref-counted)
CREF //!< Using (const) reference to an object
CREF, //!< Using (const) reference to an object
REF //!< Using (non-const) reference to an object
};
//- The managed pointer or address of the object (reference)
@ -169,6 +171,9 @@ public:
//- True for non-null pointer/reference
bool valid() const noexcept { return ptr_; }
//- 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)
bool isTmp() const noexcept { return type_ == PTR; }
@ -187,8 +192,8 @@ public:
//- Return const pointer without nullptr checking.
const T* get() const noexcept { return ptr_; }
//- Return the const object reference or a const reference to the
//- contents of a non-null managed pointer.
//- Return const reference to the object or to the contents
//- of a (non-null) managed pointer.
// Fatal for a null managed pointer
inline const T& cref() const;
@ -200,14 +205,13 @@ public:
//- Non-const dereference, even if the object is const.
// This is similar to ref(), but applies a const_cast to access
// const objects.
// Fatal for a null managed pointer.
// Fatal for a null pointer.
inline T& constCast() const;
// Edit
//- Return managed pointer for reuse, or clone() the const object
//- reference.
//- Return managed pointer for reuse, or clone() the object reference.
inline T* ptr() const;
//- If object pointer points to valid object:
@ -220,17 +224,19 @@ public:
//- Clear existing and transfer ownership.
inline void reset(tmp<T>&& other) noexcept;
//- Delete managed temporary object and set to const reference
//- Delete managed temporary object and set to (const) reference
inline void cref(const T& obj) noexcept;
//- Delete managed temporary object and set to (non-const) reference
inline void ref(T& obj) noexcept;
//- Swaps the managed object with other.
inline void swap(tmp<T>& other) noexcept;
// Member Operators
//- Return const reference to the object.
// Identical to cref() method.
//- Identical to cref() method.
inline const T& operator()() const;
//- Cast to underlying data type, using the cref() method.

View File

@ -231,7 +231,7 @@ inline T& Foam::tmp<T>::ref() const
<< abort(FatalError);
}
}
else // if (type_ == CREF)
else if (type_ == CREF)
{
FatalErrorInFunction
<< "Attempted non-const reference to const object from a "
@ -246,14 +246,7 @@ inline T& Foam::tmp<T>::ref() const
template<class T>
inline T& Foam::tmp<T>::constCast() const
{
if (isTmp() && !ptr_)
{
FatalErrorInFunction
<< typeName() << " deallocated"
<< abort(FatalError);
}
return const_cast<T&>(*ptr_);
return const_cast<T&>(cref());
}
@ -340,6 +333,15 @@ inline void Foam::tmp<T>::cref(const T& obj) noexcept
}
template<class T>
inline void Foam::tmp<T>::ref(T& obj) noexcept
{
clear();
ptr_ = &obj;
type_ = REF;
}
template<class T>
inline void Foam::tmp<T>::swap(tmp<T>& other) noexcept
{

View File

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2002 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Typedef
Foam::tmpNrc
Description
Compatibility name. Superseded (JUL-2020) by Foam::refPtr
\*---------------------------------------------------------------------------*/
#ifndef tmpNrc_H
#define tmpNrc_H
#include "refPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef refPtr tmpNrc;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1 @@
#warning File removed - left for old dependency check only