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 #include <sysc/packages/boost/config.hpp>
00018
00019 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00020 #include <sysc/packages/boost/detail/shared_ptr_nmt.hpp>
00021 #else
00022
00023 #include <sysc/packages/boost/assert.hpp>
00024 #include <sysc/packages/boost/checked_delete.hpp>
00025 #include <sysc/packages/boost/throw_exception.hpp>
00026 #include <sysc/packages/boost/detail/shared_count.hpp>
00027 #include <sysc/packages/boost/detail/workaround.hpp>
00028
00029 #include <memory>
00030 #include <algorithm>
00031 #include <functional>
00032 #include <typeinfo>
00033 #include <iosfwd>
00034
00035 #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash
00036 # pragma warning(push)
00037 # pragma warning(disable:4284) // odd return type for operator->
00038 #endif
00039
00040 namespace boost
00041 {
00042
00043 template<class T> class weak_ptr;
00044 template<class T> class enable_shared_from_this;
00045
00046 namespace detail
00047 {
00048
00049 struct static_cast_tag {};
00050 struct const_cast_tag {};
00051 struct dynamic_cast_tag {};
00052 struct polymorphic_cast_tag {};
00053
00054 template<class T> struct shared_ptr_traits
00055 {
00056 typedef T & reference;
00057 };
00058
00059 template<> struct shared_ptr_traits<void>
00060 {
00061 typedef void reference;
00062 };
00063
00064 #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
00065
00066 template<> struct shared_ptr_traits<void const>
00067 {
00068 typedef void reference;
00069 };
00070
00071 template<> struct shared_ptr_traits<void volatile>
00072 {
00073 typedef void reference;
00074 };
00075
00076 template<> struct shared_ptr_traits<void const volatile>
00077 {
00078 typedef void reference;
00079 };
00080
00081 #endif
00082
00083
00084
00085 template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px )
00086 {
00087 if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
00088 }
00089
00090 inline void sp_enable_shared_from_this( shared_count const & , ... )
00091 {
00092 }
00093
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 template<class T> class shared_ptr
00106 {
00107 private:
00108
00109
00110 typedef shared_ptr<T> this_type;
00111
00112 public:
00113
00114 typedef T element_type;
00115 typedef T value_type;
00116 typedef T * pointer;
00117 typedef typename detail::shared_ptr_traits<T>::reference reference;
00118
00119 shared_ptr(): px(0), pn()
00120 {
00121 }
00122
00123 template<class Y>
00124 explicit shared_ptr( Y * p ): px( p ), pn( p )
00125 {
00126 detail::sp_enable_shared_from_this( pn, p, p );
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
00136 {
00137 detail::sp_enable_shared_from_this( pn, p, p );
00138 }
00139
00140
00141
00142
00143 #if defined(__BORLANDC__) || defined(__GNUC__)
00144
00145 shared_ptr & operator=(shared_ptr const & r)
00146 {
00147 px = r.px;
00148 pn = r.pn;
00149 return *this;
00150 }
00151
00152 #endif
00153
00154 template<class Y>
00155 explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn)
00156 {
00157
00158 px = r.px;
00159 }
00160
00161 template<class Y>
00162 shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn)
00163 {
00164 }
00165
00166 template<class Y>
00167 shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
00168 {
00169 }
00170
00171 template<class Y>
00172 shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
00173 {
00174 }
00175
00176 template<class Y>
00177 shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00178 {
00179 if(px == 0)
00180 {
00181 pn = detail::shared_count();
00182 }
00183 }
00184
00185 template<class Y>
00186 shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00187 {
00188 if(px == 0)
00189 {
00190 boost::throw_exception(std::bad_cast());
00191 }
00192 }
00193
00194 #ifndef BOOST_NO_AUTO_PTR
00195
00196 template<class Y>
00197 explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
00198 {
00199 Y * tmp = r.get();
00200 pn = detail::shared_count(r);
00201 detail::sp_enable_shared_from_this( pn, tmp, tmp );
00202 }
00203
00204 #endif
00205
00206 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
00207
00208 template<class Y>
00209 shared_ptr & operator=(shared_ptr<Y> const & r)
00210 {
00211 px = r.px;
00212 pn = r.pn;
00213 return *this;
00214 }
00215
00216 #endif
00217
00218 #ifndef BOOST_NO_AUTO_PTR
00219
00220 template<class Y>
00221 shared_ptr & operator=(std::auto_ptr<Y> & r)
00222 {
00223 this_type(r).swap(*this);
00224 return *this;
00225 }
00226
00227 #endif
00228
00229 void reset()
00230 {
00231 this_type().swap(*this);
00232 }
00233
00234 template<class Y> void reset(Y * p)
00235 {
00236 BOOST_ASSERT(p == 0 || p != px);
00237 this_type(p).swap(*this);
00238 }
00239
00240 template<class Y, class D> void reset(Y * p, D d)
00241 {
00242 this_type(p, d).swap(*this);
00243 }
00244
00245 reference operator* () const
00246 {
00247 BOOST_ASSERT(px != 0);
00248 return *px;
00249 }
00250
00251 T * operator-> () const
00252 {
00253 BOOST_ASSERT(px != 0);
00254 return px;
00255 }
00256
00257 T * get() const
00258 {
00259 return px;
00260 }
00261
00262
00263
00264 #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
00265
00266 operator bool () const
00267 {
00268 return px != 0;
00269 }
00270
00271 #elif \
00272 ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
00273 ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) )
00274
00275 typedef T * (this_type::*unspecified_bool_type)() const;
00276
00277 operator unspecified_bool_type() const
00278 {
00279 return px == 0? 0: &this_type::get;
00280 }
00281
00282 #else
00283
00284 typedef T * this_type::*unspecified_bool_type;
00285
00286 operator unspecified_bool_type() const
00287 {
00288 return px == 0? 0: &this_type::px;
00289 }
00290
00291 #endif
00292
00293
00294
00295 bool operator! () const
00296 {
00297 return px == 0;
00298 }
00299
00300 bool unique() const
00301 {
00302 return pn.unique();
00303 }
00304
00305 long use_count() const
00306 {
00307 return pn.use_count();
00308 }
00309
00310 void swap(shared_ptr<T> & other)
00311 {
00312 std::swap(px, other.px);
00313 pn.swap(other.pn);
00314 }
00315
00316 template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
00317 {
00318 return pn < rhs.pn;
00319 }
00320
00321 void * _internal_get_deleter(std::type_info const & ti) const
00322 {
00323 return pn.get_deleter(ti);
00324 }
00325
00326
00327
00328
00329 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00330
00331 private:
00332
00333 template<class Y> friend class shared_ptr;
00334 template<class Y> friend class weak_ptr;
00335
00336
00337 #endif
00338
00339 T * px;
00340 detail::shared_count pn;
00341
00342 };
00343
00344 template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
00345 {
00346 return a.get() == b.get();
00347 }
00348
00349 template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
00350 {
00351 return a.get() != b.get();
00352 }
00353
00354 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00355
00356
00357
00358 template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
00359 {
00360 return a.get() != b.get();
00361 }
00362
00363 #endif
00364
00365 template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
00366 {
00367 return a._internal_less(b);
00368 }
00369
00370 template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
00371 {
00372 a.swap(b);
00373 }
00374
00375 template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
00376 {
00377 return shared_ptr<T>(r, detail::static_cast_tag());
00378 }
00379
00380 template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
00381 {
00382 return shared_ptr<T>(r, detail::const_cast_tag());
00383 }
00384
00385 template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
00386 {
00387 return shared_ptr<T>(r, detail::dynamic_cast_tag());
00388 }
00389
00390
00391
00392 template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
00393 {
00394 return shared_ptr<T>(r, detail::static_cast_tag());
00395 }
00396
00397 template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00398 {
00399 return shared_ptr<T>(r, detail::dynamic_cast_tag());
00400 }
00401
00402 template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
00403 {
00404 return shared_ptr<T>(r, detail::polymorphic_cast_tag());
00405 }
00406
00407 template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
00408 {
00409 BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
00410 return shared_static_cast<T>(r);
00411 }
00412
00413
00414
00415 template<class T> inline T * get_pointer(shared_ptr<T> const & p)
00416 {
00417 return p.get();
00418 }
00419
00420
00421
00422 #if defined(__GNUC__) && (__GNUC__ < 3)
00423
00424 template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
00425 {
00426 os << p.get();
00427 return os;
00428 }
00429
00430 #else
00431
00432 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, <= 1200 && __SGI_STL_PORT)
00433
00434 using std::basic_ostream;
00435 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
00436 # else
00437 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
00438 # endif
00439 {
00440 os << p.get();
00441 return os;
00442 }
00443
00444 #endif
00445
00446
00447
00448 #if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
00449 ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
00450 ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
00451
00452
00453
00454
00455 template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
00456 {
00457 void const * q = p._internal_get_deleter(typeid(D));
00458 return const_cast<D *>(static_cast<D const *>(q));
00459 }
00460
00461 #else
00462
00463 template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
00464 {
00465 return static_cast<D *>(p._internal_get_deleter(typeid(D)));
00466 }
00467
00468 #endif
00469
00470 }
00471
00472 #ifdef BOOST_MSVC
00473 # pragma warning(pop)
00474 #endif
00475
00476 #endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00477
00478 #endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED