1 #ifndef DALI_INTRUSIVE_PTR_H
2 #define DALI_INTRUSIVE_PTR_H
5 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/public-api/common/dali-common.h>
27 * @addtogroup dali_core_common
32 * @brief Templated intrusive pointer class.
34 * Uses the Dali:RefObject type with actual reference counting.
35 * The object is responsible for destroying itself.
45 * @brief Standard constructor to unassigned object.
48 IntrusivePtr() : mPtr( nullptr ) {}
51 * @brief Constructor to attach existing object.
54 * @param[in] p Pointer to object
56 IntrusivePtr( T* p ) : mPtr( p )
65 * @brief Copy constructor.
68 * @param[in] rhs Const reference to an IntrusivePtr
69 * @tparam U Reference counter object type
72 IntrusivePtr( IntrusivePtr<U> const& rhs ) : mPtr( rhs.Get() )
81 * @brief Copy constructor.
83 * @param[in] rhs Const reference to an IntrusivePtr
85 IntrusivePtr( IntrusivePtr const& rhs ) : mPtr( rhs.mPtr )
94 * @brief Move constructor.
96 * @param[in] rhs Reference to an IntrusivePtr
99 IntrusivePtr( IntrusivePtr<U>&& rhs )
100 : mPtr( rhs.Detach() )
105 * @brief Move constructor.
107 * @param[in] rhs Reference to an IntrusivePtr
109 IntrusivePtr( IntrusivePtr&& rhs )
110 : mPtr( rhs.Detach() )
117 * Object will self-destruct if reference count is zero.
129 * @brief Gets pointer to reference counted object.
132 * @return Pointer to reference counted object
140 * @brief Pointer operator override.
143 * @return Pointer to reference counted object
145 T* operator->() const
151 * @brief Dereference operator override.
154 * @return Reference to reference counted object
162 * @brief Assignment operator.
165 * @param rhs Const reference to intrusive pointer
166 * @return Reference to reference counted object
168 IntrusivePtr& operator=( IntrusivePtr const& rhs )
170 IntrusivePtr( rhs ).Swap( *this );
175 * @brief Assignment operator.
178 * @param rhs Pointer to object to wrap
179 * @return A Reference to this object
181 IntrusivePtr& operator=( T* rhs )
183 IntrusivePtr( rhs ).Swap( *this );
188 * @brief Move assignment operator.
191 * @param rhs Reference to intrusive pointer
192 * @return Reference to moved intrusive pointer
194 IntrusivePtr& operator=( IntrusivePtr&& rhs )
209 * @brief Move assignment operator.
212 * @param rhs Reference to intrusive pointer
213 * @return Reference to moved intrusive pointer
216 IntrusivePtr& operator=( IntrusivePtr<U>&& rhs )
218 if ( this != reinterpret_cast<IntrusivePtr<T>*>( &rhs ) )
231 * @brief Reset intrusive pointer.
236 IntrusivePtr().Swap( *this );
240 * @brief Reset intrusive pointer with reference counted object.
243 * @param[in] rhs Pointer to object
247 IntrusivePtr( rhs ).Swap( *this );
250 // IntrusivePtr comparisons - This is a variation of the safe bool idiom
253 * @brief Pointer-to-member type.
255 * Objects can be implicitly converted to this for validity checks.
257 using BooleanType = void ( IntrusivePtr<T>::* )() const;
260 * @brief Converts an object handle to a BooleanType.
262 * This is useful for checking whether the handle is NULL.
265 operator BooleanType() const
267 return mPtr ? &IntrusivePtr::ThisIsSaferThanReturningVoidStar : nullptr;
271 * @brief Detaches pointer from intrusive ptr counting.
275 * @return Pointer to reference counted object
287 * @brief Used by the safe bool idiom.
290 void ThisIsSaferThanReturningVoidStar() const {}
293 * @brief Internal swap function.
296 void Swap( IntrusivePtr& rhs )
303 T* mPtr; ///< pointer to RefObject
307 * @brief Comparison overrides of objects wrapped by intrusive pointers.
310 * @param[in] lhs Intrusive pointer to compare with
311 * @param[in] rhs Intrusive pointer to compare against
312 * @return True if the pointers point at the same object
314 template<typename T, typename U>
315 inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
317 return lhs.Get() == rhs.Get();
321 * @brief Comparison overrides of objects wrapped by intrusive pointers.
324 * @param[in] lhs Intrusive pointer to compare with
325 * @param[in] rhs Intrusive pointer to compare against
326 * @return True if the pointers point at different objects
328 template<typename T, typename U>
329 inline bool operator!=( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const &rhs)
331 return lhs.Get() != rhs.Get();
335 * @brief Comparison overrides of objects wrapped by intrusive pointers.
338 * @param[in] lhs Intrusive pointer to compare with
339 * @param[in] rhs Object to compare against
340 * @return True if the intrusive pointer points at the specified object
342 template<typename T, typename U>
343 inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
345 return lhs.Get() == rhs;
349 * @brief Comparison overrides of objects wrapped by intrusive pointers.
352 * @param[in] lhs Intrusive pointer to compare with
353 * @param[in] rhs Intrusive pointer to compare against
354 * @return True if the intrusive pointer doesn't point at the specified object
356 template<typename T, typename U>
357 inline bool operator!=( IntrusivePtr<T>const& lhs, U* rhs )
359 return lhs.Get() != rhs;
363 * @brief Comparison overrides of objects wrapped by intrusive pointers.
366 * @param[in] lhs Object to compare with
367 * @param[in] rhs Intrusive pointer to compare against
368 * @return True if the intrusive pointer points at the specified object
370 template<typename T, typename U>
371 inline bool operator==( T* lhs, IntrusivePtr<U>const& rhs )
373 return lhs == rhs.Get();
377 * @brief Comparison overrides of objects wrapped by intrusive pointers.
380 * @param[in] lhs Object to compare with
381 * @param[in] rhs Intrusive pointer to compare against
382 * @return True if the intrusive pointer doesn't point at the specified object
384 template<typename T, typename U>
385 inline bool operator!=( T* lhs, IntrusivePtr<U>const& rhs )
387 return lhs != rhs.Get();
395 #endif // DALI_INTRUSIVE_PTR_H