From 83d6aa424ac9f5f6106343b672778c826dae0b24 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Tue, 19 Nov 2019 20:21:42 +0100
Subject: [PATCH] ENH: add move reset and move assignment for tmp, tmpNrc

- improves similarity to autoPtr. Simplifies coding.

  Example,

    tmp<volScalarField> tfield;

    // sometime later...

    tfield.reset
    (
        volScalarField::New("myfield", mesh, dimensionedScalar(Zero))
    );

- as per tmp, disallow tmpNrc assignment from literal nullptr

- as per autoPtr, allow explicit test as bool (same as valid).
---
 src/OpenFOAM/memory/autoPtr/autoPtr.H |  2 +-
 src/OpenFOAM/memory/tmp/tmp.H         | 17 ++++++++---
 src/OpenFOAM/memory/tmp/tmpI.H        | 41 +++++++++++++++++++++++++
 src/OpenFOAM/memory/tmp/tmpNrc.H      | 34 ++++++++++++++-------
 src/OpenFOAM/memory/tmp/tmpNrcI.H     | 43 ++++++++++++++++++++++++++-
 5 files changed, 121 insertions(+), 16 deletions(-)

diff --git a/src/OpenFOAM/memory/autoPtr/autoPtr.H b/src/OpenFOAM/memory/autoPtr/autoPtr.H
index d5db1d6a3d1..b35ff37b898 100644
--- a/src/OpenFOAM/memory/autoPtr/autoPtr.H
+++ b/src/OpenFOAM/memory/autoPtr/autoPtr.H
@@ -241,7 +241,7 @@ public:
         //- Cast to pointer type
         operator T*() noexcept { return get(); }
 
-        //- True if the managed pointer is non-null
+        //- True if the managed pointer is non-null - same as valid()
         explicit inline operator bool() const noexcept;
 
         //- Transfer object ownership from parameter
diff --git a/src/OpenFOAM/memory/tmp/tmp.H b/src/OpenFOAM/memory/tmp/tmp.H
index 958749530f9..dacb813c5ff 100644
--- a/src/OpenFOAM/memory/tmp/tmp.H
+++ b/src/OpenFOAM/memory/tmp/tmp.H
@@ -63,12 +63,12 @@ namespace Foam
 template<class T>
 class tmp
 {
-    // Private data
+    // Private Data
 
         //- Object types
         enum refType
         {
-            PTR,    //!< Managing a (ref-counted) pointer
+            PTR,    //!< Managing a pointer (ref-counted)
             CREF    //!< Using a const-reference to an object
         };
 
@@ -218,14 +218,17 @@ public:
         //- Delete managed temporary object and set to new given pointer
         inline void reset(T* p) noexcept;
 
+        //- Clear existing and transfer ownership.
+        inline void reset(tmp<T>&& other) noexcept;
+
         //- Delete managed temporary object and set to const reference
         inline void cref(const T& obj) noexcept;
 
-        //- Swaps the managed object with other tmp.
+        //- Swaps the managed object with other.
         inline void swap(tmp<T>& other) noexcept;
 
 
-    // Member operators
+    // Member Operators
 
         //- Return const reference to the object.
         //  Identical to cref() method.
@@ -242,6 +245,9 @@ public:
         //  Fatal for a null managed pointer or if the object is const.
         inline T* operator->();
 
+        //- Is non-null managed pointer or const object reference : valid()
+        explicit inline operator bool() const noexcept;
+
         //- Take ownership of the pointer.
         //  Fatal for a null pointer, or when the pointer is non-unique.
         inline void operator=(T* p);
@@ -250,6 +256,9 @@ public:
         //  Fatal for a null managed pointer or if the object is const.
         inline void operator=(const tmp<T>& t);
 
+        //- Clear existing and transfer ownership.
+        inline void operator=(tmp<T>&& other) noexcept;
+
 
     // Housekeeping
 
diff --git a/src/OpenFOAM/memory/tmp/tmpI.H b/src/OpenFOAM/memory/tmp/tmpI.H
index 21e30caf6ff..a035432d813 100644
--- a/src/OpenFOAM/memory/tmp/tmpI.H
+++ b/src/OpenFOAM/memory/tmp/tmpI.H
@@ -357,6 +357,23 @@ inline void Foam::tmp<T>::reset(T* p) noexcept
 }
 
 
+template<class T>
+inline void Foam::tmp<T>::reset(tmp<T>&& other) noexcept
+{
+    if (&other == this)
+    {
+        return;  // Self-assignment is a no-op
+    }
+
+    clear();
+    ptr_ = other.ptr_;
+    type_ = other.type_;
+
+    other.ptr_ = nullptr;
+    other.type_ = PTR;
+}
+
+
 template<class T>
 inline void Foam::tmp<T>::cref(const T& obj) noexcept
 {
@@ -438,6 +455,13 @@ inline T* Foam::tmp<T>::operator->()
 }
 
 
+template<class T>
+inline Foam::tmp<T>::operator bool() const noexcept
+{
+    return (ptr_ || type_ == CREF);
+}
+
+
 template<class T>
 inline void Foam::tmp<T>::operator=(T* p)
 {
@@ -495,4 +519,21 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
 }
 
 
