-#ifndef __DALI_INTRUSIVE_PTR_H__
-#define __DALI_INTRUSIVE_PTR_H__
+#ifndef DALI_INTRUSIVE_PTR_H
+#define DALI_INTRUSIVE_PTR_H
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
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();
}
/**
* @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();
}
/**
* @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
{
/**
* @brief Pointer operator override.
*
- * @return pointer to reference counted object
+ * @SINCE_1_0.0
+ * @return Pointer to reference counted object
*/
T* operator->() const
{
/**
* @brief Dereference operator override.
*
- * @return reference to reference counted object
+ * @SINCE_1_0.0
+ * @return Reference to reference counted object
*/
T& operator*() const
{
/**
* @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;
}
-private:
-
/**
- * @brief Used by the safe bool idiom.
+ * @brief Detaches pointer from intrusive ptr counting.
+ *
+ * Use with care.
+ * @SINCE_1_0.0
+ * @return Pointer to reference counted object
*/
- void ThisIsSaferThanReturningVoidStar() const {}
+ T* Detach()
+ {
+ T* ptr = mPtr;
+ mPtr = nullptr;
+ return ptr;
+ }
+private:
/**
- * @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();
}
/**
* @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;
}
/**
* @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();
}
+/**
+ * @}
+ */
} // namespace Dali
-#endif /* __DALI_INTRUSIVE_PTR_H__ */
+#endif // DALI_INTRUSIVE_PTR_H