Merge "(Partial Update) Mark as not rendered if the node is transparent or culled...
[platform/core/uifw/dali-core.git] / dali / public-api / common / intrusive-ptr.h
1 #ifndef DALI_INTRUSIVE_PTR_H
2 #define DALI_INTRUSIVE_PTR_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23
24 namespace Dali
25 {
26 /**
27  * @addtogroup dali_core_common
28  * @{
29  */
30
31 /**
32  * @brief Templated intrusive pointer class.
33  *
34  * Uses the Dali:RefObject type with actual reference counting.
35  * The object is responsible for destroying itself.
36  * @SINCE_1_0.0
37  */
38 template<typename T>
39 class IntrusivePtr
40 {
41 public:
42   /**
43    * @brief Standard constructor to unassigned object.
44    * @SINCE_1_0.0
45    */
46   IntrusivePtr()
47   : mPtr(nullptr)
48   {
49   }
50
51   /**
52    * @brief Constructor to attach existing object.
53    *
54    * @SINCE_1_0.0
55    * @param[in] p Pointer to object
56    */
57   IntrusivePtr(T* p)
58   : mPtr(p)
59   {
60     if(mPtr)
61     {
62       mPtr->Reference();
63     }
64   }
65
66   /**
67    * @brief Copy constructor.
68    *
69    * @SINCE_1_0.0
70    * @param[in] rhs Const reference to an IntrusivePtr
71    * @tparam U Reference counter object type
72    */
73   template<typename U>
74   IntrusivePtr(IntrusivePtr<U> const& rhs)
75   : mPtr(rhs.Get())
76   {
77     if(mPtr)
78     {
79       mPtr->Reference();
80     }
81   }
82
83   /**
84    * @brief Copy constructor.
85    * @SINCE_1_0.0
86    * @param[in] rhs Const reference to an IntrusivePtr
87    */
88   IntrusivePtr(IntrusivePtr const& rhs)
89   : mPtr(rhs.mPtr)
90   {
91     if(mPtr)
92     {
93       mPtr->Reference();
94     }
95   }
96
97   /**
98    * @brief Move constructor.
99    * @SINCE_1_9.23
100    * @param[in] rhs Reference to an IntrusivePtr
101    */
102   template<typename U>
103   IntrusivePtr(IntrusivePtr<U>&& rhs)
104   : mPtr(rhs.Detach())
105   {
106   }
107
108   /**
109    * @brief Move constructor.
110    * @SINCE_1_9.23
111    * @param[in] rhs Reference to an IntrusivePtr
112    */
113   IntrusivePtr(IntrusivePtr&& rhs)
114   : mPtr(rhs.Detach())
115   {
116   }
117
118   /**
119    * @brief Destructor.
120    *
121    * Object will self-destruct if reference count is zero.
122    * @SINCE_1_0.0
123    */
124   ~IntrusivePtr()
125   {
126     if(mPtr)
127     {
128       mPtr->Unreference();
129     }
130   }
131
132   /**
133    * @brief Gets pointer to reference counted object.
134    *
135    * @SINCE_1_0.0
136    * @return Pointer to reference counted object
137    */
138   T* Get() const
139   {
140     return mPtr;
141   }
142
143   /**
144    * @brief Pointer operator override.
145    *
146    * @SINCE_1_0.0
147    * @return Pointer to reference counted object
148    */
149   T* operator->() const
150   {
151     return mPtr;
152   }
153
154   /**
155    * @brief Dereference operator override.
156    *
157    * @SINCE_1_0.0
158    * @return Reference to reference counted object
159    */
160   T& operator*() const
161   {
162     return *mPtr;
163   }
164
165   /**
166    * @brief Assignment operator.
167    *
168    * @SINCE_1_0.0
169    * @param rhs Const reference to intrusive pointer
170    * @return Reference to reference counted object
171    */
172   IntrusivePtr& operator=(IntrusivePtr const& rhs)
173   {
174     IntrusivePtr(rhs).Swap(*this);
175     return *this;
176   }
177
178   /**
179    * @brief Assignment operator.
180    *
181    * @SINCE_1_0.0
182    * @param rhs Pointer to object to wrap
183    * @return A Reference to this object
184    */
185   IntrusivePtr& operator=(T* rhs)
186   {
187     IntrusivePtr(rhs).Swap(*this);
188     return *this;
189   }
190
191   /**
192    * @brief Move assignment operator.
193    *
194    * @SINCE_1_9.23
195    * @param rhs Reference to intrusive pointer
196    * @return Reference to moved intrusive pointer
197    */
198   IntrusivePtr& operator=(IntrusivePtr&& rhs)
199   {
200     if(this != &rhs)
201     {
202       if(mPtr)
203       {
204         mPtr->Unreference();
205       }
206       mPtr = rhs.Detach();
207     }
208
209     return *this;
210   }
211
212   /**
213    * @brief Move assignment operator.
214    *
215    * @SINCE_1_9.23
216    * @param rhs Reference to intrusive pointer
217    * @return Reference to moved intrusive pointer
218    */
219   template<typename U>
220   IntrusivePtr& operator=(IntrusivePtr<U>&& rhs)
221   {
222     if(this != reinterpret_cast<IntrusivePtr<T>*>(&rhs))
223     {
224       if(mPtr)
225       {
226         mPtr->Unreference();
227       }
228       mPtr = rhs.Detach();
229     }
230
231     return *this;
232   }
233
234   /**
235    * @brief Reset intrusive pointer.
236    * @SINCE_1_0.0
237    */
238   void Reset()
239   {
240     IntrusivePtr().Swap(*this);
241   }
242
243   /**
244    * @brief Reset intrusive pointer with reference counted object.
245    *
246    * @SINCE_1_0.0
247    * @param[in] rhs Pointer to object
248    */
249   void Reset(T* rhs)
250   {
251     IntrusivePtr(rhs).Swap(*this);
252   }
253
254   // IntrusivePtr comparisons
255
256   /**
257    * @brief Converts an object handle to a bool.
258    *
259    * This is useful for checking whether the handle is NULL.
260    * @SINCE_1_0.0
261    */
262   explicit operator bool() const
263   {
264     return mPtr != nullptr;
265   }
266
267   /**
268    * @brief Detaches pointer from intrusive ptr counting.
269    *
270    * Use with care.
271    * @SINCE_1_0.0
272    * @return Pointer to reference counted object
273    */
274   T* Detach()
275   {
276     T* ptr = mPtr;
277     mPtr   = nullptr;
278     return ptr;
279   }
280
281 private:
282   /**
283    * @brief Internal swap function.
284    * @SINCE_1_0.0
285    */
286   void Swap(IntrusivePtr& rhs)
287   {
288     T* tmp   = mPtr;
289     mPtr     = rhs.mPtr;
290     rhs.mPtr = tmp;
291   }
292
293   T* mPtr; ///< pointer to RefObject
294 };
295
296 /**
297  * @brief Comparison overrides of objects wrapped by intrusive pointers.
298  *
299  * @SINCE_1_0.0
300  * @param[in] lhs Intrusive pointer to compare with
301  * @param[in] rhs Intrusive pointer to compare against
302  * @return True if the pointers point at the same object
303  */
304 template<typename T, typename U>
305 inline bool operator==(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs)
306 {
307   return lhs.Get() == rhs.Get();
308 }
309
310 /**
311  * @brief Comparison overrides of objects wrapped by intrusive pointers.
312  *
313  * @SINCE_1_0.0
314  * @param[in] lhs Intrusive pointer to compare with
315  * @param[in] rhs Intrusive pointer to compare against
316  * @return True if the pointers point at different objects
317  */
318 template<typename T, typename U>
319 inline bool operator!=(IntrusivePtr<T> const& lhs, IntrusivePtr<U> const& rhs)
320 {
321   return lhs.Get() != rhs.Get();
322 }
323
324 /**
325  * @brief Comparison overrides of objects wrapped by intrusive pointers.
326  *
327  * @SINCE_1_0.0
328  * @param[in] lhs Intrusive pointer to compare with
329  * @param[in] rhs Object to compare against
330  * @return True if the intrusive pointer points at the specified object
331  */
332 template<typename T, typename U>
333 inline bool operator==(IntrusivePtr<T> const& lhs, U* rhs)
334 {
335   return lhs.Get() == rhs;
336 }
337
338 /**
339  * @brief Comparison overrides of objects wrapped by intrusive pointers.
340  *
341  * @SINCE_1_0.0
342  * @param[in] lhs Intrusive pointer to compare with
343  * @param[in] rhs Intrusive pointer to compare against
344  * @return True if the intrusive pointer doesn't point at the specified object
345  */
346 template<typename T, typename U>
347 inline bool operator!=(IntrusivePtr<T> const& lhs, U* rhs)
348 {
349   return lhs.Get() != rhs;
350 }
351
352 /**
353  * @brief Comparison overrides of objects wrapped by intrusive pointers.
354  *
355  * @SINCE_1_0.0
356  * @param[in] lhs Object to compare with
357  * @param[in] rhs Intrusive pointer to compare against
358  * @return True if the intrusive pointer points at the specified object
359  */
360 template<typename T, typename U>
361 inline bool operator==(T* lhs, IntrusivePtr<U> const& rhs)
362 {
363   return lhs == rhs.Get();
364 }
365
366 /**
367  * @brief Comparison overrides of objects wrapped by intrusive pointers.
368  *
369  * @SINCE_1_0.0
370  * @param[in] lhs Object to compare with
371  * @param[in] rhs Intrusive pointer to compare against
372  * @return True if the intrusive pointer doesn't point at the specified object
373  */
374 template<typename T, typename U>
375 inline bool operator!=(T* lhs, IntrusivePtr<U> const& rhs)
376 {
377   return lhs != rhs.Get();
378 }
379
380 /**
381  * @}
382  */
383 } // namespace Dali
384
385 #endif // DALI_INTRUSIVE_PTR_H