-#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>
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
*/
- IntrusivePtr( T* p ) : mPtr( p )
+ IntrusivePtr(T* p)
+ : mPtr(p)
{
- if( mPtr )
+ if(mPtr)
{
mPtr->Reference();
}
* @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();
}
* @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.
*/
~IntrusivePtr()
{
- if( mPtr )
+ if(mPtr)
{
mPtr->Unreference();
}
* @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;
}
* @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;
}
*/
void Reset()
{
- IntrusivePtr().Swap( *this );
+ IntrusivePtr().Swap(*this);
}
/**
* @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;
}
/**
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
};
/**
* @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();
}
* @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();
}
* @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;
}
* @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;
}
* @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();
}
* @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