Make Dali::InstrusivePtr able to compare with nullptr
[platform/core/uifw/dali-core.git] / dali / public-api / common / intrusive-ptr.h
index 873a998..c962338 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTRUSIVE_PTR_H
 
 /*
- * Copyright (c) 2020 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>
 
@@ -38,14 +41,15 @@ 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.
@@ -53,9 +57,10 @@ public:
    * @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();
     }
@@ -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,9 +88,10 @@ 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();
     }
@@ -96,8 +103,8 @@ public:
    * @param[in] rhs Reference to an IntrusivePtr
    */
   template<typename U>
-  IntrusivePtr( IntrusivePtr<U>&& rhs )
-  : mPtr( rhs.Detach() )
+  IntrusivePtr(IntrusivePtr<U>&& rhs)
+  : mPtr(rhs.Detach())
   {
   }
 
@@ -106,8 +113,8 @@ public:
    * @SINCE_1_9.23
    * @param[in] rhs Reference to an IntrusivePtr
    */
-  IntrusivePtr( IntrusivePtr&& rhs )
-  : mPtr( rhs.Detach() )
+  IntrusivePtr(IntrusivePtr&& rhs)
+  : mPtr(rhs.Detach())
   {
   }
 
@@ -119,7 +126,7 @@ public:
    */
   ~IntrusivePtr()
   {
-    if( mPtr )
+    if(mPtr)
     {
       mPtr->Unreference();
     }
@@ -165,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;
   }
 
@@ -178,9 +185,9 @@ 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;
   }
 
@@ -191,11 +198,11 @@ public:
    * @param rhs Reference to intrusive pointer
    * @return Reference to moved intrusive pointer
    */
-  IntrusivePtr& operator=( IntrusivePtr&& rhs )
+  IntrusivePtr& operator=(IntrusivePtr&& rhs)
   {
-    if ( this != &rhs )
+    if(this != &rhs)
     {
-      if (mPtr)
+      if(mPtr)
       {
         mPtr->Unreference();
       }
@@ -213,11 +220,11 @@ public:
    * @return Reference to moved intrusive pointer
    */
   template<typename U>
-  IntrusivePtr& operator=( IntrusivePtr<U>&& rhs )
+  IntrusivePtr& operator=(IntrusivePtr<U>&& rhs)
   {
-    if ( this != reinterpret_cast<IntrusivePtr<T>*>( &rhs ) )
+    if(this != reinterpret_cast<IntrusivePtr<T>*>(&rhs))
     {
-      if (mPtr)
+      if(mPtr)
       {
         mPtr->Unreference();
       }
@@ -233,7 +240,7 @@ public:
    */
   void Reset()
   {
-    IntrusivePtr().Swap( *this );
+    IntrusivePtr().Swap(*this);
   }
 
   /**
@@ -242,29 +249,22 @@ 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;
   }
 
   /**
@@ -277,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.
    * @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
 };
 
 /**
@@ -312,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();
 }
@@ -326,7 +319,7 @@ 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();
 }
@@ -340,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;
 }
@@ -354,7 +347,7 @@ 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;
 }
@@ -368,7 +361,7 @@ 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();
 }
@@ -382,12 +375,68 @@ 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