[dali_1.0.28] 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 intrusive pointer class
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 override.
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>
215 inline bool operator==( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const& rhs )
216 {
217   return lhs.Get() == rhs.Get();
218 }
219
220 /**
221  * @brief Comparison overrides of objects wrapped by intrusive pointers.
222  *
223  * @param lhs intrusive pointer to compare with
224  * @param rhs intrusive pointer to compare against
225  * @return true if the pointers point at different objects
226  */
227 template<typename T, typename U>
228 inline bool operator!=( IntrusivePtr<T>const& lhs, IntrusivePtr<U>const &rhs)
229 {
230   return lhs.Get() != rhs.Get();
231 }
232
233 /**
234  * @brief Comparison overrides of objects wrapped by intrusive pointers
235  *
236  * @param lhs intrusive pointer to compare with
237  * @param rhs object to compare against
238  * @return true if the intrusive pointer points at the specified object
239  */
240 template<typename T, typename U>
241 inline bool operator==( IntrusivePtr<T>const& lhs, U* rhs )
242 {
243   return lhs.Get() == rhs;
244 }
245
246 /**
247  * @brief Comparison overrides of objects wrapped by intrusive pointers.
248  *
249  * @param lhs intrusive pointer to compare with
250  * @param rhs intrusive pointer to compare against
251  * @return true if the intrusive pointer doesn't point at the specified object
252  */
253 template<typename T, typename U>
254 inline bool operator!=( IntrusivePtr<T>const& lhs, U* rhs )
255 {
256   return lhs.Get() != rhs;
257 }
258
259 /**
260  * @brief Comparison overrides of objects wrapped by intrusive pointers
261  *
262  * @param lhs object to compare with
263  * @param rhs intrusive pointer to compare against
264  * @return true if the intrusive pointer points at the specified object
265  */
266 template<typename T, typename U>
267 inline bool operator==( T* lhs, IntrusivePtr<U>const& rhs )
268 {
269   return lhs == rhs.Get();
270 }
271
272 /**
273  * @brief Comparison overrides of objects wrapped by intrusive pointers
274  *
275  * @param lhs object to compare with
276  * @param rhs intrusive pointer to compare against
277  * @return true if the intrusive pointer doesn't point at the specified object
278  */
279 template<typename T, typename U>
280 inline bool operator!=( T* lhs, IntrusivePtr<U>const& rhs )
281 {
282   return lhs != rhs.Get();
283 }
284
285 } // namespace Dali
286
287 #endif /* __DALI_INTRUSIVE_PTR_H__ */