Make Dali::InstrusivePtr able to compare with nullptr
[platform/core/uifw/dali-core.git] / dali / public-api / common / intrusive-ptr.h
index e755202..c962338 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTRUSIVE_PTR_H__
-#define __DALI_INTRUSIVE_PTR_H__
+#ifndef DALI_INTRUSIVE_PTR_H
+#define DALI_INTRUSIVE_PTR_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <cstddef> // for std::nullptr_t
+
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 
@@ -29,7 +32,7 @@ namespace Dali
  */
 
 /**
- * @brief Templated intrusive pointer class
+ * @brief Templated intrusive pointer class.
  *
  * Uses the Dali:RefObject type with actual reference counting.
  * The object is responsible for destroying itself.
@@ -38,24 +41,26 @@ namespace Dali
 template<typename T>
 class IntrusivePtr
 {
-
 public:
-
   /**
    * @brief Standard constructor to unassigned object.
    * @SINCE_1_0.0
    */
-  IntrusivePtr() : mPtr( 0 ) {}
+  IntrusivePtr()
+  : mPtr(nullptr)
+  {
+  }
 
   /**
    * @brief Constructor to attach existing object.
    *
    * @SINCE_1_0.0
-   * @param[in] p Pointer to object,
+   * @param[in] p Pointer to object
    */
-  IntrusivePtr( T* p ) : mPtr( p )
+  IntrusivePtr(T* p)
+  : mPtr(p)
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Reference();
     }
@@ -69,9 +74,10 @@ public:
    * @tparam U Reference counter object type
    */
   template<typename U>
-  IntrusivePtr( IntrusivePtr<U> const& rhs ) : mPtr( rhs.Get() )
+  IntrusivePtr(IntrusivePtr<U> const& rhs)
+  : mPtr(rhs.Get())
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Reference();
     }
@@ -82,30 +88,52 @@ public:
    * @SINCE_1_0.0
    * @param[in] rhs Const reference to an IntrusivePtr
    */
-  IntrusivePtr( IntrusivePtr const& rhs ) : mPtr( rhs.mPtr )
+  IntrusivePtr(IntrusivePtr const& rhs)
+  : mPtr(rhs.mPtr)
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Reference();
     }
   }
 
   /**
+   * @brief Move constructor.
+   * @SINCE_1_9.23
+   * @param[in] rhs Reference to an IntrusivePtr
+   */
+  template<typename U>
+  IntrusivePtr(IntrusivePtr<U>&& rhs)
+  : mPtr(rhs.Detach())
+  {
+  }
+
+  /**
+   * @brief Move constructor.
+   * @SINCE_1_9.23
+   * @param[in] rhs Reference to an IntrusivePtr
+   */
+  IntrusivePtr(IntrusivePtr&& rhs)
+  : mPtr(rhs.Detach())
+  {
+  }
+
+  /**
    * @brief Destructor.
    *
-   * Object will self-destruct if reference count is zero
+   * Object will self-destruct if reference count is zero.
    * @SINCE_1_0.0
    */
   ~IntrusivePtr()
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Unreference();
     }
   }
 
   /**
-   * @brief Get pointer to reference counted object.
+   * @brief Gets pointer to reference counted object.
    *
    * @SINCE_1_0.0
    * @return Pointer to reference counted object
@@ -144,9 +172,9 @@ public:
    * @param rhs Const reference to intrusive pointer
    * @return Reference to reference counted object
    */
-  IntrusivePtr& operator=( IntrusivePtr const& rhs )
+  IntrusivePtr& operator=(IntrusivePtr const& rhs)
   {
-    IntrusivePtr( rhs ).Swap( *this );
+    IntrusivePtr(rhs).Swap(*this);
     return *this;
   }
 
@@ -157,9 +185,52 @@ public:
    * @param rhs Pointer to object to wrap
    * @return A Reference to this object
    */
-  IntrusivePtr& operator=( T* rhs )
+  IntrusivePtr& operator=(T* rhs)
   {
-    IntrusivePtr( rhs ).Swap( *this );
+    IntrusivePtr(rhs).Swap(*this);
+    return *this;
+  }
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @SINCE_1_9.23
+   * @param rhs Reference to intrusive pointer
+   * @return Reference to moved intrusive pointer
+   */
+  IntrusivePtr& operator=(IntrusivePtr&& rhs)
+  {
+    if(this != &rhs)
+    {
+      if(mPtr)
+      {
+        mPtr->Unreference();
+      }
+      mPtr = rhs.Detach();
+    }
+
+    return *this;
+  }
+
+  /**
+   * @brief Move assignment operator.
+   *
+   * @SINCE_1_9.23
+   * @param rhs Reference to intrusive pointer
+   * @return Reference to moved intrusive pointer
+   */
+  template<typename U>
+  IntrusivePtr& operator=(IntrusivePtr<U>&& rhs)
+  {
+    if(this != reinterpret_cast<IntrusivePtr<T>*>(&rhs))
+    {
+      if(mPtr)
+      {
+        mPtr->Unreference();
+      }
+      mPtr = rhs.Detach();
+    }
+
     return *this;
   }
 
@@ -169,7 +240,7 @@ public:
    */
   void Reset()
   {
-    IntrusivePtr().Swap( *this );
+    IntrusivePtr().Swap(*this);
   }
 
   /**
@@ -178,33 +249,26 @@ public:
    * @SINCE_1_0.0
    * @param[in] rhs Pointer to object
    */
-  void Reset( T* rhs )
+  void Reset(T* rhs)
   {
-    IntrusivePtr( rhs ).Swap( *this );
+    IntrusivePtr(rhs).Swap(*this);
   }
 
