]> git.lyx.org Git - lyx.git/blob - boost/boost/detail/shared_count.hpp
* Add the iostreams and range libs to our copy of boost
[lyx.git] / boost / boost / detail / shared_count.hpp
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
32 #include <memory>           // std::auto_ptr, std::allocator
33 #include <functional>       // std::less
34 #include <new>              // std::bad_alloc
35 #include <typeinfo>         // std::type_info in get_deleter
36
37 namespace boost
38 {
39
40 namespace detail
41 {
42
43 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
44
45 int const shared_count_id = 0x2C35F101;
46 int const   weak_count_id = 0x298C38A4;
47
48 #endif
49
50 class weak_count;
51
52 class shared_count
53 {
54 private:
55
56     sp_counted_base * pi_;
57
58 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
59     int id_;
60 #endif
61
62     friend class weak_count;
63
64 public:
65
66     shared_count(): pi_(0) // nothrow
67 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
68         , id_(shared_count_id)
69 #endif
70     {
71     }
72
73     template<class Y> explicit shared_count( Y * p ): pi_( 0 )
74 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
75         , id_(shared_count_id)
76 #endif
77     {
78 #ifndef BOOST_NO_EXCEPTIONS
79
80         try
81         {
82             pi_ = new sp_counted_impl_p<Y>( p );
83         }
84         catch(...)
85         {
86             boost::checked_delete( p );
87             throw;
88         }
89
90 #else
91
92         pi_ = new sp_counted_impl_p<Y>( p );
93
94         if( pi_ == 0 )
95         {
96             boost::checked_delete( p );
97             boost::throw_exception( std::bad_alloc() );
98         }
99
100 #endif
101     }
102
103     template<class P, class D> shared_count(P p, D d): pi_(0)
104 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
105         , id_(shared_count_id)
106 #endif
107     {
108 #ifndef BOOST_NO_EXCEPTIONS
109
110         try
111         {
112             pi_ = new sp_counted_impl_pd<P, D>(p, d);
113         }
114         catch(...)
115         {
116             d(p); // delete p
117             throw;
118         }
119
120 #else
121
122         pi_ = new sp_counted_impl_pd<P, D>(p, d);
123
124         if(pi_ == 0)
125         {
126             d(p); // delete p
127             boost::throw_exception(std::bad_alloc());
128         }
129
130 #endif
131     }
132
133 #ifndef BOOST_NO_AUTO_PTR
134
135     // auto_ptr<Y> is special cased to provide the strong guarantee
136
137     template<class Y>
138     explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
139 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
140         , id_(shared_count_id)
141 #endif
142     {
143 #ifdef BOOST_NO_EXCEPTIONS
144
145         if( pi_ == 0 )
146         {
147             boost::throw_exception(std::bad_alloc());
148         }
149
150 #endif
151
152         r.release();
153     }
154
155 #endif 
156
157     ~shared_count() // nothrow
158     {
159         if( pi_ != 0 ) pi_->release();
160 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
161         id_ = 0;
162 #endif
163     }
164
165     shared_count(shared_count const & r): pi_(r.pi_) // nothrow
166 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
167         , id_(shared_count_id)
168 #endif
169     {
170         if( pi_ != 0 ) pi_->add_ref_copy();
171     }
172
173     explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
174
175     shared_count & operator= (shared_count const & r) // nothrow
176     {
177         sp_counted_base * tmp = r.pi_;
178
179         if( tmp != pi_ )
180         {
181             if( tmp != 0 ) tmp->add_ref_copy();
182             if( pi_ != 0 ) pi_->release();
183             pi_ = tmp;
184         }
185
186         return *this;
187     }
188
189     void swap(shared_count & r) // nothrow
190     {
191         sp_counted_base * tmp = r.pi_;
192         r.pi_ = pi_;
193         pi_ = tmp;
194     }
195
196     long use_count() const // nothrow
197     {
198         return pi_ != 0? pi_->use_count(): 0;
199     }
200
201     bool unique() const // nothrow
202     {
203         return use_count() == 1;
204     }
205
206     friend inline bool operator==(shared_count const & a, shared_count const & b)
207     {
208         return a.pi_ == b.pi_;
209     }
210
211     friend inline bool operator<(shared_count const & a, shared_count const & b)
212     {
213         return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
214     }
215
216     void * get_deleter(std::type_info const & ti) const
217     {
218         return pi_? pi_->get_deleter( ti ): 0;
219     }
220 };
221
222
223 class weak_count
224 {
225 private:
226
227     sp_counted_base * pi_;
228
229 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
230     int id_;
231 #endif
232
233     friend class shared_count;
234
235 public:
236
237     weak_count(): pi_(0) // nothrow
238 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
239         , id_(weak_count_id)
240 #endif
241     {
242     }
243
244     weak_count(shared_count const & r): pi_(r.pi_) // nothrow
245 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
246         , id_(shared_count_id)
247 #endif
248     {
249         if(pi_ != 0) pi_->weak_add_ref();
250     }
251
252     weak_count(weak_count const & r): pi_(r.pi_) // nothrow
253 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
254         , id_(shared_count_id)
255 #endif
256     {
257         if(pi_ != 0) pi_->weak_add_ref();
258     }
259
260     ~weak_count() // nothrow
261     {
262         if(pi_ != 0) pi_->weak_release();
263 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
264         id_ = 0;
265 #endif
266     }
267
268     weak_count & operator= (shared_count const & r) // nothrow
269     {
270         sp_counted_base * tmp = r.pi_;
271         if(tmp != 0) tmp->weak_add_ref();
272         if(pi_ != 0) pi_->weak_release();
273         pi_ = tmp;
274
275         return *this;
276     }
277
278     weak_count & operator= (weak_count const & r) // nothrow
279     {
280         sp_counted_base * tmp = r.pi_;
281         if(tmp != 0) tmp->weak_add_ref();
282         if(pi_ != 0) pi_->weak_release();
283         pi_ = tmp;
284
285         return *this;
286     }
287
288     void swap(weak_count & r) // nothrow
289     {
290         sp_counted_base * tmp = r.pi_;
291         r.pi_ = pi_;
292         pi_ = tmp;
293     }
294
295     long use_count() const // nothrow
296     {
297         return pi_ != 0? pi_->use_count(): 0;
298     }
299
300     friend inline bool operator==(weak_count const & a, weak_count const & b)
301     {
302         return a.pi_ == b.pi_;
303     }
304
305     friend inline bool operator<(weak_count const & a, weak_count const & b)
306     {
307         return std::less<sp_counted_base *>()(a.pi_, b.pi_);
308     }
309 };
310
311 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
312 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
313         , id_(shared_count_id)
314 #endif
315 {
316     if( pi_ == 0 || !pi_->add_ref_lock() )
317     {
318         boost::throw_exception( boost::bad_weak_ptr() );
319     }
320 }
321
322 } // namespace detail
323
324 } // namespace boost
325
326 #ifdef __BORLANDC__
327 # pragma warn .8027     // Functions containing try are not expanded inline
328 #endif
329
330 #endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED