2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of shared pointer RAII
22 #ifndef DPL_SHARED_PTR_H
23 #define DPL_SHARED_PTR_H
25 #include <dpl/noncopyable.h>
26 #include <dpl/atomic.h>
27 #include <dpl/bool_operator.h>
29 #include <dpl/assert.h>
32 struct StaticPointerCastTag {};
33 struct ConstPointerCastTag {};
34 struct DynamicPointerCastTag {};
45 template<typename Class>
46 class EnableSharedFromThis;
48 template<typename Other>
49 inline void _Internal_AcceptSharedPtr(SharedCounter *counter,
51 EnableSharedFromThis<Other> *otherBase)
53 otherBase->_Internal_AcceptSharedPtr(counter, other);
58 template<typename Other>
63 inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer)
66 template<typename Class>
70 typedef Class ValueType;
71 typedef SharedPtr<Class> ThisType;
74 SharedCounter *m_counter;
77 void AttachCounter(const SharedCounter *counter)
79 // Attention: R-Value const cast
80 m_counter = const_cast<SharedCounter *>(counter);
82 if (m_counter != NULL) {
90 if (!--m_counter->ref) {
106 explicit SharedPtr(Class *ptr) :
111 m_counter = new SharedCounter();
112 _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
116 SharedPtr(const SharedPtr &other) :
120 AttachCounter(other.m_counter);
123 SharedPtr(SharedCounter *counter, Class *ptr) :
127 AttachCounter(counter);
130 template<typename Other>
131 friend class SharedPtr;
133 template<typename Other>
134 SharedPtr(const SharedPtr<Other> &other, const StaticPointerCastTag &) :
138 m_ptr = static_cast<Class *>(other.m_ptr);
139 AttachCounter(other.m_counter);
142 template<typename Other>
143 SharedPtr(const SharedPtr<Other> &other, const ConstPointerCastTag &) :
147 m_ptr = const_cast<Class *>(other.m_ptr);
148 AttachCounter(other.m_counter);
151 template<typename Other>
152 SharedPtr(const SharedPtr<Other> &other, const DynamicPointerCastTag &) :
156 Class *ptr = dynamic_cast<Class *>(other.Get());
163 AttachCounter(other.m_counter);
173 return m_counter == NULL ? NULL : m_ptr;
176 Class *operator->() const
178 Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
182 Class &operator *() const
184 Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
188 void Reset(Class *ptr = NULL)
194 m_counter = new SharedCounter();
195 _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
199 SharedPtr &operator=(const SharedPtr &other)
201 if (this != &other) {
204 AttachCounter(other.m_counter);
210 Atomic::ValueType GetUseCount() const
212 if (m_counter == NULL) {
213 return Atomic::ValueType(0);
216 return m_counter->ref;
219 DPL_IMPLEMENT_BOOL_OPERATOR(ValueType, ThisType, m_counter, m_ptr)
222 template<typename Target, typename Source>
223 SharedPtr<Target> StaticPointerCast(const SharedPtr<Source> &ptr)
225 return SharedPtr<Target>(ptr, StaticPointerCastTag());
228 template<typename Target, typename Source>
229 SharedPtr<Target> ConstPointerCast(const SharedPtr<Source> &ptr)
231 return SharedPtr<Target>(ptr, ConstPointerCastTag());
234 template<typename Target, typename Source>
235 SharedPtr<Target> DynamicPointerCast(const SharedPtr<Source> &ptr)
237 return SharedPtr<Target>(ptr, DynamicPointerCastTag());
240 template<typename First, typename Second>
241 inline bool operator ==(const SharedPtr<First> &first,
242 const SharedPtr<Second> &second)
244 return first.Get() == second.Get();
247 template<typename First, typename Second>
248 inline bool operator !=(const SharedPtr<First> &first,
249 const SharedPtr<Second> &second)
251 return first.Get() != second.Get();
254 template<typename First, typename Second>
255 inline bool operator <(const SharedPtr<First> &first,
256 const SharedPtr<Second> &second)
258 return first.Get() < second.Get();
260 template<typename First, typename Second>
261 inline bool operator >(const SharedPtr<First> &first,
262 const SharedPtr<Second> &second)
264 return first.Get() > second.Get();
267 template<typename First, typename Second>
268 inline bool operator <=(const SharedPtr<First> &first,
269 const SharedPtr<Second> &second)
271 return first.Get() <= second.Get();
274 template<typename First, typename Second>
275 inline bool operator >=(const SharedPtr<First> &first,
276 const SharedPtr<Second> &second)
278 return first.Get() >= second.Get();
282 #endif // DPL_SHARED_PTR_H