CppCMS
shared_count.h
1 #ifndef BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
2 #define BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
3 //
4 // detail/shared_count.hpp
5 //
6 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
7 // Copyright 2004-2005 Peter Dimov
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 //
13 
14 #ifdef __BORLANDC__
15 # pragma warn -8027 // Functions containing try are not expanded inline
16 #endif
17 
18 #include <booster/config.h>
19 #include <booster/checked_delete.h>
20 #include <booster/bad_weak_ptr.h>
21 #include <booster/smart_ptr/sp_counted_base.h>
22 #include <booster/smart_ptr/sp_counted_impl.h>
23 #include <booster/auto_ptr_inc.h>
24 #include <functional> // std::less
25 #include <new> // std::bad_alloc
26 
27 namespace booster
28 {
29 
30 namespace detail
31 {
32 
33 struct sp_nothrow_tag {};
34 
35 class weak_count;
36 
38 {
39 private:
40 
41  sp_counted_base * pi_;
42 
43  friend class weak_count;
44 
45 public:
46 
47  shared_count(): pi_(0) // nothrow
48  {
49  }
50 
51  template<class Y> explicit shared_count( Y * p ): pi_( 0 )
52  {
53  try
54  {
55  pi_ = new sp_counted_impl_p<Y>( p );
56  }
57  catch(...)
58  {
59  booster::checked_delete( p );
60  throw;
61  }
62  }
63 
64  template<class P, class D> shared_count( P p, D d ): pi_(0)
65  {
66  try
67  {
68  pi_ = new sp_counted_impl_pd<P, D>(p, d);
69  }
70  catch(...)
71  {
72  d(p); // delete p
73  throw;
74  }
75  }
76 
77  template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
78  {
79  typedef sp_counted_impl_pda<P, D, A> impl_type;
80  typedef typename A::template rebind< impl_type >::other A2;
81 
82  A2 a2( a );
83 
84  try
85  {
86  pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
87  new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
88  }
89  catch(...)
90  {
91  d( p );
92 
93  if( pi_ != 0 )
94  {
95  a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
96  }
97 
98  throw;
99  }
100 
101  }
102 
103  // auto_ptr<Y> is special cased to provide the strong guarantee
104 
105  template<class Y>
106  explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
107  {
108 
109  r.release();
110  }
111 
112 
113  ~shared_count() // nothrow
114  {
115  if( pi_ != 0 ) pi_->release();
116  }
117 
118  shared_count(shared_count const & r): pi_(r.pi_) // nothrow
119  {
120  if( pi_ != 0 ) pi_->add_ref_copy();
121  }
122 
123  explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
124  shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
125 
126  shared_count & operator= (shared_count const & r) // nothrow
127  {
128  sp_counted_base * tmp = r.pi_;
129 
130  if( tmp != pi_ )
131  {
132  if( tmp != 0 ) tmp->add_ref_copy();
133  if( pi_ != 0 ) pi_->release();
134  pi_ = tmp;
135  }
136 
137  return *this;
138  }
139 
140  void swap(shared_count & r) // nothrow
141  {
142  sp_counted_base * tmp = r.pi_;
143  r.pi_ = pi_;
144  pi_ = tmp;
145  }
146 
147  long use_count() const // nothrow
148  {
149  return pi_ != 0? pi_->use_count(): 0;
150  }
151 
152  bool unique() const // nothrow
153  {
154  return use_count() == 1;
155  }
156 
157  bool empty() const // nothrow
158  {
159  return pi_ == 0;
160  }
161 
162  friend inline bool operator==(shared_count const & a, shared_count const & b)
163  {
164  return a.pi_ == b.pi_;
165  }
166 
167  friend inline bool operator<(shared_count const & a, shared_count const & b)
168  {
169  return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
170  }
171 
172  void * get_deleter( sp_typeinfo const & ti ) const
173  {
174  return pi_? pi_->get_deleter( ti ): 0;
175  }
176 };
177 
178 
180 {
181 private:
182 
183  sp_counted_base * pi_;
184 
185  friend class shared_count;
186 
187 public:
188 
189  weak_count(): pi_(0) // nothrow
190  {
191  }
192 
193  weak_count(shared_count const & r): pi_(r.pi_) // nothrow
194  {
195  if(pi_ != 0) pi_->weak_add_ref();
196  }
197 
198  weak_count(weak_count const & r): pi_(r.pi_) // nothrow
199  {
200  if(pi_ != 0) pi_->weak_add_ref();
201  }
202 
203 
204  ~weak_count() // nothrow
205  {
206  if(pi_ != 0) pi_->weak_release();
207  }
208 
209  weak_count & operator= (shared_count const & r) // nothrow
210  {
211  sp_counted_base * tmp = r.pi_;
212 
213  if( tmp != pi_ )
214  {
215  if(tmp != 0) tmp->weak_add_ref();
216  if(pi_ != 0) pi_->weak_release();
217  pi_ = tmp;
218  }
219 
220  return *this;
221  }
222 
223  weak_count & operator= (weak_count const & r) // nothrow
224  {
225  sp_counted_base * tmp = r.pi_;
226 
227  if( tmp != pi_ )
228  {
229  if(tmp != 0) tmp->weak_add_ref();
230  if(pi_ != 0) pi_->weak_release();
231  pi_ = tmp;
232  }
233 
234  return *this;
235  }
236 
237  void swap(weak_count & r) // nothrow
238  {
239  sp_counted_base * tmp = r.pi_;
240  r.pi_ = pi_;
241  pi_ = tmp;
242  }
243 
244  long use_count() const // nothrow
245  {
246  return pi_ != 0? pi_->use_count(): 0;
247  }
248 
249  bool empty() const // nothrow
250  {
251  return pi_ == 0;
252  }
253 
254  friend inline bool operator==(weak_count const & a, weak_count const & b)
255  {
256  return a.pi_ == b.pi_;
257  }
258 
259  friend inline bool operator<(weak_count const & a, weak_count const & b)
260  {
261  return std::less<sp_counted_base *>()(a.pi_, b.pi_);
262  }
263 };
264 
265 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
266 {
267  if( pi_ == 0 || !pi_->add_ref_lock() )
268  {
269  throw booster::bad_weak_ptr();
270  }
271 }
272 
273 inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
274 {
275  if( pi_ != 0 && !pi_->add_ref_lock() )
276  {
277  pi_ = 0;
278  }
279 }
280 
281 } // namespace detail
282 
283 } // namespace boost
284 
285 #ifdef __BORLANDC__
286 # pragma warn .8027 // Functions containing try are not expanded inline
287 #endif
288 
289 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
Definition: shared_count.h:37
Definition: sp_counted_base.h:39
Definition: sp_counted_impl.h:77
Definition: shared_count.h:179
Definition: sp_counted_impl.h:32
Definition: sp_counted_impl.h:119
Definition: shared_count.h:33
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
Definition: bad_weak_ptr.h:36