Chris@16
|
1 #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|
Chris@16
|
2 #define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_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/shared_count.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 #ifdef __BORLANDC__
|
Chris@16
|
22 # pragma warn -8027 // Functions containing try are not expanded inline
|
Chris@16
|
23 #endif
|
Chris@16
|
24
|
Chris@16
|
25 #include <boost/config.hpp>
|
Chris@16
|
26 #include <boost/checked_delete.hpp>
|
Chris@16
|
27 #include <boost/throw_exception.hpp>
|
Chris@16
|
28 #include <boost/smart_ptr/bad_weak_ptr.hpp>
|
Chris@16
|
29 #include <boost/smart_ptr/detail/sp_counted_base.hpp>
|
Chris@16
|
30 #include <boost/smart_ptr/detail/sp_counted_impl.hpp>
|
Chris@16
|
31 #include <boost/detail/workaround.hpp>
|
Chris@16
|
32 // In order to avoid circular dependencies with Boost.TR1
|
Chris@16
|
33 // we make sure that our include of <memory> doesn't try to
|
Chris@16
|
34 // pull in the TR1 headers: that's why we use this header
|
Chris@16
|
35 // rather than including <memory> directly:
|
Chris@16
|
36 #include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
|
Chris@16
|
37 #include <functional> // std::less
|
Chris@16
|
38
|
Chris@16
|
39 #ifdef BOOST_NO_EXCEPTIONS
|
Chris@16
|
40 # include <new> // std::bad_alloc
|
Chris@16
|
41 #endif
|
Chris@16
|
42
|
Chris@16
|
43 #if !defined( BOOST_NO_CXX11_SMART_PTR )
|
Chris@16
|
44 # include <boost/utility/addressof.hpp>
|
Chris@16
|
45 #endif
|
Chris@16
|
46
|
Chris@16
|
47 namespace boost
|
Chris@16
|
48 {
|
Chris@16
|
49
|
Chris@16
|
50 namespace detail
|
Chris@16
|
51 {
|
Chris@16
|
52
|
Chris@16
|
53 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
54
|
Chris@16
|
55 int const shared_count_id = 0x2C35F101;
|
Chris@16
|
56 int const weak_count_id = 0x298C38A4;
|
Chris@16
|
57
|
Chris@16
|
58 #endif
|
Chris@16
|
59
|
Chris@16
|
60 struct sp_nothrow_tag {};
|
Chris@16
|
61
|
Chris@16
|
62 template< class D > struct sp_inplace_tag
|
Chris@16
|
63 {
|
Chris@16
|
64 };
|
Chris@16
|
65
|
Chris@16
|
66 #if !defined( BOOST_NO_CXX11_SMART_PTR )
|
Chris@16
|
67
|
Chris@16
|
68 template< class T > class sp_reference_wrapper
|
Chris@16
|
69 {
|
Chris@16
|
70 public:
|
Chris@16
|
71
|
Chris@16
|
72 explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
|
Chris@16
|
73 {
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 template< class Y > void operator()( Y * p ) const
|
Chris@16
|
77 {
|
Chris@16
|
78 (*t_)( p );
|
Chris@16
|
79 }
|
Chris@16
|
80
|
Chris@16
|
81 private:
|
Chris@16
|
82
|
Chris@16
|
83 T * t_;
|
Chris@16
|
84 };
|
Chris@16
|
85
|
Chris@16
|
86 template< class D > struct sp_convert_reference
|
Chris@16
|
87 {
|
Chris@16
|
88 typedef D type;
|
Chris@16
|
89 };
|
Chris@16
|
90
|
Chris@16
|
91 template< class D > struct sp_convert_reference< D& >
|
Chris@16
|
92 {
|
Chris@16
|
93 typedef sp_reference_wrapper< D > type;
|
Chris@16
|
94 };
|
Chris@16
|
95
|
Chris@16
|
96 #endif
|
Chris@16
|
97
|
Chris@16
|
98 class weak_count;
|
Chris@16
|
99
|
Chris@16
|
100 class shared_count
|
Chris@16
|
101 {
|
Chris@16
|
102 private:
|
Chris@16
|
103
|
Chris@16
|
104 sp_counted_base * pi_;
|
Chris@16
|
105
|
Chris@16
|
106 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
107 int id_;
|
Chris@16
|
108 #endif
|
Chris@16
|
109
|
Chris@16
|
110 friend class weak_count;
|
Chris@16
|
111
|
Chris@16
|
112 public:
|
Chris@16
|
113
|
Chris@16
|
114 shared_count(): pi_(0) // nothrow
|
Chris@16
|
115 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
116 , id_(shared_count_id)
|
Chris@16
|
117 #endif
|
Chris@16
|
118 {
|
Chris@16
|
119 }
|
Chris@16
|
120
|
Chris@16
|
121 template<class Y> explicit shared_count( Y * p ): pi_( 0 )
|
Chris@16
|
122 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
123 , id_(shared_count_id)
|
Chris@16
|
124 #endif
|
Chris@16
|
125 {
|
Chris@16
|
126 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
127
|
Chris@16
|
128 try
|
Chris@16
|
129 {
|
Chris@16
|
130 pi_ = new sp_counted_impl_p<Y>( p );
|
Chris@16
|
131 }
|
Chris@16
|
132 catch(...)
|
Chris@16
|
133 {
|
Chris@16
|
134 boost::checked_delete( p );
|
Chris@16
|
135 throw;
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 #else
|
Chris@16
|
139
|
Chris@16
|
140 pi_ = new sp_counted_impl_p<Y>( p );
|
Chris@16
|
141
|
Chris@16
|
142 if( pi_ == 0 )
|
Chris@16
|
143 {
|
Chris@16
|
144 boost::checked_delete( p );
|
Chris@16
|
145 boost::throw_exception( std::bad_alloc() );
|
Chris@16
|
146 }
|
Chris@16
|
147
|
Chris@16
|
148 #endif
|
Chris@16
|
149 }
|
Chris@16
|
150
|
Chris@16
|
151 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
Chris@16
|
152 template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
|
Chris@16
|
153 #else
|
Chris@16
|
154 template<class P, class D> shared_count( P p, D d ): pi_(0)
|
Chris@16
|
155 #endif
|
Chris@16
|
156 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
157 , id_(shared_count_id)
|
Chris@16
|
158 #endif
|
Chris@16
|
159 {
|
Chris@16
|
160 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
|
Chris@16
|
161 typedef Y* P;
|
Chris@16
|
162 #endif
|
Chris@16
|
163 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
164
|
Chris@16
|
165 try
|
Chris@16
|
166 {
|
Chris@16
|
167 pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
Chris@16
|
168 }
|
Chris@16
|
169 catch(...)
|
Chris@16
|
170 {
|
Chris@16
|
171 d(p); // delete p
|
Chris@16
|
172 throw;
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 #else
|
Chris@16
|
176
|
Chris@16
|
177 pi_ = new sp_counted_impl_pd<P, D>(p, d);
|
Chris@16
|
178
|
Chris@16
|
179 if(pi_ == 0)
|
Chris@16
|
180 {
|
Chris@16
|
181 d(p); // delete p
|
Chris@16
|
182 boost::throw_exception(std::bad_alloc());
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 #endif
|
Chris@16
|
186 }
|
Chris@16
|
187
|
Chris@16
|
188 #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
Chris@16
|
189
|
Chris@16
|
190 template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
|
Chris@16
|
191 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
192 , id_(shared_count_id)
|
Chris@16
|
193 #endif
|
Chris@16
|
194 {
|
Chris@16
|
195 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
196
|
Chris@16
|
197 try
|
Chris@16
|
198 {
|
Chris@16
|
199 pi_ = new sp_counted_impl_pd< P, D >( p );
|
Chris@16
|
200 }
|
Chris@16
|
201 catch( ... )
|
Chris@16
|
202 {
|
Chris@16
|
203 D::operator_fn( p ); // delete p
|
Chris@16
|
204 throw;
|
Chris@16
|
205 }
|
Chris@16
|
206
|
Chris@16
|
207 #else
|
Chris@16
|
208
|
Chris@16
|
209 pi_ = new sp_counted_impl_pd< P, D >( p );
|
Chris@16
|
210
|
Chris@16
|
211 if( pi_ == 0 )
|
Chris@16
|
212 {
|
Chris@16
|
213 D::operator_fn( p ); // delete p
|
Chris@16
|
214 boost::throw_exception( std::bad_alloc() );
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 #endif // #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
218 }
|
Chris@16
|
219
|
Chris@16
|
220 #endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
Chris@16
|
221
|
Chris@16
|
222 template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
|
Chris@16
|
223 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
224 , id_(shared_count_id)
|
Chris@16
|
225 #endif
|
Chris@16
|
226 {
|
Chris@16
|
227 typedef sp_counted_impl_pda<P, D, A> impl_type;
|
Chris@101
|
228
|
Chris@101
|
229 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
230
|
Chris@101
|
231 typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
Chris@101
|
232
|
Chris@101
|
233 #else
|
Chris@101
|
234
|
Chris@16
|
235 typedef typename A::template rebind< impl_type >::other A2;
|
Chris@16
|
236
|
Chris@101
|
237 #endif
|
Chris@101
|
238
|
Chris@16
|
239 A2 a2( a );
|
Chris@16
|
240
|
Chris@16
|
241 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
242
|
Chris@16
|
243 try
|
Chris@16
|
244 {
|
Chris@101
|
245 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
246
|
Chris@101
|
247 impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
Chris@101
|
248 pi_ = pi;
|
Chris@101
|
249 std::allocator_traits<A2>::construct( a2, pi, p, d, a );
|
Chris@101
|
250
|
Chris@101
|
251 #else
|
Chris@101
|
252
|
Chris@16
|
253 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
Chris@101
|
254 ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
Chris@101
|
255
|
Chris@101
|
256 #endif
|
Chris@16
|
257 }
|
Chris@16
|
258 catch(...)
|
Chris@16
|
259 {
|
Chris@16
|
260 d( p );
|
Chris@16
|
261
|
Chris@16
|
262 if( pi_ != 0 )
|
Chris@16
|
263 {
|
Chris@16
|
264 a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
Chris@16
|
265 }
|
Chris@16
|
266
|
Chris@16
|
267 throw;
|
Chris@16
|
268 }
|
Chris@16
|
269
|
Chris@16
|
270 #else
|
Chris@16
|
271
|
Chris@101
|
272 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
273
|
Chris@101
|
274 impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
Chris@101
|
275 pi_ = pi;
|
Chris@101
|
276
|
Chris@101
|
277 #else
|
Chris@101
|
278
|
Chris@16
|
279 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
Chris@16
|
280
|
Chris@101
|
281 #endif
|
Chris@101
|
282
|
Chris@16
|
283 if( pi_ != 0 )
|
Chris@16
|
284 {
|
Chris@101
|
285 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
286
|
Chris@101
|
287 std::allocator_traits<A2>::construct( a2, pi, p, d, a );
|
Chris@101
|
288
|
Chris@101
|
289 #else
|
Chris@101
|
290
|
Chris@101
|
291 ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
|
Chris@101
|
292
|
Chris@101
|
293 #endif
|
Chris@16
|
294 }
|
Chris@16
|
295 else
|
Chris@16
|
296 {
|
Chris@16
|
297 d( p );
|
Chris@16
|
298 boost::throw_exception( std::bad_alloc() );
|
Chris@16
|
299 }
|
Chris@16
|
300
|
Chris@16
|
301 #endif
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
Chris@16
|
305
|
Chris@16
|
306 template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
|
Chris@16
|
307 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
308 , id_(shared_count_id)
|
Chris@16
|
309 #endif
|
Chris@16
|
310 {
|
Chris@16
|
311 typedef sp_counted_impl_pda< P, D, A > impl_type;
|
Chris@101
|
312
|
Chris@101
|
313 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
314
|
Chris@101
|
315 typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
|
Chris@101
|
316
|
Chris@101
|
317 #else
|
Chris@101
|
318
|
Chris@16
|
319 typedef typename A::template rebind< impl_type >::other A2;
|
Chris@16
|
320
|
Chris@101
|
321 #endif
|
Chris@101
|
322
|
Chris@16
|
323 A2 a2( a );
|
Chris@16
|
324
|
Chris@16
|
325 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
326
|
Chris@16
|
327 try
|
Chris@16
|
328 {
|
Chris@101
|
329 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
330
|
Chris@101
|
331 impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
Chris@101
|
332 pi_ = pi;
|
Chris@101
|
333 std::allocator_traits<A2>::construct( a2, pi, p, a );
|
Chris@101
|
334
|
Chris@101
|
335 #else
|
Chris@101
|
336
|
Chris@16
|
337 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
Chris@101
|
338 ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
Chris@101
|
339
|
Chris@101
|
340 #endif
|
Chris@16
|
341 }
|
Chris@16
|
342 catch(...)
|
Chris@16
|
343 {
|
Chris@16
|
344 D::operator_fn( p );
|
Chris@16
|
345
|
Chris@16
|
346 if( pi_ != 0 )
|
Chris@16
|
347 {
|
Chris@16
|
348 a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
|
Chris@16
|
349 }
|
Chris@16
|
350
|
Chris@16
|
351 throw;
|
Chris@16
|
352 }
|
Chris@16
|
353
|
Chris@16
|
354 #else
|
Chris@16
|
355
|
Chris@101
|
356 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
357
|
Chris@101
|
358 impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
|
Chris@101
|
359 pi_ = pi;
|
Chris@101
|
360
|
Chris@101
|
361 #else
|
Chris@101
|
362
|
Chris@16
|
363 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
|
Chris@16
|
364
|
Chris@101
|
365 #endif
|
Chris@101
|
366
|
Chris@16
|
367 if( pi_ != 0 )
|
Chris@16
|
368 {
|
Chris@101
|
369 #if !defined( BOOST_NO_CXX11_ALLOCATOR )
|
Chris@101
|
370
|
Chris@101
|
371 std::allocator_traits<A2>::construct( a2, pi, p, a );
|
Chris@101
|
372
|
Chris@101
|
373 #else
|
Chris@101
|
374
|
Chris@101
|
375 ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
|
Chris@101
|
376
|
Chris@101
|
377 #endif
|
Chris@16
|
378 }
|
Chris@16
|
379 else
|
Chris@16
|
380 {
|
Chris@16
|
381 D::operator_fn( p );
|
Chris@16
|
382 boost::throw_exception( std::bad_alloc() );
|
Chris@16
|
383 }
|
Chris@16
|
384
|
Chris@16
|
385 #endif // #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
386 }
|
Chris@16
|
387
|
Chris@16
|
388 #endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
|
Chris@16
|
389
|
Chris@16
|
390 #ifndef BOOST_NO_AUTO_PTR
|
Chris@16
|
391
|
Chris@16
|
392 // auto_ptr<Y> is special cased to provide the strong guarantee
|
Chris@16
|
393
|
Chris@16
|
394 template<class Y>
|
Chris@16
|
395 explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
|
Chris@16
|
396 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
397 , id_(shared_count_id)
|
Chris@16
|
398 #endif
|
Chris@16
|
399 {
|
Chris@16
|
400 #ifdef BOOST_NO_EXCEPTIONS
|
Chris@16
|
401
|
Chris@16
|
402 if( pi_ == 0 )
|
Chris@16
|
403 {
|
Chris@16
|
404 boost::throw_exception(std::bad_alloc());
|
Chris@16
|
405 }
|
Chris@16
|
406
|
Chris@16
|
407 #endif
|
Chris@16
|
408
|
Chris@16
|
409 r.release();
|
Chris@16
|
410 }
|
Chris@16
|
411
|
Chris@16
|
412 #endif
|
Chris@16
|
413
|
Chris@16
|
414 #if !defined( BOOST_NO_CXX11_SMART_PTR )
|
Chris@16
|
415
|
Chris@16
|
416 template<class Y, class D>
|
Chris@16
|
417 explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
|
Chris@16
|
418 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
419 , id_(shared_count_id)
|
Chris@16
|
420 #endif
|
Chris@16
|
421 {
|
Chris@16
|
422 typedef typename sp_convert_reference<D>::type D2;
|
Chris@16
|
423
|
Chris@16
|
424 D2 d2( r.get_deleter() );
|
Chris@16
|
425 pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
|
Chris@16
|
426
|
Chris@16
|
427 #ifdef BOOST_NO_EXCEPTIONS
|
Chris@16
|
428
|
Chris@16
|
429 if( pi_ == 0 )
|
Chris@16
|
430 {
|
Chris@16
|
431 boost::throw_exception( std::bad_alloc() );
|
Chris@16
|
432 }
|
Chris@16
|
433
|
Chris@16
|
434 #endif
|
Chris@16
|
435
|
Chris@16
|
436 r.release();
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 #endif
|
Chris@16
|
440
|
Chris@16
|
441 ~shared_count() // nothrow
|
Chris@16
|
442 {
|
Chris@16
|
443 if( pi_ != 0 ) pi_->release();
|
Chris@16
|
444 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
445 id_ = 0;
|
Chris@16
|
446 #endif
|
Chris@16
|
447 }
|
Chris@16
|
448
|
Chris@16
|
449 shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
450 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
451 , id_(shared_count_id)
|
Chris@16
|
452 #endif
|
Chris@16
|
453 {
|
Chris@16
|
454 if( pi_ != 0 ) pi_->add_ref_copy();
|
Chris@16
|
455 }
|
Chris@16
|
456
|
Chris@16
|
457 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
Chris@16
|
458
|
Chris@16
|
459 shared_count(shared_count && r): pi_(r.pi_) // nothrow
|
Chris@16
|
460 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
461 , id_(shared_count_id)
|
Chris@16
|
462 #endif
|
Chris@16
|
463 {
|
Chris@16
|
464 r.pi_ = 0;
|
Chris@16
|
465 }
|
Chris@16
|
466
|
Chris@16
|
467 #endif
|
Chris@16
|
468
|
Chris@16
|
469 explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
Chris@16
|
470 shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
|
Chris@16
|
471
|
Chris@16
|
472 shared_count & operator= (shared_count const & r) // nothrow
|
Chris@16
|
473 {
|
Chris@16
|
474 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
475
|
Chris@16
|
476 if( tmp != pi_ )
|
Chris@16
|
477 {
|
Chris@16
|
478 if( tmp != 0 ) tmp->add_ref_copy();
|
Chris@16
|
479 if( pi_ != 0 ) pi_->release();
|
Chris@16
|
480 pi_ = tmp;
|
Chris@16
|
481 }
|
Chris@16
|
482
|
Chris@16
|
483 return *this;
|
Chris@16
|
484 }
|
Chris@16
|
485
|
Chris@16
|
486 void swap(shared_count & r) // nothrow
|
Chris@16
|
487 {
|
Chris@16
|
488 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
489 r.pi_ = pi_;
|
Chris@16
|
490 pi_ = tmp;
|
Chris@16
|
491 }
|
Chris@16
|
492
|
Chris@16
|
493 long use_count() const // nothrow
|
Chris@16
|
494 {
|
Chris@16
|
495 return pi_ != 0? pi_->use_count(): 0;
|
Chris@16
|
496 }
|
Chris@16
|
497
|
Chris@16
|
498 bool unique() const // nothrow
|
Chris@16
|
499 {
|
Chris@16
|
500 return use_count() == 1;
|
Chris@16
|
501 }
|
Chris@16
|
502
|
Chris@16
|
503 bool empty() const // nothrow
|
Chris@16
|
504 {
|
Chris@16
|
505 return pi_ == 0;
|
Chris@16
|
506 }
|
Chris@16
|
507
|
Chris@16
|
508 friend inline bool operator==(shared_count const & a, shared_count const & b)
|
Chris@16
|
509 {
|
Chris@16
|
510 return a.pi_ == b.pi_;
|
Chris@16
|
511 }
|
Chris@16
|
512
|
Chris@16
|
513 friend inline bool operator<(shared_count const & a, shared_count const & b)
|
Chris@16
|
514 {
|
Chris@16
|
515 return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
|
Chris@16
|
516 }
|
Chris@16
|
517
|
Chris@16
|
518 void * get_deleter( sp_typeinfo const & ti ) const
|
Chris@16
|
519 {
|
Chris@16
|
520 return pi_? pi_->get_deleter( ti ): 0;
|
Chris@16
|
521 }
|
Chris@16
|
522
|
Chris@16
|
523 void * get_untyped_deleter() const
|
Chris@16
|
524 {
|
Chris@16
|
525 return pi_? pi_->get_untyped_deleter(): 0;
|
Chris@16
|
526 }
|
Chris@16
|
527 };
|
Chris@16
|
528
|
Chris@16
|
529
|
Chris@16
|
530 class weak_count
|
Chris@16
|
531 {
|
Chris@16
|
532 private:
|
Chris@16
|
533
|
Chris@16
|
534 sp_counted_base * pi_;
|
Chris@16
|
535
|
Chris@16
|
536 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
537 int id_;
|
Chris@16
|
538 #endif
|
Chris@16
|
539
|
Chris@16
|
540 friend class shared_count;
|
Chris@16
|
541
|
Chris@16
|
542 public:
|
Chris@16
|
543
|
Chris@16
|
544 weak_count(): pi_(0) // nothrow
|
Chris@16
|
545 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
546 , id_(weak_count_id)
|
Chris@16
|
547 #endif
|
Chris@16
|
548 {
|
Chris@16
|
549 }
|
Chris@16
|
550
|
Chris@16
|
551 weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
552 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
553 , id_(weak_count_id)
|
Chris@16
|
554 #endif
|
Chris@16
|
555 {
|
Chris@16
|
556 if(pi_ != 0) pi_->weak_add_ref();
|
Chris@16
|
557 }
|
Chris@16
|
558
|
Chris@16
|
559 weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
560 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
561 , id_(weak_count_id)
|
Chris@16
|
562 #endif
|
Chris@16
|
563 {
|
Chris@16
|
564 if(pi_ != 0) pi_->weak_add_ref();
|
Chris@16
|
565 }
|
Chris@16
|
566
|
Chris@16
|
567 // Move support
|
Chris@16
|
568
|
Chris@16
|
569 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
|
Chris@16
|
570
|
Chris@16
|
571 weak_count(weak_count && r): pi_(r.pi_) // nothrow
|
Chris@16
|
572 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
573 , id_(weak_count_id)
|
Chris@16
|
574 #endif
|
Chris@16
|
575 {
|
Chris@16
|
576 r.pi_ = 0;
|
Chris@16
|
577 }
|
Chris@16
|
578
|
Chris@16
|
579 #endif
|
Chris@16
|
580
|
Chris@16
|
581 ~weak_count() // nothrow
|
Chris@16
|
582 {
|
Chris@16
|
583 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
584 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
585 id_ = 0;
|
Chris@16
|
586 #endif
|
Chris@16
|
587 }
|
Chris@16
|
588
|
Chris@16
|
589 weak_count & operator= (shared_count const & r) // nothrow
|
Chris@16
|
590 {
|
Chris@16
|
591 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
592
|
Chris@16
|
593 if( tmp != pi_ )
|
Chris@16
|
594 {
|
Chris@16
|
595 if(tmp != 0) tmp->weak_add_ref();
|
Chris@16
|
596 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
597 pi_ = tmp;
|
Chris@16
|
598 }
|
Chris@16
|
599
|
Chris@16
|
600 return *this;
|
Chris@16
|
601 }
|
Chris@16
|
602
|
Chris@16
|
603 weak_count & operator= (weak_count const & r) // nothrow
|
Chris@16
|
604 {
|
Chris@16
|
605 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
606
|
Chris@16
|
607 if( tmp != pi_ )
|
Chris@16
|
608 {
|
Chris@16
|
609 if(tmp != 0) tmp->weak_add_ref();
|
Chris@16
|
610 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
611 pi_ = tmp;
|
Chris@16
|
612 }
|
Chris@16
|
613
|
Chris@16
|
614 return *this;
|
Chris@16
|
615 }
|
Chris@16
|
616
|
Chris@16
|
617 void swap(weak_count & r) // nothrow
|
Chris@16
|
618 {
|
Chris@16
|
619 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
620 r.pi_ = pi_;
|
Chris@16
|
621 pi_ = tmp;
|
Chris@16
|
622 }
|
Chris@16
|
623
|
Chris@16
|
624 long use_count() const // nothrow
|
Chris@16
|
625 {
|
Chris@16
|
626 return pi_ != 0? pi_->use_count(): 0;
|
Chris@16
|
627 }
|
Chris@16
|
628
|
Chris@16
|
629 bool empty() const // nothrow
|
Chris@16
|
630 {
|
Chris@16
|
631 return pi_ == 0;
|
Chris@16
|
632 }
|
Chris@16
|
633
|
Chris@16
|
634 friend inline bool operator==(weak_count const & a, weak_count const & b)
|
Chris@16
|
635 {
|
Chris@16
|
636 return a.pi_ == b.pi_;
|
Chris@16
|
637 }
|
Chris@16
|
638
|
Chris@16
|
639 friend inline bool operator<(weak_count const & a, weak_count const & b)
|
Chris@16
|
640 {
|
Chris@16
|
641 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
Chris@16
|
642 }
|
Chris@16
|
643 };
|
Chris@16
|
644
|
Chris@16
|
645 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
|
Chris@16
|
646 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
647 , id_(shared_count_id)
|
Chris@16
|
648 #endif
|
Chris@16
|
649 {
|
Chris@16
|
650 if( pi_ == 0 || !pi_->add_ref_lock() )
|
Chris@16
|
651 {
|
Chris@16
|
652 boost::throw_exception( boost::bad_weak_ptr() );
|
Chris@16
|
653 }
|
Chris@16
|
654 }
|
Chris@16
|
655
|
Chris@16
|
656 inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
|
Chris@16
|
657 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
658 , id_(shared_count_id)
|
Chris@16
|
659 #endif
|
Chris@16
|
660 {
|
Chris@16
|
661 if( pi_ != 0 && !pi_->add_ref_lock() )
|
Chris@16
|
662 {
|
Chris@16
|
663 pi_ = 0;
|
Chris@16
|
664 }
|
Chris@16
|
665 }
|
Chris@16
|
666
|
Chris@16
|
667 } // namespace detail
|
Chris@16
|
668
|
Chris@16
|
669 } // namespace boost
|
Chris@16
|
670
|
Chris@16
|
671 #ifdef __BORLANDC__
|
Chris@16
|
672 # pragma warn .8027 // Functions containing try are not expanded inline
|
Chris@16
|
673 #endif
|
Chris@16
|
674
|
Chris@16
|
675 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
|