File indexing completed on 2025-12-16 10:08:50
0001 #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
0002 #define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <boost/config.hpp>
0016 #include <boost/shared_ptr.hpp>
0017 #include <boost/weak_ptr.hpp>
0018 #include <boost/assert.hpp>
0019 #include <boost/config/workaround.hpp>
0020
0021 namespace boost
0022 {
0023 template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
0024 template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
0025
0026 namespace detail
0027 {
0028 template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
0029
0030 }
0031
0032 class enable_shared_from_raw
0033 {
0034 protected:
0035
0036 enable_shared_from_raw()
0037 {
0038 }
0039
0040 enable_shared_from_raw( enable_shared_from_raw const & )
0041 {
0042 }
0043
0044 enable_shared_from_raw & operator=( enable_shared_from_raw const & )
0045 {
0046 return *this;
0047 }
0048
0049 ~enable_shared_from_raw()
0050 {
0051 BOOST_ASSERT( shared_this_.use_count() <= 1 );
0052 }
0053
0054 private:
0055
0056 void init_if_expired() const
0057 {
0058 if( weak_this_.expired() )
0059 {
0060 shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
0061 weak_this_ = shared_this_;
0062 }
0063 }
0064
0065 void init_if_empty() const
0066 {
0067 if( weak_this_._empty() )
0068 {
0069 shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
0070 weak_this_ = shared_this_;
0071 }
0072 }
0073
0074 private:
0075
0076 template<class Y> friend class shared_ptr;
0077 template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
0078 template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
0079 template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
0080
0081 shared_ptr<void const volatile> shared_from_this() const
0082 {
0083 init_if_expired();
0084 return shared_ptr<void const volatile>( weak_this_ );
0085 }
0086
0087 shared_ptr<void const volatile> shared_from_this() const volatile
0088 {
0089 return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
0090 }
0091
0092 weak_ptr<void const volatile> weak_from_this() const
0093 {
0094 init_if_empty();
0095 return weak_this_;
0096 }
0097
0098 weak_ptr<void const volatile> weak_from_this() const volatile
0099 {
0100 return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
0101 }
0102
0103
0104 template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * ) const
0105 {
0106 BOOST_ASSERT( ppx != 0 );
0107
0108 if( weak_this_.expired() )
0109 {
0110 weak_this_ = *ppx;
0111 }
0112 else if( shared_this_.use_count() != 0 )
0113 {
0114 BOOST_ASSERT( ppx->unique() );
0115
0116 detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
0117 BOOST_ASSERT( pd != 0 );
0118
0119 pd->set_deleter( *ppx );
0120
0121 ppx->reset( shared_this_, ppx->get() );
0122 shared_this_.reset();
0123 }
0124 }
0125
0126 mutable weak_ptr<void const volatile> weak_this_;
0127
0128 private:
0129
0130 mutable shared_ptr<void const volatile> shared_this_;
0131 };
0132
0133 template<typename T>
0134 boost::shared_ptr<T> shared_from_raw(T *p)
0135 {
0136 BOOST_ASSERT(p != 0);
0137 return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
0138 }
0139
0140 template<typename T>
0141 boost::weak_ptr<T> weak_from_raw(T *p)
0142 {
0143 BOOST_ASSERT(p != 0);
0144 boost::weak_ptr<T> result(p->enable_shared_from_raw::weak_from_this(), p);
0145 return result;
0146 }
0147
0148 namespace detail
0149 {
0150 template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe )
0151 {
0152 if( pe != 0 )
0153 {
0154 pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
0155 }
0156 }
0157 }
0158
0159 }
0160
0161 #endif