]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/sp_counted_impl.hpp
import quincy beta 17.1.0
[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 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 sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
160 {
161 }
162
163 sp_counted_impl_pd( P p ): ptr( p ), del()
164 {
165 }
166
167 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
168 {
169 del( ptr );
170 }
171
172 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
173 {
174 return ti == BOOST_SP_TYPEID_(D)? &reinterpret_cast<char&>( del ): 0;
175 }
176
177 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
178 {
179 return ti == BOOST_SP_TYPEID_(D)? boost::detail::get_local_deleter( boost::addressof( del ) ): 0;
180 }
181
182 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
183 {
184 return &reinterpret_cast<char&>( del );
185 }
186
187 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
188
189 void * operator new( std::size_t )
190 {
191 return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
192 }
193
194 void operator delete( void * p )
195 {
196 std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
197 }
198
199 #endif
200
201 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
202
203 void * operator new( std::size_t )
204 {
205 return quick_allocator<this_type>::alloc();
206 }
207
208 void operator delete( void * p )
209 {
210 quick_allocator<this_type>::dealloc( p );
211 }
212
213 #endif
214 };
215
216 template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
217 {
218 private:
219
220 P p_; // copy constructor must not throw
221 D d_; // copy constructor must not throw
222 A a_; // copy constructor must not throw
223
224 sp_counted_impl_pda( sp_counted_impl_pda const & );
225 sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
226
227 typedef sp_counted_impl_pda<P, D, A> this_type;
228
229 public:
230
231 // pre: d( p ) must not throw
232
233 sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
234 {
235 }
236
237 sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
238 {
239 }
240
241 void dispose() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
242 {
243 d_( p_ );
244 }
245
246 void destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
247 {
248 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
249
250 typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
251
252 #else
253
254 typedef typename A::template rebind< this_type >::other A2;
255
256 #endif
257
258 A2 a2( a_ );
259
260 this->~this_type();
261
262 a2.deallocate( this, 1 );
263 }
264
265 void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
266 {
267 return ti == BOOST_SP_TYPEID_( D )? &reinterpret_cast<char&>( d_ ): 0;
268 }
269
270 void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT BOOST_OVERRIDE
271 {
272 return ti == BOOST_SP_TYPEID_( D )? boost::detail::get_local_deleter( boost::addressof( d_ ) ): 0;
273 }
274
275 void * get_untyped_deleter() BOOST_SP_NOEXCEPT BOOST_OVERRIDE
276 {
277 return &reinterpret_cast<char&>( d_ );
278 }
279 };
280
281 #ifdef __CODEGUARD__
282 # pragma option pop
283 #endif
284
285 } // namespace detail
286
287 } // namespace boost
288
289 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED