]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_impl.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_impl.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
3
4 // MS compatible compilers support #pragma once
5
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
7 # pragma once
8 #endif
9
10 //
11 // detail/sp_counted_impl.hpp
12 //
13 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
14 // Copyright 2004-2005 Peter Dimov
15 //
16 // Distributed under the Boost Software License, Version 1.0. (See
17 // accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19 //
20
21 #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
22 # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
23 #endif
24
25 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
26 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
27 #include <boost/checked_delete.hpp>
28 #include <boost/core/addressof.hpp>
29 #include <boost/config.hpp>
30
31 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
32 #include <boost/smart_ptr/detail/quick_allocator.hpp>
33 #endif
34
35 #include <memory> // std::allocator, std::allocator_traits
36 #include <cstddef> // std::size_t
37
38 namespace boost
39 {
40
41 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
42
43 void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
44 void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
45
46 #endif
47
48 namespace detail
49 {
50
51 // get_local_deleter
52
53 template<class D> class local_sp_deleter;
54
55 template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT
56 {
57 return 0;
58 }
59
60 template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT;
61
62 //
63
64 template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
65 {
66 private:
67
68 X * px_;
69
70 sp_counted_impl_p( sp_counted_impl_p const & );
71 sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
72
73 typedef sp_counted_impl_p<X> this_type;
74
75 public:
76
77 explicit sp_counted_impl_p( X * px ): px_( px )
78 {
79 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
80 boost::sp_scalar_constructor_hook( px, sizeof(X), this );
81 #endif
82 }
83
84 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
85 {
86 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
87 boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
88 #endif
89 boost::checked_delete( px_ );
90 }
91
92 void * get_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
93 {
94 return 0;
95 }
96
97 void * get_local_deleter( sp_typeinfo_ const & ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
98 {
99 return 0;
100 }
101
102 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
103 {
104 return 0;
105 }
106
107 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
108
109 void * operator new( std::size_t )
110 {
111 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
112 }
113
114 void operator delete( void * p )
115 {
116 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
117 }
118
119 #endif
120
121 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
122
123 void * operator new( std::size_t )
124 {
125 return quick_allocator<this_type>::alloc();
126 }
127
128 void operator delete( void * p )
129 {
130 quick_allocator<this_type>::dealloc( p );
131 }
132
133 #endif
134 };
135
136 //
137 // Borland's Codeguard trips up over the -Vx- option here:
138 //
139 #ifdef __CODEGUARD__
140 # pragma option push -Vx-
141 #endif
142
143 template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
144 {
145 private:
146
147 P ptr; // copy constructor must not throw
148 D del; // copy/move constructor must not throw
149
150 sp_counted_impl_pd( sp_counted_impl_pd const & );
151 sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
152
153 typedef sp_counted_impl_pd<P, D> this_type;
154
155 public:
156
157 // pre: d(p) must not throw
158
159 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
160
161 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( static_cast< D&& >( d ) )
162 {
163 }
164
165 #else
166
167 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
168 {
169 }
170
171 #endif
172
173 sp_counted_impl_pd( P p ): ptr( p ), del()
174 {
175 }
176
177 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
178 {
179 del( ptr );
180 }
181
182 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
183 {
184 return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
185 }
186
187 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
188 {
189 return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
190 }
191
192 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
193 {
194 return &reinterpret_cast<char&>( del );
195 }
196
197 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
198
199 void * operator new( std::size_t )
200 {
201 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
202 }
203
204 void operator delete( void * p )
205 {
206 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
207 }
208
209 #endif
210
211 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
212
213 void * operator new( std::size_t )
214 {
215 return quick_allocator<this_type>::alloc();
216 }
217
218 void operator delete( void * p )
219 {
220 quick_allocator<this_type>::dealloc( p );
221 }
222
223 #endif
224 };
225
226 template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
227 {
228 private:
229
230 P p_; // copy constructor must not throw
231 D d_; // copy/move constructor must not throw
232 A a_; // copy constructor must not throw
233
234 sp_counted_impl_pda( sp_counted_impl_pda const & );
235 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
236
237 typedef sp_counted_impl_pda<P, D, A> this_type;
238
239 public:
240
241 // pre: d( p ) must not throw
242
243 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
244
245 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( static_cast< D&& >( d ) ), a_( a )
246 {
247 }
248
249 #else
250
251 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
252 {
253 }
254
255 #endif
256
257 sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
258 {
259 }
260
261 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
262 {
263 d_( p_ );
264 }
265
266 void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
267 {
268 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
269
270 typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
271
272 #else
273
274 typedef typename A::template rebind< this_type >::other A2;
275
276 #endif
277
278 A2 a2( a_ );
279
280 this->~this_type();
281
282 a2.deallocate( this, 1 );
283 }
284
285 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
286 {
287 return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
288 }
289
290 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
291 {
292 return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
293 }
294
295 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
296 {
297 return &reinterpret_cast<char&>( d_ );
298 }
299 };
300
301 #ifdef __CODEGUARD__
302 # pragma option pop
303 #endif
304
305 } // namespace detail
306
307 } // namespace boost
308
309 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED