VirtualBox

source: vbox/trunk/src/libs/boost-1.37.0/boost/detail/shared_count.hpp@ 37808

Last change on this file since 37808 was 16204, checked in by vboxsync, 16 years ago

export the boost stuff required for Main

File size: 8.7 KB
Line 
1#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
2#define BOOST_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>
27#include <boost/throw_exception.hpp>
28#include <boost/detail/bad_weak_ptr.hpp>
29#include <boost/detail/sp_counted_base.hpp>
30#include <boost/detail/sp_counted_impl.hpp>
31// In order to avoid circular dependencies with Boost.TR1
32// we make sure that our include of <memory> doesn't try to
33// pull in the TR1 headers: that's why we use this header
34// rather than including <memory> directly:
35#include <boost/config/no_tr1/memory.hpp> // std::auto_ptr
36#include <functional> // std::less
37#include <new> // std::bad_alloc
38
39namespace boost
40{
41
42namespace detail
43{
44
45#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
46
47int const shared_count_id = 0x2C35F101;
48int const weak_count_id = 0x298C38A4;
49
50#endif
51
52struct sp_nothrow_tag {};
53
54class weak_count;
55
56class shared_count
57{
58private:
59
60 sp_counted_base * pi_;
61
62#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
63 int id_;
64#endif
65
66 friend class weak_count;
67
68public:
69
70 shared_count(): pi_(0) // nothrow
71#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
72 , id_(shared_count_id)
73#endif
74 {
75 }
76
77 template<class Y> explicit shared_count( Y * p ): pi_( 0 )
78#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
79 , id_(shared_count_id)
80#endif
81 {
82#ifndef BOOST_NO_EXCEPTIONS
83
84 try
85 {
86 pi_ = new sp_counted_impl_p<Y>( p );
87 }
88 catch(...)
89 {
90 boost::checked_delete( p );
91 throw;
92 }
93
94#else
95
96 pi_ = new sp_counted_impl_p<Y>( p );
97
98 if( pi_ == 0 )
99 {
100 boost::checked_delete( p );
101 boost::throw_exception( std::bad_alloc() );
102 }
103
104#endif
105 }
106
107#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
108 template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
109#else
110 template<class P, class D> shared_count( P p, D d ): pi_(0)
111#endif
112#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
113 , id_(shared_count_id)
114#endif
115 {
116#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
117 typedef Y* P;
118#endif
119#ifndef BOOST_NO_EXCEPTIONS
120
121 try
122 {
123 pi_ = new sp_counted_impl_pd<P, D>(p, d);
124 }
125 catch(...)
126 {
127 d(p); // delete p
128 throw;
129 }
130
131#else
132
133 pi_ = new sp_counted_impl_pd<P, D>(p, d);
134
135 if(pi_ == 0)
136 {
137 d(p); // delete p
138 boost::throw_exception(std::bad_alloc());
139 }
140
141#endif
142 }
143
144 template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
145#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
146 , id_(shared_count_id)
147#endif
148 {
149 typedef sp_counted_impl_pda<P, D, A> impl_type;
150 typedef typename A::template rebind< impl_type >::other A2;
151
152 A2 a2( a );
153
154#ifndef BOOST_NO_EXCEPTIONS
155
156 try
157 {
158 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
159 new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
160 }
161 catch(...)
162 {
163 d( p );
164
165 if( pi_ != 0 )
166 {
167 a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
168 }
169
170 throw;
171 }
172
173#else
174
175 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
176
177 if( pi_ != 0 )
178 {
179 new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
180 }
181 else
182 {
183 d( p );
184 boost::throw_exception( std::bad_alloc() );
185 }
186
187#endif
188 }
189
190#ifndef BOOST_NO_AUTO_PTR
191
192 // auto_ptr<Y> is special cased to provide the strong guarantee
193
194 template<class Y>
195 explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
196#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
197 , id_(shared_count_id)
198#endif
199 {
200#ifdef BOOST_NO_EXCEPTIONS
201
202 if( pi_ == 0 )
203 {
204 boost::throw_exception(std::bad_alloc());
205 }
206
207#endif
208
209 r.release();
210 }
211
212#endif
213
214 ~shared_count() // nothrow
215 {
216 if( pi_ != 0 ) pi_->release();
217#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
218 id_ = 0;
219#endif
220 }
221
222 shared_count(shared_count const & r): pi_(r.pi_) // nothrow
223#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
224 , id_(shared_count_id)
225#endif
226 {
227 if( pi_ != 0 ) pi_->add_ref_copy();
228 }
229
230 explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
231 shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
232
233 shared_count & operator= (shared_count const & r) // nothrow
234 {
235 sp_counted_base * tmp = r.pi_;
236
237 if( tmp != pi_ )
238 {
239 if( tmp != 0 ) tmp->add_ref_copy();
240 if( pi_ != 0 ) pi_->release();
241 pi_ = tmp;
242 }
243
244 return *this;
245 }
246
247 void swap(shared_count & r) // nothrow
248 {
249 sp_counted_base * tmp = r.pi_;
250 r.pi_ = pi_;
251 pi_ = tmp;
252 }
253
254 long use_count() const // nothrow
255 {
256 return pi_ != 0? pi_->use_count(): 0;
257 }
258
259 bool unique() const // nothrow
260 {
261 return use_count() == 1;
262 }
263
264 bool empty() const // nothrow
265 {
266 return pi_ == 0;
267 }
268
269 friend inline bool operator==(shared_count const & a, shared_count const & b)
270 {
271 return a.pi_ == b.pi_;
272 }
273
274 friend inline bool operator<(shared_count const & a, shared_count const & b)
275 {
276 return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
277 }
278
279 void * get_deleter( sp_typeinfo const & ti ) const
280 {
281 return pi_? pi_->get_deleter( ti ): 0;
282 }
283};
284
285
286class weak_count
287{
288private:
289
290 sp_counted_base * pi_;
291
292#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
293 int id_;
294#endif
295
296 friend class shared_count;
297
298public:
299
300 weak_count(): pi_(0) // nothrow
301#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
302 , id_(weak_count_id)
303#endif
304 {
305 }
306
307 weak_count(shared_count const & r): pi_(r.pi_) // nothrow
308#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
309 , id_(shared_count_id)
310#endif
311 {
312 if(pi_ != 0) pi_->weak_add_ref();
313 }
314
315 weak_count(weak_count const & r): pi_(r.pi_) // nothrow
316#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
317 , id_(shared_count_id)
318#endif
319 {
320 if(pi_ != 0) pi_->weak_add_ref();
321 }
322
323 ~weak_count() // nothrow
324 {
325 if(pi_ != 0) pi_->weak_release();
326#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
327 id_ = 0;
328#endif
329 }
330
331 weak_count & operator= (shared_count const & r) // nothrow
332 {
333 sp_counted_base * tmp = r.pi_;
334
335 if( tmp != pi_ )
336 {
337 if(tmp != 0) tmp->weak_add_ref();
338 if(pi_ != 0) pi_->weak_release();
339 pi_ = tmp;
340 }
341
342 return *this;
343 }
344
345 weak_count & operator= (weak_count const & r) // nothrow
346 {
347 sp_counted_base * tmp = r.pi_;
348
349 if( tmp != pi_ )
350 {
351 if(tmp != 0) tmp->weak_add_ref();
352 if(pi_ != 0) pi_->weak_release();
353 pi_ = tmp;
354 }
355
356 return *this;
357 }
358
359 void swap(weak_count & r) // nothrow
360 {
361 sp_counted_base * tmp = r.pi_;
362 r.pi_ = pi_;
363 pi_ = tmp;
364 }
365
366 long use_count() const // nothrow
367 {
368 return pi_ != 0? pi_->use_count(): 0;
369 }
370
371 friend inline bool operator==(weak_count const & a, weak_count const & b)
372 {
373 return a.pi_ == b.pi_;
374 }
375
376 friend inline bool operator<(weak_count const & a, weak_count const & b)
377 {
378 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
379 }
380};
381
382inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
383#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
384 , id_(shared_count_id)
385#endif
386{
387 if( pi_ == 0 || !pi_->add_ref_lock() )
388 {
389 boost::throw_exception( boost::bad_weak_ptr() );
390 }
391}
392
393inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
394#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
395 , id_(shared_count_id)
396#endif
397{
398 if( pi_ != 0 && !pi_->add_ref_lock() )
399 {
400 pi_ = 0;
401 }
402}
403
404} // namespace detail
405
406} // namespace boost
407
408#ifdef __BORLANDC__
409# pragma warn .8027 // Functions containing try are not expanded inline
410#endif
411
412#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette