Chris@16
|
1 #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
Chris@16
|
2 #define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|
Chris@16
|
3
|
Chris@16
|
4 //
|
Chris@16
|
5 // enable_shared_from_raw.hpp
|
Chris@16
|
6 //
|
Chris@101
|
7 // Copyright 2002, 2009, 2014 Peter Dimov
|
Chris@16
|
8 // Copyright 2008-2009 Frank Mori Hess
|
Chris@16
|
9 //
|
Chris@16
|
10 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
11 // See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
12 // http://www.boost.org/LICENSE_1_0.txt
|
Chris@16
|
13 //
|
Chris@16
|
14
|
Chris@16
|
15 #include <boost/config.hpp>
|
Chris@16
|
16 #include <boost/shared_ptr.hpp>
|
Chris@16
|
17 #include <boost/weak_ptr.hpp>
|
Chris@16
|
18 #include <boost/assert.hpp>
|
Chris@16
|
19 #include <boost/detail/workaround.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 namespace boost
|
Chris@16
|
22 {
|
Chris@16
|
23 template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
|
Chris@16
|
24 template<typename T> boost::weak_ptr<T> weak_from_raw(T *);
|
Chris@16
|
25
|
Chris@16
|
26 namespace detail
|
Chris@16
|
27 {
|
Chris@16
|
28 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 );
|
Chris@16
|
29
|
Chris@16
|
30 } // namespace detail
|
Chris@16
|
31
|
Chris@16
|
32 class enable_shared_from_raw
|
Chris@16
|
33 {
|
Chris@16
|
34 protected:
|
Chris@16
|
35
|
Chris@16
|
36 enable_shared_from_raw()
|
Chris@16
|
37 {
|
Chris@16
|
38 }
|
Chris@16
|
39
|
Chris@16
|
40 enable_shared_from_raw( enable_shared_from_raw const & )
|
Chris@16
|
41 {
|
Chris@16
|
42 }
|
Chris@16
|
43
|
Chris@16
|
44 enable_shared_from_raw & operator=( enable_shared_from_raw const & )
|
Chris@16
|
45 {
|
Chris@16
|
46 return *this;
|
Chris@16
|
47 }
|
Chris@16
|
48
|
Chris@16
|
49 ~enable_shared_from_raw()
|
Chris@16
|
50 {
|
Chris@16
|
51 BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
|
Chris@16
|
52 }
|
Chris@16
|
53
|
Chris@16
|
54 private:
|
Chris@16
|
55
|
Chris@101
|
56 void init_if_expired() const
|
Chris@16
|
57 {
|
Chris@16
|
58 if( weak_this_.expired() )
|
Chris@16
|
59 {
|
Chris@16
|
60 shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
Chris@16
|
61 weak_this_ = shared_this_;
|
Chris@16
|
62 }
|
Chris@16
|
63 }
|
Chris@16
|
64
|
Chris@101
|
65 void init_if_empty() const
|
Chris@101
|
66 {
|
Chris@101
|
67 if( weak_this_._empty() )
|
Chris@101
|
68 {
|
Chris@101
|
69 shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
|
Chris@101
|
70 weak_this_ = shared_this_;
|
Chris@101
|
71 }
|
Chris@101
|
72 }
|
Chris@101
|
73
|
Chris@16
|
74 #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
Chris@16
|
75 public:
|
Chris@16
|
76 #else
|
Chris@16
|
77 private:
|
Chris@16
|
78 template<class Y> friend class shared_ptr;
|
Chris@16
|
79 template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
|
Chris@16
|
80 template<typename T> friend boost::weak_ptr<T> weak_from_raw(T *);
|
Chris@16
|
81 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 );
|
Chris@16
|
82 #endif
|
Chris@16
|
83
|
Chris@101
|
84 shared_ptr<void const volatile> shared_from_this() const
|
Chris@16
|
85 {
|
Chris@101
|
86 init_if_expired();
|
Chris@101
|
87 return shared_ptr<void const volatile>( weak_this_ );
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@101
|
90 shared_ptr<void const volatile> shared_from_this() const volatile
|
Chris@16
|
91 {
|
Chris@101
|
92 return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
|
Chris@101
|
93 }
|
Chris@101
|
94
|
Chris@101
|
95 weak_ptr<void const volatile> weak_from_this() const
|
Chris@101
|
96 {
|
Chris@101
|
97 init_if_empty();
|
Chris@101
|
98 return weak_this_;
|
Chris@101
|
99 }
|
Chris@101
|
100
|
Chris@101
|
101 weak_ptr<void const volatile> weak_from_this() const volatile
|
Chris@101
|
102 {
|
Chris@101
|
103 return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 // Note: invoked automatically by shared_ptr; do not call
|
Chris@16
|
107 template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
|
Chris@16
|
108 {
|
Chris@16
|
109 BOOST_ASSERT( ppx != 0 );
|
Chris@16
|
110
|
Chris@16
|
111 if( weak_this_.expired() )
|
Chris@16
|
112 {
|
Chris@16
|
113 weak_this_ = *ppx;
|
Chris@16
|
114 }
|
Chris@16
|
115 else if( shared_this_.use_count() != 0 )
|
Chris@16
|
116 {
|
Chris@16
|
117 BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that
|
Chris@16
|
118
|
Chris@16
|
119 detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );
|
Chris@16
|
120 BOOST_ASSERT( pd != 0 );
|
Chris@16
|
121
|
Chris@16
|
122 pd->set_deleter( *ppx );
|
Chris@16
|
123
|
Chris@16
|
124 ppx->reset( shared_this_, ppx->get() );
|
Chris@16
|
125 shared_this_.reset();
|
Chris@16
|
126 }
|
Chris@16
|
127 }
|
Chris@16
|
128
|
Chris@101
|
129 mutable weak_ptr<void const volatile> weak_this_;
|
Chris@101
|
130
|
Chris@16
|
131 private:
|
Chris@101
|
132
|
Chris@101
|
133 mutable shared_ptr<void const volatile> shared_this_;
|
Chris@16
|
134 };
|
Chris@16
|
135
|
Chris@16
|
136 template<typename T>
|
Chris@16
|
137 boost::shared_ptr<T> shared_from_raw(T *p)
|
Chris@16
|
138 {
|
Chris@16
|
139 BOOST_ASSERT(p != 0);
|
Chris@16
|
140 return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
|
Chris@16
|
141 }
|
Chris@16
|
142
|
Chris@16
|
143 template<typename T>
|
Chris@16
|
144 boost::weak_ptr<T> weak_from_raw(T *p)
|
Chris@16
|
145 {
|
Chris@16
|
146 BOOST_ASSERT(p != 0);
|
Chris@16
|
147 boost::weak_ptr<T> result;
|
Chris@101
|
148 result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
|
Chris@16
|
149 return result;
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 namespace detail
|
Chris@16
|
153 {
|
Chris@16
|
154 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 )
|
Chris@16
|
155 {
|
Chris@16
|
156 if( pe != 0 )
|
Chris@16
|
157 {
|
Chris@16
|
158 pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
|
Chris@16
|
159 }
|
Chris@16
|
160 }
|
Chris@16
|
161 } // namepsace detail
|
Chris@16
|
162
|
Chris@16
|
163 } // namespace boost
|
Chris@16
|
164
|
Chris@16
|
165 #endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
|