Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules_wearable / core / include / dpl / shared_ptr.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        shared_ptr.h
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @version     1.0
20  * @brief       This file is the implementation file of shared pointer RAII
21  *
22  * This module is deprecated, please use standard C++11 feature: std::shared_ptr
23  */
24 #ifndef DPL_SHARED_PTR_H
25 #define DPL_SHARED_PTR_H
26
27 #include <stddef.h>
28
29 #include <dpl/noncopyable.h>
30 #include <dpl/atomic.h>
31 #include <dpl/bool_operator.h>
32 #include <dpl/assert.h>
33 #include <dpl/availability.h>
34
35 namespace DPL {
36 struct StaticPointerCastTag {};
37 struct ConstPointerCastTag {};
38 struct DynamicPointerCastTag {};
39
40 struct SharedCounter
41 {
42     SharedCounter() :
43         ref(1)
44     {}
45
46     Atomic ref;
47 };
48
49 template<typename Class>
50 class EnableSharedFromThis;
51
52 template<typename Other>
53 inline void _Internal_AcceptSharedPtr(SharedCounter *counter,
54                                       Other *other,
55                                       EnableSharedFromThis<Other> *otherBase)
56 {
57     otherBase->_Internal_AcceptSharedPtr(counter, other);
58 }
59
60 struct AnyPointer
61 {
62     template<typename Other>
63     AnyPointer(Other *)
64     {}
65 };
66
67 inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer)
68 {}
69
70 template<typename Class>
71 class SharedPtr
72 {
73   public:
74     typedef Class ValueType;
75     typedef SharedPtr<Class> ThisType;
76
77   private:
78     SharedCounter *m_counter;
79     Class *m_ptr;
80
81     void AttachCounter(const SharedCounter *counter)
82     {
83         // Attention: R-Value const cast
84         m_counter = const_cast<SharedCounter *>(counter);
85
86         if (m_counter != NULL) {
87             ++m_counter->ref;
88         }
89     }
90
91     void DetachCounter()
92     {
93         if (m_counter) {
94             if (!--m_counter->ref) {
95                 delete m_ptr;
96                 delete m_counter;
97             }
98
99             m_counter = NULL;
100             m_ptr = NULL;
101         }
102     }
103
104   public:
105     SharedPtr() :
106         m_counter(NULL),
107         m_ptr(NULL)
108     {}
109
110     explicit SharedPtr(Class *ptr) :
111         m_counter(NULL),
112         m_ptr(ptr)
113     {
114         if (m_ptr != NULL) {
115             m_counter = new SharedCounter();
116             _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
117         }
118     }
119
120     SharedPtr(const SharedPtr &other) :
121         m_counter(NULL),
122         m_ptr(other.m_ptr)
123     {
124         AttachCounter(other.m_counter);
125     }
126
127     SharedPtr(SharedCounter *counter, Class *ptr) :
128         m_counter(NULL),
129         m_ptr(ptr)
130     {
131         AttachCounter(counter);
132     }
133
134     template<typename Other>
135     friend class SharedPtr;
136
137     template<typename Other>
138     SharedPtr(const SharedPtr<Other> &other, const StaticPointerCastTag &) :
139         m_counter(NULL),
140         m_ptr(NULL)
141     {
142         m_ptr = static_cast<Class *>(other.m_ptr);
143         AttachCounter(other.m_counter);
144     }
145
146     template<typename Other>
147     SharedPtr(const SharedPtr<Other> &other, const ConstPointerCastTag &) :
148         m_counter(NULL),
149         m_ptr(NULL)
150     {
151         m_ptr = const_cast<Class *>(other.m_ptr);
152         AttachCounter(other.m_counter);
153     }
154
155     template<typename Other>
156     SharedPtr(const SharedPtr<Other> &other, const DynamicPointerCastTag &) :
157         m_counter(NULL),
158         m_ptr(NULL)
159     {
160         Class *ptr = dynamic_cast<Class *>(other.Get());
161
162         if (ptr == NULL) {
163             return;
164         }
165
166         m_ptr = ptr;
167         AttachCounter(other.m_counter);
168     }
169
170     virtual ~SharedPtr()
171     {
172         DetachCounter();
173     }
174
175     Class *Get() const
176     {
177         return m_counter == NULL ? NULL : m_ptr;
178     }
179
180     Class *operator->() const
181     {
182         Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
183         return m_ptr;
184     }
185
186     Class &operator *() const
187     {
188         Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
189         return *m_ptr;
190     }
191
192     void Reset(Class *ptr = NULL)
193     {
194         DetachCounter();
195
196         if (ptr != NULL) {
197             m_ptr = ptr;
198             m_counter = new SharedCounter();
199             _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
200         }
201     }
202
203     SharedPtr &operator=(const SharedPtr &other)
204     {
205         if (this != &other) {
206             DetachCounter();
207             m_ptr = other.m_ptr;
208             AttachCounter(other.m_counter);
209         }
210
211         return *this;
212     }
213
214     Atomic::ValueType GetUseCount() const
215     {
216         if (m_counter == NULL) {
217             return Atomic::ValueType(0);
218         }
219
220         return m_counter->ref;
221     }
222
223     DPL_IMPLEMENT_BOOL_OPERATOR(ValueType, ThisType, m_counter, m_ptr)
224 } DPL_DEPRECATED_WITH_MESSAGE("use standard C++11 feature: std::shared_ptr");
225
226 template<typename Target, typename Source>
227 SharedPtr<Target> StaticPointerCast(const SharedPtr<Source> &ptr)
228 {
229     return SharedPtr<Target>(ptr, StaticPointerCastTag());
230 }
231
232 template<typename Target, typename Source>
233 SharedPtr<Target> ConstPointerCast(const SharedPtr<Source> &ptr)
234 {
235     return SharedPtr<Target>(ptr, ConstPointerCastTag());
236 }
237
238 template<typename Target, typename Source>
239 SharedPtr<Target> DynamicPointerCast(const SharedPtr<Source> &ptr)
240 {
241     return SharedPtr<Target>(ptr, DynamicPointerCastTag());
242 }
243
244 template<typename First, typename Second>
245 inline bool operator ==(const SharedPtr<First> &first,
246                         const SharedPtr<Second> &second)
247 {
248     return first.Get() == second.Get();
249 }
250
251 template<typename First, typename Second>
252 inline bool operator !=(const SharedPtr<First> &first,
253                         const SharedPtr<Second> &second)
254 {
255     return first.Get() != second.Get();
256 }
257
258 template<typename First, typename Second>
259 inline bool operator <(const SharedPtr<First> &first,
260                        const SharedPtr<Second> &second)
261 {
262     return first.Get() < second.Get();
263 }
264 template<typename First, typename Second>
265 inline bool operator >(const SharedPtr<First> &first,
266                        const SharedPtr<Second> &second)
267 {
268     return first.Get() > second.Get();
269 }
270
271 template<typename First, typename Second>
272 inline bool operator <=(const SharedPtr<First> &first,
273                         const SharedPtr<Second> &second)
274 {
275     return first.Get() <= second.Get();
276 }
277
278 template<typename First, typename Second>
279 inline bool operator >=(const SharedPtr<First> &first,
280                         const SharedPtr<Second> &second)
281 {
282     return first.Get() >= second.Get();
283 }
284 } // namespace DPL
285
286 #endif // DPL_SHARED_PTR_H