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