~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to include/builtin-boost/boost/detail/shared_count.hpp

Tags: upstream-0.15.3+svn20934
ImportĀ upstreamĀ versionĀ 0.15.3+svn20934

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
39
namespace boost
 
40
{
 
41
 
 
42
namespace detail
 
43
{
 
44
 
 
45
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
46
 
 
47
int const shared_count_id = 0x2C35F101;
 
48
int const   weak_count_id = 0x298C38A4;
 
49
 
 
50
#endif
 
51
 
 
52
struct sp_nothrow_tag {};
 
53
 
 
54
class weak_count;
 
55
 
 
56
class shared_count
 
57
{
 
58
private:
 
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
 
 
68
public:
 
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
 
 
286
class weak_count
 
287
{
 
288
private:
 
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
 
 
298
public:
 
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
 
 
382
inline 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
 
 
393
inline 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