-  // IntrusivePtr comparisons - This is a variation of the safe bool idiom
-
-  /**
-   * @brief Pointer-to-member type.
-   *
-   * Objects can be implicitly converted to this for validity checks.
-   */
-  typedef void (IntrusivePtr::*BooleanType)() const;
+  // IntrusivePtr comparisons
 
   /**
-   * @brief Converts an object handle to a BooleanType.
+   * @brief Converts an object handle to a bool.
    *
    * This is useful for checking whether the handle is NULL.
    * @SINCE_1_0.0
    */
-  operator BooleanType() const
+  explicit operator bool() const
   {
-    return mPtr ? &IntrusivePtr::ThisIsSaferThanReturningVoidStar : 0;
+    return mPtr != nullptr;
   }
 
   /**
-   * @brief Detach pointer from intrusive ptr counting.
+   * @brief Detaches pointer from intrusive ptr counting.
    *
    * Use with care.
    * @SINCE_1_0.0
@@ -213,30 +277,23 @@ public:
   T* Detach()
   {
     T* ptr = mPtr;
-    mPtr = 0;
+    mPtr   = nullptr;
     return ptr;
   }
 
 private:
-
-  /**
-   * @brief Used by the safe bool idiom.
-   * @SINCE_1_0.0
-   */
-  void ThisIsSaferThanReturningVoidStar() const {}
-
   /**
-   * @brief Internal swap function
+   * @brief Internal swap function.
    * @SINCE_1_0.0
    */
-  void Swap( IntrusivePtr& rhs )
+  void Swap(IntrusivePtr& rhs)
   {
-    T* tmp = mPtr;
-    mPtr = rhs.mPtr;
+    T* tmp   = mPtr;
+    mPtr     = rhs.mPtr;
     rhs.mPtr = tmp;
   }
 
-  T* mPtr;  ///< pointer to RefObject
+  T* mPtr; ///< pointer to RefObject
 };
 
 /**
@@ -248,7 +305,7 @@ private:
  * @return True if the pointers point at the same object
  */
 template<typename T, typename U>
-inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
+inline bool operator==(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs)
 {
   return lhs.Get() == rhs.Get();
 }
@@ -262,13 +319,13 @@ inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
  * @return True if the pointers point at different objects
  */
 template<typename T, typename U>
-inline bool operator!=( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const &rhs)
+inline bool operator!=(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs)
 {
   return lhs.Get() != rhs.Get();
 }
 
 /**
- * @brief Comparison overrides of objects wrapped by intrusive pointers
+ * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
  * @SINCE_1_0.0
  * @param[in] lhs Intrusive pointer to compare with
@@ -276,7 +333,7 @@ inline bool operator!=( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const &rhs)
  * @return True if the intrusive pointer points at the specified object
  */
 template<typename T, typename U>
-inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
+inline bool operator==(IntrusivePtr<T> const& lhs, U* rhs)
 {
   return lhs.Get() == rhs;
 }
@@ -290,13 +347,13 @@ inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
  * @return True if the intrusive pointer doesn't point at the specified object
  */
 template<typename T, typename U>
-inline bool operator!=( IntrusivePtr<T>const& lhs, U* rhs )
+inline bool operator!=(IntrusivePtr<T> const& lhs, U* rhs)
 {
   return lhs.Get() != rhs;
 }
 
 /**
- * @brief Comparison overrides of objects wrapped by intrusive pointers
+ * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
  * @SINCE_1_0.0
  * @param[in] lhs Object to compare with
@@ -304,13 +361,13 @@ inline bool operator!=( IntrusivePtr<T>const& lhs, U* rhs )
  * @return True if the intrusive pointer points at the specified object
  */
 template<typename T, typename U>
-inline bool operator==( T* lhs, IntrusivePtr<U>const& rhs )
+inline bool operator==(T* lhs, IntrusivePtr<U> const& rhs)
 {
   return lhs == rhs.Get();
 }
 
 /**
- * @brief Comparison overrides of objects wrapped by intrusive pointers
+ * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
  * @SINCE_1_0.0
  * @param[in] lhs Object to compare with
@@ -318,14 +375,70 @@ inline bool operator==( T* lhs, IntrusivePtr<U>const& rhs )
  * @return True if the intrusive pointer doesn't point at the specified object
  */
 template<typename T, typename U>
-inline bool operator!=( T* lhs, IntrusivePtr<U>const& rhs )
+inline bool operator!=(T* lhs, IntrusivePtr<U> const& rhs)
 {
   return lhs != rhs.Get();
 }
 
 /**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs nullptr
+ * @return True if the pointers is nullptr
+ */
+template<typename T>
+inline bool operator==(IntrusivePtr<T> const& lhs, std::nullptr_t rhs)
+{
+  return lhs.Get() == nullptr;
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs nullptr
+ * @return True if the pointers is not nullptr
+ */
+template<typename T>
+inline bool operator!=(IntrusivePtr<T> const& lhs, std::nullptr_t rhs)
+{
+  return lhs.Get() != nullptr;
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs nullptr
+ * @param[in] rhs Intrusive pointer to compare against
+ * @return True if the pointers is nullptr
+ */
+template<typename T>
+inline bool operator==(std::nullptr_t lhs, IntrusivePtr<T> const& rhs)
+{
+  return nullptr == rhs.Get();
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs nullptr
+ * @param[in] rhs Intrusive pointer to compare against
+ * @return True if the pointers is not nullptr
+ */
+template<typename T>
+inline bool operator!=(std::nullptr_t lhs, IntrusivePtr<T> const& rhs)
+{
+  return nullptr != rhs.Get();
+}
+
+/**
  * @}
  */
 } // namespace Dali
 
-#endif /* __DALI_INTRUSIVE_PTR_H__ */
+#endif // DALI_INTRUSIVE_PTR_H