Back to home page

EIC code displayed by LXR

 
 

    


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 //  shared_ptr.hpp
0006 //
0007 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
0008 //  Copyright (c) 2001, 2002, 2003 Peter Dimov
0009 //
0010 //  Distributed under the Boost Software License, Version 1.0. (See
0011 //  accompanying file LICENSE_1_0.txt or copy at
0012 //  http://www.boost.org/LICENSE_1_0.txt)
0013 //
0014 //  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
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  // moved here to work around VC++ compiler crash
0038 # pragma warning(push)
0039 # pragma warning(disable:4284) // odd return type for operator->
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 // enable_shared_from_this support
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 & /*pn*/, ... )
0092 {
0093 }
0094 
0095 } // namespace detail
0096 
0097 
0098 //
0099 //  shared_ptr
0100 //
0101 //  An enhanced relative of scoped_ptr with reference counted copy semantics.
0102 //  The object pointed to is deleted when the last shared_ptr pointing to it
0103 //  is destroyed or reset.
0104 //
0105 
0106 template<class T> class shared_ptr
0107 {
0108 private:
0109     // Borland 5.5.1 specific workaround
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() // never throws in 1.30+
0120     {
0121     }
0122 
0123     template<class Y>
0124     explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter<Y>()) // Y must be complete
0125     {
0126         detail::sp_enable_shared_from_this( pn, p, p );
0127     }
0128 
0129     //
0130     // Requirements: D's copy constructor must not throw
0131     //
0132     // shared_ptr will release p by calling d(p)
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 //  generated copy constructor, assignment, destructor are fine...
0141 
0142 //  except that Borland C++ has a bug, and g++ with -Wsynth warns
0143 #if defined(__GNUC__)
0144     shared_ptr & operator=(shared_ptr const & r) // never throws
0145     {
0146         px = r.px;
0147         pn = r.pn; // shared_count::op= doesn't throw
0148         return *this;
0149     }
0150 #endif
0151 
0152     template<class Y>
0153     explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
0154     {
0155         // it is now safe to copy r.px, as pn(r.pn) did not throw
0156         px = r.px;
0157     }
0158 
0159     template<class Y>
0160     shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
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) // need to allocate new counter -- the cast failed
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) // never throws
0208     {
0209         px = r.px;
0210         pn = r.pn; // shared_count::op= doesn't throw
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() // never throws in 1.30+
0228     {
0229         this_type().swap(*this);
0230     }
0231 
0232     template<class Y> void reset(Y * p) // Y must be complete
0233     {
0234         BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
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 // never throws
0244     {
0245         BOOST_ASSERT(px != 0);
0246         return *px;
0247     }
0248 
0249     T * operator-> () const // never throws
0250     {
0251         BOOST_ASSERT(px != 0);
0252         return px;
0253     }
0254 
0255     T * get() const // never throws
0256     {
0257         return px;
0258     }
0259 
0260     // implicit conversion to "bool"
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 // never throws
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 // never throws
0282     {
0283         return px == 0? 0: &this_type::px;
0284     }
0285 
0286 #endif
0287 
0288     // operator! is redundant, but some compilers need it
0289 
0290     bool operator! () const // never throws
0291     {
0292         return px == 0;
0293     }
0294 
0295     bool unique() const // never throws
0296     {
0297         return pn.unique();
0298     }
0299 
0300     long use_count() const // never throws
0301     {
0302         return pn.use_count();
0303     }
0304 
0305     void swap(shared_ptr< T > & other) // never throws
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 // Tasteless as this may seem, making all members public allows member templates
0322 // to work in the absence of member template friends. (Matthew Langston)
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: // for serialization
0334     T * px;                     // contained pointer
0335     detail::shared_count pn;    // reference counter
0336 
0337 };  // shared_ptr
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 // shared_*_cast names are deprecated. Use *_pointer_cast instead.
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 // get_pointer() enables boost::mem_fn to recognize shared_ptr
0398 
0399 template<class T> inline T * get_pointer(shared_ptr< T > const & p)
0400 {
0401     return p.get();
0402 }
0403 
0404 // operator<<
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 // get_deleter (experimental)
0414 
0415 #if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238)
0416 
0417 // g++ 2.9x doesn't allow static_cast<X const *>(void *)
0418 // apparently EDG 2.38 also doesn't accept it
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 } // namespace boost
0436 
0437 #ifdef BOOST_MSVC
0438 # pragma warning(pop)
0439 #endif
0440 
0441 #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
0442 
0443 #endif  // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED