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>
33 struct StaticPointerCastTag {};
34 struct ConstPointerCastTag {};
35 struct DynamicPointerCastTag {};
47 template<typename Class>
48 class EnableSharedFromThis;
50 template<typename Other>
51 inline void _Internal_AcceptSharedPtr(SharedCounter *counter, Other *other, EnableSharedFromThis<Other> *otherBase)
53 otherBase->_Internal_AcceptSharedPtr(counter, other);
58 template<typename Other>
64 inline void _Internal_AcceptSharedPtr(SharedCounter *, AnyPointer, AnyPointer)
68 template<typename Class>
72 typedef Class ValueType;
73 typedef SharedPtr<Class> ThisType;
76 SharedCounter *m_counter;
79 void AttachCounter(const SharedCounter *counter)
81 // Attention: R-Value const cast
82 m_counter = const_cast<SharedCounter *>(counter);
84 if (m_counter != NULL)
92 if (!--m_counter->ref)
110 explicit SharedPtr(Class *ptr)
116 m_counter = new SharedCounter();
117 _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
121 SharedPtr(const SharedPtr &other)
125 AttachCounter(other.m_counter);
128 SharedPtr(SharedCounter *counter, Class *ptr)
132 AttachCounter(counter);
135 template<typename Other>
136 friend class SharedPtr;
138 template<typename Other>
139 SharedPtr(const SharedPtr<Other> &other, const StaticPointerCastTag &)
143 m_ptr = static_cast<Class *>(other.m_ptr);
144 AttachCounter(other.m_counter);
147 template<typename Other>
148 SharedPtr(const SharedPtr<Other> &other, const ConstPointerCastTag &)
152 m_ptr = const_cast<Class *>(other.m_ptr);
153 AttachCounter(other.m_counter);
156 template<typename Other>
157 SharedPtr(const SharedPtr<Other> &other, const DynamicPointerCastTag &)
161 Class *ptr = dynamic_cast<Class *>(other.Get());
167 AttachCounter(other.m_counter);
177 return m_counter == NULL ? NULL : m_ptr;
180 Class *operator->() const
182 Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
186 Class &operator *() const
188 Assert(m_counter != NULL && "Dereference of shared NULL pointer!");
192 void Reset(Class *ptr = NULL)
199 m_counter = new SharedCounter();
200 _Internal_AcceptSharedPtr(m_counter, m_ptr, m_ptr);
204 SharedPtr &operator=(const SharedPtr &other)
210 AttachCounter(other.m_counter);
216 Atomic::ValueType GetUseCount() const
218 if (m_counter == NULL)
219 return Atomic::ValueType(0);
221 return m_counter->ref;
224 DPL_IMPLEMENT_BOOL_OPERATOR(ValueType, ThisType, m_counter, m_ptr)
227 template<typename Target, typename Source>
228 SharedPtr<Target> StaticPointerCast(const SharedPtr<Source> &ptr)
230 return SharedPtr<Target>(ptr, StaticPointerCastTag());
233 template<typename Target, typename Source>
234 SharedPtr<Target> ConstPointerCast(const SharedPtr<Source> &ptr)
236 return SharedPtr<Target>(ptr, ConstPointerCastTag());
239 template<typename Target, typename Source>
240 SharedPtr<Target> DynamicPointerCast(const SharedPtr<Source> &ptr)
242 return SharedPtr<Target>(ptr, DynamicPointerCastTag());
245 template<typename First, typename Second>
246 inline bool operator ==(const SharedPtr<First> &first, const SharedPtr<Second> &second)
248 return first.Get() == second.Get();
251 template<typename First, typename Second>
252 inline bool operator !=(const SharedPtr<First> &first, const SharedPtr<Second> &second)
254 return first.Get() != second.Get();
257 template<typename First, typename Second>
258 inline bool operator <(const SharedPtr<First> &first, const SharedPtr<Second> &second)
260 return first.Get() < second.Get();
262 template<typename First, typename Second>
263 inline bool operator >(const SharedPtr<First> &first, const SharedPtr<Second> &second)
265 return first.Get() > second.Get();
268 template<typename First, typename Second>
269 inline bool operator <=(const SharedPtr<First> &first, const SharedPtr<Second> &second)
271 return first.Get() <= second.Get();
274 template<typename First, typename Second>
275 inline bool operator >=(const SharedPtr<First> &first, const SharedPtr<Second> &second)
277 return first.Get() >= second.Get();
282 #endif // DPL_SHARED_PTR_H