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