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
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 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 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
216template<class P, class D, class A> class BOOST_SYMBOL_VISIBLE sp_counted_impl_pda: public sp_counted_base
217{
218private:
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
229public:
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
290

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