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