File indexing completed on 2025-01-30 09:59:44
0001 #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED
0002 #define BOOST_SHARED_PTR_132_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <boost/config.hpp> // for broken compiler workarounds
0018
0019 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
0020 #include <boost/serialization/detail/shared_ptr_nmt_132.hpp>
0021 #else
0022
0023 #include <boost/assert.hpp>
0024 #include <boost/checked_delete.hpp>
0025 #include <boost/serialization/throw_exception.hpp>
0026 #include <boost/detail/workaround.hpp>
0027
0028 #include <boost/serialization/access.hpp>
0029 #include <boost/serialization/detail/shared_count_132.hpp>
0030
0031 #include <memory> // for std::auto_ptr
0032 #include <algorithm> // for std::swap
0033 #include <functional> // for std::less
0034 #include <typeinfo> // for std::bad_cast
0035 #include <iosfwd> // for std::basic_ostream
0036
0037 #ifdef BOOST_MSVC
0038 # pragma warning(push)
0039 # pragma warning(disable:4284)
0040 #endif
0041
0042 namespace boost_132 {
0043
0044 template<class T> class weak_ptr;
0045 template<class T> class enable_shared_from_this;
0046
0047 namespace detail
0048 {
0049
0050 struct static_cast_tag {};
0051 struct const_cast_tag {};
0052 struct dynamic_cast_tag {};
0053 struct polymorphic_cast_tag {};
0054
0055 template<class T> struct shared_ptr_traits
0056 {
0057 typedef T & reference;
0058 };
0059
0060 template<> struct shared_ptr_traits<void>
0061 {
0062 typedef void reference;
0063 };
0064
0065 #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
0066
0067 template<> struct shared_ptr_traits<void const>
0068 {
0069 typedef void reference;
0070 };
0071
0072 template<> struct shared_ptr_traits<void volatile>
0073 {
0074 typedef void reference;
0075 };
0076
0077 template<> struct shared_ptr_traits<void const volatile>
0078 {
0079 typedef void reference;
0080 };
0081
0082 #endif
0083
0084
0085
0086 template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px )
0087 {
0088 if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
0089 }
0090
0091 inline void sp_enable_shared_from_this( shared_count const & , ... )
0092 {
0093 }
0094
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 template<class T> class shared_ptr
0107 {
0108 private:
0109
0110 typedef shared_ptr< T > this_type;
0111
0112 public:
0113
0114 typedef T element_type;
0115 typedef T value_type;
0116 typedef T * pointer;
0117 typedef typename detail::shared_ptr_traits< T >::reference reference;
0118
0119 shared_ptr(): px(0), pn()
0120 {
0121 }
0122
0123 template<class Y>
0124 explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter<Y>())
0125 {
0126 detail::sp_enable_shared_from_this( pn, p, p );
0127 }
0128
0129
0130
0131
0132
0133
0134
0135 template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
0136 {
0137 detail::sp_enable_shared_from_this( pn, p, p );
0138 }
0139
0140
0141
0142
0143 #if defined(__GNUC__)
0144 shared_ptr & operator=(shared_ptr const & r)
0145 {
0146 px = r.px;
0147 pn = r.pn;
0148 return *this;
0149 }
0150 #endif
0151
0152 template<class Y>
0153 explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn)
0154 {
0155
0156 px = r.px;
0157 }
0158
0159 template<class Y>
0160 shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn)
0161 {
0162 }
0163
0164 template<class Y>
0165 shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
0166 {
0167 }
0168
0169 template<class Y>
0170 shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
0171 {
0172 }
0173
0174 template<class Y>
0175 shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
0176 {
0177 if(px == 0)
0178 {
0179 pn = detail::shared_count();
0180 }
0181 }
0182
0183 template<class Y>
0184 shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
0185 {
0186 if(px == 0)
0187 {
0188 boost::serialization::throw_exception(std::bad_cast());
0189 }
0190 }
0191
0192 #ifndef BOOST_NO_AUTO_PTR
0193
0194 template<class Y>
0195 explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
0196 {
0197 Y * tmp = r.get();
0198 pn = detail::shared_count(r);
0199 detail::sp_enable_shared_from_this( pn, tmp, tmp );
0200 }
0201
0202 #endif
0203
0204 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
0205
0206 template<class Y>
0207 shared_ptr & operator=(shared_ptr<Y> const & r)
0208 {
0209 px = r.px;
0210 pn = r.pn;
0211 return *this;
0212 }
0213
0214 #endif
0215
0216 #ifndef BOOST_NO_AUTO_PTR
0217
0218 template<class Y>
0219 shared_ptr & operator=(std::auto_ptr<Y> & r)
0220 {
0221 this_type(r).swap(*this);
0222 return *this;
0223 }
0224
0225 #endif
0226
0227 void reset()
0228 {
0229 this_type().swap(*this);
0230 }
0231
0232 template<class Y> void reset(Y * p)
0233 {
0234 BOOST_ASSERT(p == 0 || p != px);
0235 this_type(p).swap(*this);
0236 }
0237
0238 template<class Y, class D> void reset(Y * p, D d)
0239 {
0240 this_type(p, d).swap(*this);
0241 }
0242
0243 reference operator* () const
0244 {
0245 BOOST_ASSERT(px != 0);
0246 return *px;
0247 }
0248
0249 T * operator-> () const
0250 {
0251 BOOST_ASSERT(px != 0);
0252 return px;
0253 }
0254
0255 T * get() const
0256 {
0257 return px;
0258 }
0259
0260
0261
0262 #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
0263
0264 operator bool () const
0265 {
0266 return px != 0;
0267 }
0268
0269 #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
0270 typedef T * (this_type::*unspecified_bool_type)() const;
0271
0272 operator unspecified_bool_type() const
0273 {
0274 return px == 0? 0: &this_type::get;
0275 }
0276
0277 #else
0278
0279 typedef T * this_type::*unspecified_bool_type;
0280
0281 operator unspecified_bool_type() const
0282 {
0283 return px == 0? 0: &this_type::px;
0284 }
0285
0286 #endif
0287
0288
0289
0290 bool operator! () const
0291 {
0292 return px == 0;
0293 }
0294
0295 bool unique() const
0296 {
0297 return pn.unique();
0298 }
0299
0300 long use_count() const
0301 {
0302 return pn.use_count();
0303 }
0304
0305 void swap(shared_ptr< T > & other)
0306 {
0307 std::swap(px, other.px);
0308 pn.swap(other.pn);
0309 }
0310
0311 template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
0312 {
0313 return pn < rhs.pn;
0314 }
0315
0316 void * _internal_get_deleter(std::type_info const & ti) const
0317 {
0318 return pn.get_deleter(ti);
0319 }
0320
0321
0322
0323
0324 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0325
0326 private:
0327
0328 template<class Y> friend class shared_ptr;
0329 template<class Y> friend class weak_ptr;
0330
0331
0332 #endif
0333 public:
0334 T * px;
0335 detail::shared_count pn;
0336
0337 };
0338
0339 template<class T, class U> inline bool operator==(shared_ptr< T > const & a, shared_ptr<U> const & b)
0340 {
0341 return a.get() == b.get();
0342 }
0343
0344 template<class T, class U> inline bool operator!=(shared_ptr< T > const & a, shared_ptr<U> const & b)
0345 {
0346 return a.get() != b.get();
0347 }
0348
0349 template<class T, class U> inline bool operator<(shared_ptr< T > const & a, shared_ptr<U> const & b)
0350 {
0351 return a._internal_less(b);
0352 }
0353
0354 template<class T> inline void swap(shared_ptr< T > & a, shared_ptr< T > & b)
0355 {
0356 a.swap(b);
0357 }
0358
0359 template<class T, class U> shared_ptr< T > static_pointer_cast(shared_ptr<U> const & r)
0360 {
0361 return shared_ptr< T >(r, detail::static_cast_tag());
0362 }
0363
0364 template<class T, class U> shared_ptr< T > const_pointer_cast(shared_ptr<U> const & r)
0365 {
0366 return shared_ptr< T >(r, detail::const_cast_tag());
0367 }
0368
0369 template<class T, class U> shared_ptr< T > dynamic_pointer_cast(shared_ptr<U> const & r)
0370 {
0371 return shared_ptr< T >(r, detail::dynamic_cast_tag());
0372 }
0373
0374
0375
0376 template<class T, class U> shared_ptr< T > shared_static_cast(shared_ptr<U> const & r)
0377 {
0378 return shared_ptr< T >(r, detail::static_cast_tag());
0379 }
0380
0381 template<class T, class U> shared_ptr< T > shared_dynamic_cast(shared_ptr<U> const & r)
0382 {
0383 return shared_ptr< T >(r, detail::dynamic_cast_tag());
0384 }
0385
0386 template<class T, class U> shared_ptr< T > shared_polymorphic_cast(shared_ptr<U> const & r)
0387 {
0388 return shared_ptr< T >(r, detail::polymorphic_cast_tag());
0389 }
0390
0391 template<class T, class U> shared_ptr< T > shared_polymorphic_downcast(shared_ptr<U> const & r)
0392 {
0393 BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
0394 return shared_static_cast< T >(r);
0395 }
0396
0397
0398
0399 template<class T> inline T * get_pointer(shared_ptr< T > const & p)
0400 {
0401 return p.get();
0402 }
0403
0404
0405
0406
0407 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
0408 {
0409 os << p.get();
0410 return os;
0411 }
0412
0413
0414
0415 #if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238)
0416
0417
0418
0419
0420 template<class D, class T> D * get_deleter(shared_ptr< T > const & p)
0421 {
0422 void const * q = p._internal_get_deleter(typeid(D));
0423 return const_cast<D *>(static_cast<D const *>(q));
0424 }
0425
0426 #else
0427
0428 template<class D, class T> D * get_deleter(shared_ptr< T > const & p)
0429 {
0430 return static_cast<D *>(p._internal_get_deleter(typeid(D)));
0431 }
0432
0433 #endif
0434
0435 }
0436
0437 #ifdef BOOST_MSVC
0438 # pragma warning(pop)
0439 #endif
0440
0441 #endif
0442
0443 #endif