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/core/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
38namespace boost
39{
40
41#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
42
43void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
44void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
45
46#endif
47
48namespace detail
49{
50
51// get_local_deleter
52
53template<class D> class local_sp_deleter;
54
55template<class D> D * get_local_deleter( D * /*p*/ ) BOOST_SP_NOEXCEPT
56{
57 return 0;
58}
59
60template<class D> D * get_local_deleter( local_sp_deleter<D> * p ) BOOST_SP_NOEXCEPT;
61
62//
63
64template<class X> class BOOST_SYMBOL_VISIBLE sp_counted_impl_p: public sp_counted_base
65{
66private:
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
75public:
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
143template<class P, class D> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pd: public sp_counted_base
144{
145private:
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
155public:
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
226template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
227{
228private:
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
239public:
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
310

source code of boost/libs/smart_ptr/include/boost/smart_ptr/detail/sp_counted_impl.hpp