Back to home page

EIC code displayed by LXR

 
 

    


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 //  enable_shared_from_raw.hpp
0006 //
0007 //  Copyright 2002, 2009, 2014 Peter Dimov
0008 //  Copyright 2008-2009 Frank Mori Hess
0009 //
0010 //  Distributed under the Boost Software License, Version 1.0.
0011 //  See accompanying file LICENSE_1_0.txt or copy at
0012 //  http://www.boost.org/LICENSE_1_0.txt
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 } // namespace detail
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 ); // make sure no dangling shared_ptr objects exist
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     // Note: invoked automatically by shared_ptr; do not call
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() ); // no weak_ptrs should exist either, but there's no way to check that
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 } // namepsace detail
0158 
0159 } // namespace boost
0160 
0161 #endif  // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED