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