Make Dali::InstrusivePtr able to compare with nullptr
[platform/core/uifw/dali-core.git] / dali / public-api / common / intrusive-ptr.h
index 13a36e6..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.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <cstddef> // for std::nullptr_t
+
 // INTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 
 namespace Dali
 {
+/**
+ * @addtogroup dali_core_common
+ * @{
+ */
 
 /**
- * @brief Templated intrusive pointer class
+ * @brief Templated intrusive pointer class.
  *
- * Uses the Dali:Refobject type supply actual reference counting
- * The object is responsible for destroying itself
+ * Uses the Dali:RefObject type with actual reference counting.
+ * The object is responsible for destroying itself.
+ * @SINCE_1_0.0
  */
 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.
    *
-   * @param p pointer to object,
+   * @SINCE_1_0.0
+   * @param[in] p Pointer to object
    */
-  IntrusivePtr( T* p ) : mPtr( p )
+  IntrusivePtr(T* p)
+  : mPtr(p)
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Reference();
     }
@@ -57,13 +69,15 @@ public:
   /**
    * @brief Copy constructor.
    *
-   * @param rhs const reference to an IntrusivePtr
-   * @tparam U reference counter object type
+   * @SINCE_1_0.0
+   * @param[in] rhs Const reference to an IntrusivePtr
+   * @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();
     }
@@ -71,32 +85,58 @@ public:
 
   /**
    * @brief Copy constructor.
+   * @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.
    *
-   * @return pointer to reference counted object
+   * @SINCE_1_0.0
+   * @return Pointer to reference counted object
    */
   T* Get() const
   {
@@ -106,7 +146,8 @@ public:
   /**
    * @brief Pointer operator override.
    *
-   * @return pointer to reference counted object
+   * @SINCE_1_0.0
+   * @return Pointer to reference counted object
    */
   T* operator->() const
   {
@@ -116,7 +157,8 @@ public:
   /**
    * @brief Dereference operator override.
    *
-   * @return reference to reference counted object
+   * @SINCE_1_0.0
+   * @return Reference to reference counted object
    */
   T& operator*() const
   {
@@ -126,105 +168,144 @@ public:
   /**
    * @brief Assignment operator.
    *
-   * @param rhs const reference to intrusive pointer
-   * @return reference to reference counted object
+   * @SINCE_1_0.0
+   * @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;
   }
 
   /**
    * @brief Assignment operator.
    *
-   * @param rhs pointer to object to wrap
-   * @return A reference to this object
+   * @SINCE_1_0.0
+   * @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 Reset intrusive pointer.
+   * @brief Move assignment operator.
+   *
+   * @SINCE_1_9.23
+   * @param rhs Reference to intrusive pointer
+   * @return Reference to moved intrusive pointer
    */
-  void Reset()
+  IntrusivePtr& operator=(IntrusivePtr&& rhs)
   {
-    IntrusivePtr().Swap( *this );
+    if(this != &rhs)
+    {
+      if(mPtr)
+      {
+        mPtr->Unreference();
+      }
+      mPtr = rhs.Detach();
+    }
+
+    return *this;
   }
 
   /**
-   * @brief Reset intrusive pointer with reference counted object.
+   * @brief Move assignment operator.
    *
-   * @param rhs pointer to object
+   * @SINCE_1_9.23
+   * @param rhs Reference to intrusive pointer
+   * @return Reference to moved intrusive pointer
    */
-  void Reset( T* rhs )
+  template<typename U>
+  IntrusivePtr& operator=(IntrusivePtr<U>&& rhs)
   {
-    IntrusivePtr( rhs ).Swap( *this );
+    if(this != reinterpret_cast<IntrusivePtr<T>*>(&rhs))
+    {
+      if(mPtr)
+      {
+        mPtr->Unreference();
+      }
+      mPtr = rhs.Detach();
+    }
+
+    return *this;
   }
 
-  // IntrusivePtr comparisons - This is a variation of the safe bool idiom
+  /**
+   * @brief Reset intrusive pointer.
+   * @SINCE_1_0.0
+   */
+  void Reset()
+  {
+    IntrusivePtr().Swap(*this);
+  }
 
   /**
-   * @brief Pointer-to-member type.
+   * @brief Reset intrusive pointer with reference counted object.
    *
-   * Objects can be implicitly converted to this for validity checks.
+   * @SINCE_1_0.0
+   * @param[in] rhs Pointer to object
    */
-  typedef void (IntrusivePtr::*BooleanType)() const;
+  void Reset(T* rhs)
+  {
+    IntrusivePtr(rhs).Swap(*this);
+  }
+
+  // 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
+   * @return Pointer to reference counted object
    */
   T* Detach()
   {
     T* ptr = mPtr;
-    mPtr = 0;
+    mPtr   = nullptr;
     return ptr;
   }
 
 private:
-
-  /**
-   * @brief Used by the safe bool idiom.
-   */
-  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
 };
 
 /**
  * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
- * @param lhs intrusive pointer to compare with
- * @param rhs intrusive pointer to compare against
- * @return true if the pointers point at the same object
+ * @SINCE_1_0.0
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs Intrusive pointer to compare against
+ * @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();
 }
@@ -232,25 +313,27 @@ inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
 /**
  * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
- * @param lhs intrusive pointer to compare with
- * @param rhs intrusive pointer to compare against
- * @return true if the pointers point at different objects
+ * @SINCE_1_0.0
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs Intrusive pointer to compare against
+ * @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.
  *
- * @param lhs intrusive pointer to compare with
- * @param rhs object to compare against
- * @return true if the intrusive pointer points at the specified object
+ * @SINCE_1_0.0
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs Object to compare against
+ * @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;
 }
@@ -258,42 +341,104 @@ inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
 /**
  * @brief Comparison overrides of objects wrapped by intrusive pointers.
  *
- * @param lhs intrusive pointer to compare with
- * @param rhs intrusive pointer to compare against
- * @return true if the intrusive pointer doesn't point at the specified object
+ * @SINCE_1_0.0
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs Intrusive pointer to compare against
+ * @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.
  *
- * @param lhs object to compare with
- * @param rhs intrusive pointer to compare against
- * @return true if the intrusive pointer points at the specified object
+ * @SINCE_1_0.0
+ * @param[in] lhs Object to compare with
+ * @param[in] rhs Intrusive pointer to compare against
+ * @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.
  *
- * @param lhs object to compare with
- * @param rhs intrusive pointer to compare against
- * @return true if the intrusive pointer doesn't point at the specified object
+ * @SINCE_1_0.0
+ * @param[in] lhs Object to compare with
+ * @param[in] rhs Intrusive pointer to compare against
+ * @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