]> git.lyx.org Git - lyx.git/blob - boost/boost/smart_ptr/enable_shared_from_this2.hpp
Don't need this.
[lyx.git] / boost / boost / smart_ptr / enable_shared_from_this2.hpp
1 #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED\r
2 #define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED\r
3 \r
4 //\r
5 //  enable_shared_from_this2.hpp\r
6 //\r
7 //  Copyright 2002, 2009 Peter Dimov\r
8 //  Copyright 2008 Frank Mori Hess\r
9 //\r
10 //  Distributed under the Boost Software License, Version 1.0.\r
11 //  See accompanying file LICENSE_1_0.txt or copy at\r
12 //  http://www.boost.org/LICENSE_1_0.txt\r
13 //\r
14 \r
15 #include <boost/config.hpp>\r
16 #include <boost/shared_ptr.hpp>\r
17 #include <boost/assert.hpp>\r
18 #include <boost/detail/workaround.hpp>\r
19 \r
20 namespace boost\r
21 {\r
22 \r
23 namespace detail\r
24 {\r
25 \r
26 class esft2_deleter_wrapper\r
27 {\r
28 private:\r
29 \r
30     shared_ptr<void> deleter_;\r
31 \r
32 public:\r
33 \r
34     esft2_deleter_wrapper()\r
35     {\r
36     }\r
37 \r
38     template< class T > void set_deleter( shared_ptr<T> const & deleter )\r
39     {\r
40         deleter_ = deleter;\r
41     }\r
42 \r
43     template< class T> void operator()( T* )\r
44     {\r
45         BOOST_ASSERT( deleter_.use_count() <= 1 );\r
46         deleter_.reset();\r
47     }\r
48 };\r
49 \r
50 } // namespace detail\r
51 \r
52 template< class T > class enable_shared_from_this2\r
53 {\r
54 protected:\r
55 \r
56     enable_shared_from_this2()\r
57     {\r
58     }\r
59 \r
60     enable_shared_from_this2( enable_shared_from_this2 const & )\r
61     {\r
62     }\r
63 \r
64     enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )\r
65     {\r
66         return *this;\r
67     }\r
68 \r
69     ~enable_shared_from_this2()\r
70     {\r
71         BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist\r
72     }\r
73 \r
74 private:\r
75 \r
76     mutable weak_ptr<T> weak_this_;\r
77     mutable shared_ptr<T> shared_this_;\r
78 \r
79 public:\r
80 \r
81     shared_ptr<T> shared_from_this()\r
82     {\r
83         init_weak_once();\r
84         return shared_ptr<T>( weak_this_ );\r
85     }\r
86 \r
87     shared_ptr<T const> shared_from_this() const\r
88     {\r
89         init_weak_once();\r
90         return shared_ptr<T>( weak_this_ );\r
91     }\r
92 \r
93 private:\r
94 \r
95     void init_weak_once() const\r
96     {\r
97         if( weak_this_._empty() )\r
98         {\r
99             shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );\r
100             weak_this_ = shared_this_;\r
101         }\r
102     }\r
103 \r
104 public: // actually private, but avoids compiler template friendship issues\r
105 \r
106     // Note: invoked automatically by shared_ptr; do not call\r
107     template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const\r
108     {\r
109         BOOST_ASSERT( ppx != 0 );\r
110 \r
111         if( weak_this_.use_count() == 0 )\r
112         {\r
113             weak_this_ = shared_ptr<T>( *ppx, py );\r
114         }\r
115         else if( shared_this_.use_count() != 0 )\r
116         {\r
117             BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that\r
118 \r
119             detail::esft2_deleter_wrapper * pd = boost::get_deleter<detail::esft2_deleter_wrapper>( shared_this_ );\r
120             BOOST_ASSERT( pd != 0 );\r
121 \r
122             pd->set_deleter( *ppx );\r
123 \r
124             ppx->reset( shared_this_, ppx->get() );\r
125             shared_this_.reset();\r
126         }\r
127     }\r
128 };\r
129 \r
130 } // namespace boost\r
131 \r
132 #endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED\r