Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/detail/shared_count.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 7.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
32#include <memory>           // std::auto_ptr
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    template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
134#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
135        , id_(shared_count_id)
136#endif
137    {
138        typedef sp_counted_impl_pda<P, D, A> impl_type;
139        typedef typename A::template rebind< impl_type >::other A2;
140
141        A2 a2( a );
142
143#ifndef BOOST_NO_EXCEPTIONS
144
145        try
146        {
147            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
148            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
149        }
150        catch(...)
151        {
152            d( p );
153
154            if( pi_ != 0 )
155            {
156                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
157            }
158
159            throw;
160        }
161
162#else
163
164        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
165
166        if( pi_ != 0 )
167        {
168            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
169        }
170        else
171        {
172            d( p );
173            boost::throw_exception( std::bad_alloc() );
174        }
175
176#endif
177    }
178
179#ifndef BOOST_NO_AUTO_PTR
180
181    // auto_ptr<Y> is special cased to provide the strong guarantee
182
183    template<class Y>
184    explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
185#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
186        , id_(shared_count_id)
187#endif
188    {
189#ifdef BOOST_NO_EXCEPTIONS
190
191        if( pi_ == 0 )
192        {
193            boost::throw_exception(std::bad_alloc());
194        }
195
196#endif
197
198        r.release();
199    }
200
201#endif
202
203    ~shared_count() // nothrow
204    {
205        if( pi_ != 0 ) pi_->release();
206#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
207        id_ = 0;
208#endif
209    }
210
211    shared_count(shared_count const & r): pi_(r.pi_) // nothrow
212#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
213        , id_(shared_count_id)
214#endif
215    {
216        if( pi_ != 0 ) pi_->add_ref_copy();
217    }
218
219    explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
220
221    shared_count & operator= (shared_count const & r) // nothrow
222    {
223        sp_counted_base * tmp = r.pi_;
224
225        if( tmp != pi_ )
226        {
227            if( tmp != 0 ) tmp->add_ref_copy();
228            if( pi_ != 0 ) pi_->release();
229            pi_ = tmp;
230        }
231
232        return *this;
233    }
234
235    void swap(shared_count & r) // nothrow
236    {
237        sp_counted_base * tmp = r.pi_;
238        r.pi_ = pi_;
239        pi_ = tmp;
240    }
241
242    long use_count() const // nothrow
243    {
244        return pi_ != 0? pi_->use_count(): 0;
245    }
246
247    bool unique() const // nothrow
248    {
249        return use_count() == 1;
250    }
251
252    friend inline bool operator==(shared_count const & a, shared_count const & b)
253    {
254        return a.pi_ == b.pi_;
255    }
256
257    friend inline bool operator<(shared_count const & a, shared_count const & b)
258    {
259        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
260    }
261
262    void * get_deleter(std::type_info const & ti) const
263    {
264        return pi_? pi_->get_deleter( ti ): 0;
265    }
266};
267
268
269class weak_count
270{
271private:
272
273    sp_counted_base * pi_;
274
275#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
276    int id_;
277#endif
278
279    friend class shared_count;
280
281public:
282
283    weak_count(): pi_(0) // nothrow
284#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
285        , id_(weak_count_id)
286#endif
287    {
288    }
289
290    weak_count(shared_count const & r): pi_(r.pi_) // nothrow
291#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
292        , id_(shared_count_id)
293#endif
294    {
295        if(pi_ != 0) pi_->weak_add_ref();
296    }
297
298    weak_count(weak_count const & r): pi_(r.pi_) // nothrow
299#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
300        , id_(shared_count_id)
301#endif
302    {
303        if(pi_ != 0) pi_->weak_add_ref();
304    }
305
306    ~weak_count() // nothrow
307    {
308        if(pi_ != 0) pi_->weak_release();
309#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
310        id_ = 0;
311#endif
312    }
313
314    weak_count & operator= (shared_count const & r) // nothrow
315    {
316        sp_counted_base * tmp = r.pi_;
317        if(tmp != 0) tmp->weak_add_ref();
318        if(pi_ != 0) pi_->weak_release();
319        pi_ = tmp;
320
321        return *this;
322    }
323
324    weak_count & operator= (weak_count const & r) // nothrow
325    {
326        sp_counted_base * tmp = r.pi_;
327        if(tmp != 0) tmp->weak_add_ref();
328        if(pi_ != 0) pi_->weak_release();
329        pi_ = tmp;
330
331        return *this;
332    }
333
334    void swap(weak_count & r) // nothrow
335    {
336        sp_counted_base * tmp = r.pi_;
337        r.pi_ = pi_;
338        pi_ = tmp;
339    }
340
341    long use_count() const // nothrow
342    {
343        return pi_ != 0? pi_->use_count(): 0;
344    }
345
346    friend inline bool operator==(weak_count const & a, weak_count const & b)
347    {
348        return a.pi_ == b.pi_;
349    }
350
351    friend inline bool operator<(weak_count const & a, weak_count const & b)
352    {
353        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
354    }
355};
356
357inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
358#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
359        , id_(shared_count_id)
360#endif
361{
362    if( pi_ == 0 || !pi_->add_ref_lock() )
363    {
364        boost::throw_exception( boost::bad_weak_ptr() );
365    }
366}
367
368} // namespace detail
369
370} // namespace boost
371
372#ifdef __BORLANDC__
373# pragma warn .8027     // Functions containing try are not expanded inline
374#endif
375
376#endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.