diff options
author | Murray Cumming <murrayc@murrayc.com> | 2015-08-20 14:04:15 +0200 |
---|---|---|
committer | Murray Cumming <murrayc@murrayc.com> | 2015-08-20 14:04:15 +0200 |
commit | 8dffde3c2210bb0c623af173a8d877647d9f8b67 (patch) | |
tree | 34bd51a821e54970c0984ce7872c1d77bb2280ce | |
parent | 59366128a9848549a9bc6572145da1c02be2f8b9 (diff) |
RefPtr: Add move constructors and move operator=().
Roughly based on the same changes in Glib::RefPtr<>.
-rw-r--r-- | cairomm/refptr.h | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/cairomm/refptr.h b/cairomm/refptr.h index afe3e07..9b7eb91 100644 --- a/cairomm/refptr.h +++ b/cairomm/refptr.h @@ -22,6 +22,7 @@ * 02110-1301, USA. */ +#include <utility> namespace Cairo { @@ -42,6 +43,10 @@ template <class T_CppObject> class RefPtr { public: + // Let the cast constructors and assignement operators access private data. + template <typename T_CastFrom> + friend class RefPtr; + /** Default constructor * * Afterwards it will be null and use of -> will cause a segmentation fault. @@ -67,6 +72,15 @@ public: /// For use only in the internal implementation of sharedptr. explicit inline RefPtr(T_CppObject* pCppObject, int* refcount); + /** Move constructor + */ + inline RefPtr(RefPtr&& src); + + /** Move constructor (from different, but castable type). + */ + template <class T_CastFrom> + inline RefPtr(RefPtr<T_CastFrom>&& src); + /** Copy constructor * * This increments the shared reference count. @@ -97,6 +111,13 @@ public: template <class T_CastFrom> inline RefPtr<T_CppObject>& operator=(const RefPtr<T_CastFrom>& src); + /// Move assignment operator: + inline RefPtr& operator=(RefPtr&& src); + + /// Move assignment operator (from different, but castable type): + template <class T_CastFrom> + inline RefPtr& operator=(RefPtr<T_CastFrom>&& src); + /// Tests whether the RefPtr<> point to the same underlying instance. inline bool operator==(const RefPtr<T_CppObject>& src) const; @@ -251,6 +272,28 @@ RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CppObject>& src) ++(*pCppRefcount_); } +template <class T_CppObject> inline +RefPtr<T_CppObject>::RefPtr(RefPtr&& src) +: + pCppObject_ (src.pCppObject_), + pCppRefcount_ (src.pCppRefcount_) +{ + src.pCppObject_ = nullptr; + src.pCppRefcount_ = nullptr; +} + +template <class T_CppObject> + template <class T_CastFrom> +inline +RefPtr<T_CppObject>::RefPtr(RefPtr<T_CastFrom>&& src) +: + pCppObject_ (src.pCppObject_), + pCppRefcount_ (src.pCppRefcount_) +{ + src.pCppObject_ = nullptr; + src.pCppRefcount_ = nullptr; +} + // The templated ctor allows copy construction from any object that's // castable. Thus, it does downcasts: // base_ref = derived_ref @@ -259,7 +302,8 @@ template <class T_CppObject> inline RefPtr<T_CppObject>::RefPtr(const RefPtr<T_CastFrom>& src) : - // A different RefPtr<> will not allow us access to pCppObject_. We need + // Without the friend delaration, + // a different RefPtr<> will not allow us access to pCppObject_. We need // to add a get_underlying() for this, but that would encourage incorrect // use, so we use the less well-known operator->() accessor: pCppObject_ (src.operator->()), @@ -314,6 +358,30 @@ RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(const RefPtr<T_CppObject>& s return *this; } +template <class T_CppObject> inline +RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(RefPtr&& src) +{ + RefPtr<T_CppObject> temp (std::move(src)); + this->swap(temp); + src.pCppObject_ = nullptr; + src.pCppRefcount_ = nullptr; + + return *this; +} + +template <class T_CppObject> + template <class T_CastFrom> +inline +RefPtr<T_CppObject>& RefPtr<T_CppObject>::operator=(RefPtr<T_CastFrom>&& src) +{ + RefPtr<T_CppObject> temp (std::move(src)); + this->swap(temp); + src.pCppObject_ = nullptr; + src.pCppRefcount_ = nullptr; + + return *this; +} + template <class T_CppObject> template <class T_CastFrom> inline |