[dali_1.1.21] Merge branch 'devel/master'
[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) 2015 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
42 public:
43
44   /**
45    * @brief Standard constructor to unassigned object.
46    * @SINCE_1_0.0
47    */
48   IntrusivePtr() : mPtr( 0 ) {}
49
50   /**
51    * @brief Constructor to attach existing object.
52    *
53    * @SINCE_1_0.0
54    * @param[in] p Pointer to object,
55    */
56   IntrusivePtr( T* p ) : mPtr( p )
57   {
58     if( mPtr )
59     {
60       mPtr->Reference();
61     }
62   }
63
64   /**
65    * @brief Copy constructor.
66    *
67    * @SINCE_1_0.0
68    * @param[in] rhs Const reference to an IntrusivePtr
69    * @tparam U Reference counter object type
70    */
71   template<typename U>
72   IntrusivePtr( IntrusivePtr<U> const& rhs ) : mPtr( rhs.Get() )
73   {
74     if( mPtr )
75     {
76       mPtr->Reference();
77     }
78   }
79
80   /**
81    * @brief Copy constructor.
82    * @SINCE_1_0.0
83    */
84   IntrusivePtr( IntrusivePtr const& rhs ) : mPtr( rhs.mPtr )
85   {
86     if( mPtr )
87     {
88       mPtr->Reference();
89     }
90   }
91
92   /**
93    * @brief Destructor.
94    *
95    * Object will self-destruct if reference count is zero
96    * @SINCE_1_0.0
97    */
98   ~IntrusivePtr()
99   {
100     if( mPtr )
101     {
102       mPtr->Unreference();
103     }
104   }
105
106   /**
107    * @brief Get pointer to reference counted object.
108    *
109    * @SINCE_1_0.0
110    * @return Pointer to reference counted object
111    */
112   T* Get() const
113   {
114     return mPtr;
115   }
116
117   /**
118    * @brief Pointer operator override.
119    *
120    * @SINCE_1_0.0
121    * @return Pointer to reference counted object
122    */
123   T* operator->() const
124   {
125     return mPtr;
126   }
127
128   /**
129    * @brief Dereference operator override.
130    *
131    * @SINCE_1_0.0
132    * @return Reference to reference counted object
133    */
134   T& operator*() const
135   {
136     return *mPtr;
137   }
138
139   /**
140    * @brief Assignment operator.
141    *
142    * @SINCE_1_0.0
143    * @param rhs Const reference to intrusive pointer
144    * @return Reference to reference counted object
145    */
146   IntrusivePtr& operator=( IntrusivePtr const& rhs )
147   {
148     IntrusivePtr( rhs ).Swap( *this );
149     return *this;
150   }
151
152   /**
153    * @brief Assignment operator.
154    *
155    * @SINCE_1_0.0
156    * @param rhs Pointer to object to wrap
157    * @return A Reference to this object
158    */
159   IntrusivePtr& operator=( T* rhs )
160   {
161     IntrusivePtr( rhs ).Swap( *this );
162     return *this;
163   }
164
165   /**
166    * @brief Reset intrusive pointer.
167    * @SINCE_1_0.0
168    */
169   void Reset()
170   {
171     IntrusivePtr().Swap( *this );
172   }
173
174   /**
175    * @brief Reset intrusive pointer with reference counted object.
176    *
177    * @SINCE_1_0.0
178    * @param[in] rhs Pointer to object
179    */
180   void Reset( T* rhs )
181   {
182     IntrusivePtr( rhs ).Swap( *this );
183   }
184
185   // IntrusivePtr comparisons - This is a variation of the safe bool idiom
186
187   /**
188    * @brief Pointer-to-member type.
189    *
190    * Objects can be implicitly converted to this for validity checks.
191    */
192   typedef void (IntrusivePtr::*BooleanType)() const;
193
194   /**
195    * @brief Converts an object handle to a BooleanType.
196    *
197    * This is useful for checking whether the handle is NULL.
198    * @SINCE_1_0.0
199    */
200   operator BooleanType() const
201   {
202     return mPtr ? &IntrusivePtr::ThisIsSaferThanReturningVoidStar : 0;
203   }
204
205   /**
206    * @brief Detach pointer from intrusive ptr counting.
207    *
208    * Use with care.
209    * @SINCE_1_0.0
210    */
211   T* Detach()
212   {
213     T* ptr = mPtr;
214     mPtr = 0;
215     return ptr;
216   }
217
218 private:
219
220   /**
221    * @brief Used by the safe bool idiom.
222    * @SINCE_1_0.0
223    */
224   void ThisIsSaferThanReturningVoidStar() const {}
225
226   /**
227    * @brief Internal swap function
228    * @SINCE_1_0.0
229    */
230   void Swap( IntrusivePtr& rhs )
231   {
232     T* tmp = mPtr;
233     mPtr = rhs.mPtr;
234     rhs.mPtr = tmp;
235   }
236
237   T* mPtr;  ///< pointer to RefObject
238 };
239
240 /**
241  * @brief Comparison overrides of objects wrapped by intrusive pointers.
242  *
243  * @SINCE_1_0.0
244  * @param[in] lhs Intrusive pointer to compare with
245  * @param[in] rhs Intrusive pointer to compare against
246  * @return True if the pointers point at the same object
247  */
248 template<typename T, typename U>
249 inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
250 {
251   return lhs.Get() == rhs.Get();
252 }
253
254 /**
255  * @brief Comparison overrides of objects wrapped by intrusive pointers.
256  *
257  * @SINCE_1_0.0
258  * @param[in] lhs Intrusive pointer to compare with
259  * @param[in] rhs Intrusive pointer to compare against
260  * @return True if the pointers point at different objects
261  */
262 template<typename T, typename U>
263 inline bool operator!=( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const &rhs)
264 {
265   return lhs.Get() != rhs.Get();
266 }
267
268 /**
269  * @brief Comparison overrides of objects wrapped by intrusive pointers
270  *
271  * @SINCE_1_0.0
272  * @param[in] lhs Intrusive pointer to compare with
273  * @param[in] rhs Object to compare against
274  * @return True if the intrusive pointer points at the specified object
275  */
276 template<typename T, typename U>
277 inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
278 {
279   return lhs.Get() == rhs;
280 }
281
282 /**
283  * @brief Comparison overrides of objects wrapped by intrusive pointers.
284  *
285  * @SINCE_1_0.0
286  * @param[in] lhs Intrusive pointer to compare with
287  * @param[in] rhs Intrusive pointer to compare against
288  * @return True if the intrusive pointer doesn't point at the specified object
289  */
290 template<typename T, typename U>
291 inline bool operator!=( IntrusivePtr<T>const& lhs, U* rhs )
292 {
293   return lhs.Get() != rhs;
294 }
295
296 /**
297  * @brief Comparison overrides of objects wrapped by intrusive pointers
298  *
299  * @SINCE_1_0.0
300  * @param[in] lhs Object to compare with
301  * @param[in] rhs Intrusive pointer to compare against
302  * @return True if the intrusive pointer points at the specified object
303  */
304 template<typename T, typename U>
305 inline bool operator==( T* lhs, IntrusivePtr<U>const& rhs )
306 {
307   return lhs == 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 Object to compare with
315  * @param[in] rhs Intrusive pointer to compare against
316  * @return True if the intrusive pointer doesn't point at the specified object
317  */
318 template<typename T, typename U>
319 inline bool operator!=( T* lhs, IntrusivePtr<U>const& rhs )
320 {
321   return lhs != rhs.Get();
322 }
323
324 /**
325  * @}
326  */
327 } // namespace Dali
328
329 #endif /* __DALI_INTRUSIVE_PTR_H__ */