+template<class T>
+inline void Foam::tmp<T>::operator=(tmp<T>&& other) noexcept
+{
+    if (&other == this)
+    {
+        return;  // Self-assignment is a no-op
+    }
+
+    clear();
+    ptr_ = other.ptr_;
+    type_ = other.type_;
+
+    other.ptr_ = nullptr;
+    other.type_ = PTR;
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/memory/tmp/tmpNrc.H b/src/OpenFOAM/memory/tmp/tmpNrc.H
index 2e33aeb8d45..c997b3c8000 100644
--- a/src/OpenFOAM/memory/tmp/tmpNrc.H
+++ b/src/OpenFOAM/memory/tmp/tmpNrc.H
@@ -35,16 +35,14 @@ SourceFiles
 
 See also
     Foam::autoPtr
+    Foam::tmp
 
 \*---------------------------------------------------------------------------*/
 
 #ifndef tmpNrc_H
 #define tmpNrc_H
 
-#include "refCount.H"
-#include "word.H"
 #include "tmp.H"
-#include <utility>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -58,7 +56,7 @@ namespace Foam
 template<class T>
 class tmpNrc
 {
-    // Private data
+    // Private Data
 
         //- Object types
         enum refType
@@ -123,13 +121,13 @@ public:
         //- Construct for a const reference to an object.
         inline tmpNrc(const T& obj) noexcept;
 
-        //- Move construct
-        inline tmpNrc(tmpNrc<T>&& t);
+        //- Move construct, transferring ownership.
+        inline tmpNrc(tmpNrc<T>&& t) noexcept;
 
         //- Copy construct
         inline tmpNrc(const tmpNrc<T>& t);
 
-        //- Construct copy, transferring content of temporary if required
+        //- Copy construct. Optionally reusing pointer.
         inline tmpNrc(const tmpNrc<T>& t, bool reuse);
 
 
@@ -200,14 +198,17 @@ public:
         //- Delete managed temporary object and set to new given pointer
         inline void reset(T* p) noexcept;
 
+        //- Clear existing and transfer ownership.
+        inline void reset(tmpNrc<T>&& other) noexcept;
+
         //- Delete managed temporary object and set to const reference
         inline void cref(const T& obj) noexcept;
 
-        //- Swaps the managed object with other tmpNrc.
+        //- Swaps the managed object with other.
         inline void swap(tmpNrc<T>& other) noexcept;
 
 
-    // Member operators
+    // Member Operators
 
         //- Return const reference to the object.
         //  Identical to cref() method.
@@ -224,6 +225,9 @@ public:
         //  Fatal for a null managed pointer or if the object is const.
         inline T* operator->();
 
+        //- Is non-null managed pointer or const object reference : valid()
+        explicit inline operator bool() const noexcept;
+
         //- Take ownership of the pointer.
         //  Fatal for a null pointer, or when the pointer is non-unique.
         inline void operator=(T* p);
@@ -232,14 +236,24 @@ public:
         //  Fatal for a null managed pointer or if the object is const.
         inline void operator=(const tmpNrc<T>& t);
 
+        //- Clear existing and transfer ownership.
+        inline void operator=(tmpNrc<T>&& other) noexcept;
+
         //- Conversion to tmp
         inline operator tmp<T>();
+
+
+    // Housekeeping
+
+        //- No assignment from literal nullptr.
+        //  Consistent with run-time check for nullptr on assignment.
+        void operator=(std::nullptr_t) = delete;
 };
 
 
 // Global Functions
 
-//- Specializes the Swap algorithm for tmp.
+//- Specializes the Swap algorithm for tmpNrc.
 //  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)
diff --git a/src/OpenFOAM/memory/tmp/tmpNrcI.H b/src/OpenFOAM/memory/tmp/tmpNrcI.H
index fd35c741ef7..3ff8924c16b 100644
--- a/src/OpenFOAM/memory/tmp/tmpNrcI.H
+++ b/src/OpenFOAM/memory/tmp/tmpNrcI.H
@@ -82,7 +82,7 @@ inline Foam::tmpNrc<T>::tmpNrc(const T& obj) noexcept
 
 
 template<class T>
-inline Foam::tmpNrc<T>::tmpNrc(tmpNrc<T>&& t)
+inline Foam::tmpNrc<T>::tmpNrc(tmpNrc<T>&& t) noexcept
 :
     ptr_(t.ptr_),
     type_(t.type_)
@@ -307,6 +307,23 @@ inline void Foam::tmpNrc<T>::reset(T* p) noexcept
 }
 
 
+template<class T>
+inline void Foam::tmpNrc<T>::reset(tmpNrc<T>&& other) noexcept
+{
+    if (&other == this)
+    {
+        return;  // Self-assignment is a no-op
+    }
+
+    clear();
+    ptr_ = other.ptr_;
+    type_ = other.type_;
+
+    other.ptr_ = nullptr;
+    other.type_ = PTR;
+}
+
+
 template<class T>
 inline void Foam::tmpNrc<T>::cref(const T& obj) noexcept
 {
@@ -388,6 +405,13 @@ inline T* Foam::tmpNrc<T>::operator->()
 }
 
 
+template<class T>
+inline Foam::tmpNrc<T>::operator bool() const noexcept
+{
+    return (ptr_ || type_ == CREF);
+}
+
+
 template<class T>
 inline void Foam::tmpNrc<T>::operator=(T* p)
 {
@@ -438,6 +462,23 @@ inline void Foam::tmpNrc<T>::operator=(const tmpNrc<T>& t)
 }
 
 
+template<class T>
+inline void Foam::tmpNrc<T>::operator=(tmpNrc<T>&& other) noexcept
+{
+    if (&other == this)
+    {
+        return;  // Self-assignment is a no-op
+    }
+
+    clear();
+    ptr_ = other.ptr_;
+    type_ = other.type_;
+
+    other.ptr_ = nullptr;
+    other.type_ = PTR;
+}
+
+
 template<class T>
 inline Foam::tmpNrc<T>::operator tmp<T>()
 {
-- 
GitLab