source: NonGTP/Boost/boost/detail/shared_count.hpp @ 857

Revision 857, 7.0 KB checked in by igarcia, 18 years ago (diff)
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
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
37namespace boost
38{
39
40namespace detail
41{
42
43#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
44
45int const shared_count_id = 0x2C35F101;
46int const   weak_count_id = 0x298C38A4;
47
48#endif
49
50class weak_count;
51
52class shared_count
53{
54private:
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
64public:
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
223class weak_count
224{
225private:
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
235public:
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
311inline 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
Note: See TracBrowser for help on using the repository browser.