00001 #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
00002 #define BOOST_SHARED_PTR_HPP_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <sysc/packages/boost/config.hpp>
00019
00020 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00021 #include <sysc/packages/boost/detail/shared_ptr_nmt.hpp>
00022 #else
00023
00024 #include <sysc/packages/boost/assert.hpp>
00025 #include <sysc/packages/boost/checked_delete.hpp>
00026 #include <sysc/packages/boost/throw_exception.hpp>
00027 #include <sysc/packages/boost/detail/shared_count.hpp>
00028
00029 #include <memory>
00030 #include <algorithm>
00031 #include <functional>
00032 #include <typeinfo>
00033
00034 #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
00035 # pragma warning(push)
00036 # pragma warning(disable:4284) // odd return type for operator->
00037 #endif
00038
00039 namespace boost
00040 {
00041
00042 namespace detail
00043 {
00044
00045 struct static_cast_tag {};
00046 struct dynamic_cast_tag {};
00047 struct polymorphic_cast_tag {};
00048
00049 template<typename T> struct shared_ptr_traits
00050 {
00051 typedef T & reference;
00052 };
00053
00054 template<> struct shared_ptr_traits<void>
00055 {
00056 typedef void reference;
00057 };
00058
00059 #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
00060
00061 template<> struct shared_ptr_traits<void const>
00062 {
00063 typedef void reference;
00064 };
00065
00066 #endif
00067
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 template<typename T> class weak_ptr;
00080 template<typename T> class intrusive_ptr;
00081
00082 template<typename T> class shared_ptr
00083 {
00084 private:
00085
00086
00087
00088 typedef shared_ptr<T> this_type;
00089
00090 public:
00091
00092 typedef T element_type;
00093 typedef T value_type;
00094
00095 shared_ptr(): px(0), pn()
00096 {
00097 }
00098
00099 template<typename Y>
00100 explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>(), p)
00101 {
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 template<typename Y, typename D> shared_ptr(Y * p, D d): px(p), pn(p, d)
00111 {
00112 }
00113
00114
00115
00116 template<typename Y>
00117 explicit shared_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn)
00118 {
00119 }
00120
00121 template<typename Y>
00122 shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn)
00123 {
00124 }
00125
00126 template<typename Y>
00127 shared_ptr(intrusive_ptr<Y> const & r): px(r.get()), pn(r.get())
00128 {
00129 }
00130
00131 template<typename Y>
00132 shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
00133 {
00134 }
00135
00136 template<typename Y>
00137 shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00138 {
00139 if (px == 0)
00140 {
00141 pn = detail::shared_count();
00142 }
00143 }
00144
00145 template<typename Y>
00146 shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00147 {
00148 if (px == 0)
00149 {
00150 boost::throw_exception(std::bad_cast());
00151 }
00152 }
00153
00154 #ifndef BOOST_NO_AUTO_PTR
00155
00156 template<typename Y>
00157 explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn(r)
00158 {
00159 }
00160
00161 #endif
00162
00163 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
00164
00165 template<typename Y>
00166 shared_ptr & operator=(shared_ptr<Y> const & r)
00167 {
00168 px = r.px;
00169 pn = r.pn;
00170 return *this;
00171 }
00172
00173 #endif
00174
00175 #ifndef BOOST_NO_AUTO_PTR
00176
00177 template<typename Y>
00178 shared_ptr & operator=(std::auto_ptr<Y> & r)
00179 {
00180 this_type(r).swap(*this);
00181 return *this;
00182 }
00183
00184 #endif
00185
00186 void reset()
00187 {
00188 this_type().swap(*this);
00189 }
00190
00191 template<typename Y> void reset(Y * p)
00192 {
00193 BOOST_ASSERT(p == 0 || p != px);
00194 this_type(p).swap(*this);
00195 }
00196
00197 template<typename Y, typename D> void reset(Y * p, D d)
00198 {
00199 this_type(p, d).swap(*this);
00200 }
00201
00202 typename detail::shared_ptr_traits<T>::reference operator* () const
00203 {
00204 BOOST_ASSERT(px != 0);
00205 return *px;
00206 }
00207
00208 T * operator-> () const
00209 {
00210 BOOST_ASSERT(px != 0);
00211 return px;
00212 }
00213
00214 T * get() const
00215 {
00216 return px;
00217 }
00218
00219
00220
00221 typedef T * (this_type::*unspecified_bool_type)() const;
00222
00223 operator unspecified_bool_type() const
00224 {
00225 return px == 0? 0: &this_type::get;
00226 }
00227
00228 bool operator! () const
00229 {
00230 return px == 0;
00231 }
00232
00233 bool unique() const
00234 {
00235 return pn.unique();
00236 }
00237
00238 long use_count() const
00239 {
00240 return pn.use_count();
00241 }
00242
00243 void swap(shared_ptr<T> & other)
00244 {
00245 std::swap(px, other.px);
00246 pn.swap(other.pn);
00247 }
00248
00249
00250
00251
00252 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00253
00254 private:
00255
00256 template<typename Y> friend class shared_ptr;
00257 template<typename Y> friend class weak_ptr;
00258
00259
00260 #endif
00261
00262 T * px;
00263 detail::shared_count pn;
00264
00265 };
00266
00267 template<typename T, typename U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
00268 {
00269 return a.get() == b.get();
00270 }
00271
00272 template<typename T, typename U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
00273 {
00274 return a.get() != b.get();
00275 }
00276
00277 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00278
00279
00280
00281 template<typename T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
00282 {
00283 return a.get() != b.get();
00284 }
00285
00286 #endif
00287
00288 template<typename T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
00289 {
00290 return std::less<T*>()(a.get(), b.get());
00291 }
00292
00293 template<typename T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
00294 {
00295 a.swap(b);
00296 }
00297
00298 template<typename T, typename U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
00299 {
00300 return shared_ptr<T>(r, detail::static_cast_tag());
00301 }
00302
00303 template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00304 {
00305 return shared_ptr<T>(r, detail::dynamic_cast_tag());
00306 }
00307
00308 template<typename T, typename U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
00309 {
00310 return shared_ptr<T>(r, detail::polymorphic_cast_tag());
00311 }
00312
00313 template<typename T, typename U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
00314 {
00315 BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
00316 return shared_static_cast<T>(r);
00317 }
00318
00319
00320
00321 template<typename T> inline T * get_pointer(shared_ptr<T> const & p)
00322 {
00323 return p.get();
00324 }
00325
00326
00327
00328 namespace detail
00329 {
00330
00331 inline void sp_assert_counted_base(boost::counted_base const *)
00332 {
00333 }
00334
00335 template<class T> inline T * sp_remove_const(T const * p)
00336 {
00337 return const_cast<T *>(p);
00338 }
00339
00340 }
00341
00342 template<class T> shared_ptr<T> shared_from_this(T * p)
00343 {
00344 detail::sp_assert_counted_base(p);
00345 return shared_ptr<T>(detail::sp_remove_const(p));
00346 }
00347
00348 }
00349
00350 #ifdef BOOST_MSVC
00351 # pragma warning(pop)
00352 #endif
00353
00354 #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00355
00356 #endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED