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