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