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

« back to all changes in this revision

Viewing changes to include/builtin-boost/boost/serialization/detail/shared_count_132.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_132_HPP_INCLUDED
 
2
#define BOOST_DETAIL_SHARED_COUNT_132_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
//
 
15
// Distributed under the Boost Software License, Version 1.0. (See
 
16
// accompanying file LICENSE_1_0.txt or copy at
 
17
// http://www.boost.org/LICENSE_1_0.txt)
 
18
//
 
19
 
 
20
#include <boost/config.hpp>
 
21
 
 
22
#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 
23
# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
 
24
#endif
 
25
 
 
26
#include <boost/checked_delete.hpp>
 
27
#include <boost/serialization/throw_exception.hpp>
 
28
#include <boost/detail/lightweight_mutex.hpp>
 
29
 
 
30
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 
31
#include <boost/detail/quick_allocator.hpp>
 
32
#endif
 
33
 
 
34
#include <memory>           // std::auto_ptr, std::allocator
 
35
#include <functional>       // std::less
 
36
#include <exception>        // std::exception
 
37
#include <new>              // std::bad_alloc
 
38
#include <typeinfo>         // std::type_info in get_deleter
 
39
#include <cstddef>          // std::size_t
 
40
 
 
41
#include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
 
42
#if defined(BOOST_NO_STDC_NAMESPACE)
 
43
namespace std{ 
 
44
    using ::size_t; 
 
45
} // namespace std
 
46
#endif
 
47
 
 
48
#ifdef __BORLANDC__
 
49
# pragma warn -8026     // Functions with excep. spec. are not expanded inline
 
50
# pragma warn -8027     // Functions containing try are not expanded inline
 
51
#endif
 
52
 
 
53
namespace boost_132 {
 
54
 
 
55
// Debug hooks
 
56
 
 
57
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
58
 
 
59
void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
 
60
void sp_array_constructor_hook(void * px);
 
61
void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
 
62
void sp_array_destructor_hook(void * px);
 
63
 
 
64
#endif
 
65
 
 
66
 
 
67
// The standard library that comes with Borland C++ 5.5.1
 
68
// defines std::exception and its members as having C calling
 
69
// convention (-pc). When the definition of bad_weak_ptr
 
70
// is compiled with -ps, the compiler issues an error.
 
71
// Hence, the temporary #pragma option -pc below. The version
 
72
// check is deliberately conservative.
 
73
 
 
74
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
 
75
# pragma option push -pc
 
76
#endif
 
77
 
 
78
class bad_weak_ptr: public std::exception
 
79
{
 
80
public:
 
81
 
 
82
    virtual char const * what() const throw()
 
83
    {
 
84
        return "boost::bad_weak_ptr";
 
85
    }
 
86
};
 
87
 
 
88
#if defined(__BORLANDC__) && __BORLANDC__ == 0x551
 
89
# pragma option pop
 
90
#endif
 
91
 
 
92
namespace detail{
 
93
 
 
94
class sp_counted_base
 
95
{
 
96
//private:
 
97
 
 
98
    typedef boost::detail::lightweight_mutex mutex_type;
 
99
 
 
100
public:
 
101
 
 
102
    sp_counted_base(): use_count_(1), weak_count_(1)
 
103
    {
 
104
    }
 
105
 
 
106
    virtual ~sp_counted_base() // nothrow
 
107
    {
 
108
    }
 
109
 
 
110
    // dispose() is called when use_count_ drops to zero, to release
 
111
    // the resources managed by *this.
 
112
 
 
113
    virtual void dispose() = 0; // nothrow
 
114
 
 
115
    // destruct() is called when weak_count_ drops to zero.
 
116
 
 
117
    virtual void destruct() // nothrow
 
118
    {
 
119
        delete this;
 
120
    }
 
121
 
 
122
    virtual void * get_deleter(std::type_info const & ti) = 0;
 
123
 
 
124
    void add_ref_copy()
 
125
    {
 
126
#if defined(BOOST_HAS_THREADS)
 
127
        mutex_type::scoped_lock lock(mtx_);
 
128
#endif
 
129
        ++use_count_;
 
130
    }
 
131
 
 
132
    void add_ref_lock()
 
133
    {
 
134
#if defined(BOOST_HAS_THREADS)
 
135
        mutex_type::scoped_lock lock(mtx_);
 
136
#endif
 
137
        if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr());
 
138
        ++use_count_;
 
139
    }
 
140
 
 
141
    void release() // nothrow
 
142
    {
 
143
        {
 
144
#if defined(BOOST_HAS_THREADS)
 
145
            mutex_type::scoped_lock lock(mtx_);
 
146
#endif
 
147
            long new_use_count = --use_count_;
 
148
 
 
149
            if(new_use_count != 0) return;
 
150
        }
 
151
 
 
152
        dispose();
 
153
        weak_release();
 
154
    }
 
155
 
 
156
    void weak_add_ref() // nothrow
 
157
    {
 
158
#if defined(BOOST_HAS_THREADS)
 
159
        mutex_type::scoped_lock lock(mtx_);
 
160
#endif
 
161
        ++weak_count_;
 
162
    }
 
163
 
 
164
    void weak_release() // nothrow
 
165
    {
 
166
        long new_weak_count;
 
167
 
 
168
        {
 
169
#if defined(BOOST_HAS_THREADS)
 
170
            mutex_type::scoped_lock lock(mtx_);
 
171
#endif
 
172
            new_weak_count = --weak_count_;
 
173
        }
 
174
 
 
175
        if(new_weak_count == 0)
 
176
        {
 
177
            destruct();
 
178
        }
 
179
    }
 
180
 
 
181
    long use_count() const // nothrow
 
182
    {
 
183
#if defined(BOOST_HAS_THREADS)
 
184
        mutex_type::scoped_lock lock(mtx_);
 
185
#endif
 
186
        return use_count_;
 
187
    }
 
188
 
 
189
//private:
 
190
public:
 
191
    sp_counted_base(sp_counted_base const &);
 
192
    sp_counted_base & operator= (sp_counted_base const &);
 
193
 
 
194
    long use_count_;        // #shared
 
195
    long weak_count_;       // #weak + (#shared != 0)
 
196
 
 
197
#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32)
 
198
    mutable mutex_type mtx_;
 
199
#endif
 
200
};
 
201
 
 
202
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
203
 
 
204
template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
 
205
{
 
206
    boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
 
207
}
 
208
 
 
209
template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
 
210
{
 
211
    boost::sp_array_constructor_hook(px);
 
212
}
 
213
 
 
214
template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
 
215
{
 
216
}
 
217
 
 
218
template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, checked_deleter<T> const &, int)
 
219
{
 
220
    boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
 
221
}
 
222
 
 
223
template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, checked_array_deleter<T> const &, int)
 
224
{
 
225
    boost::sp_array_destructor_hook(px);
 
226
}
 
227
 
 
228
template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
 
229
{
 
230
}
 
231
 
 
232
#endif
 
233
 
 
234
//
 
235
// Borland's Codeguard trips up over the -Vx- option here:
 
236
//
 
237
#ifdef __CODEGUARD__
 
238
# pragma option push -Vx-
 
239
#endif
 
240
 
 
241
template<class P, class D> class sp_counted_base_impl: public sp_counted_base
 
242
{
 
243
//private:
 
244
public:
 
245
    P ptr; // copy constructor must not throw
 
246
    D del; // copy constructor must not throw
 
247
 
 
248
    sp_counted_base_impl(sp_counted_base_impl const &);
 
249
    sp_counted_base_impl & operator= (sp_counted_base_impl const &);
 
250
 
 
251
    typedef sp_counted_base_impl<P, D> this_type;
 
252
 
 
253
public:
 
254
 
 
255
    // pre: initial_use_count <= initial_weak_count, d(p) must not throw
 
256
 
 
257
    sp_counted_base_impl(P p, D d): ptr(p), del(d)
 
258
    {
 
259
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
260
        detail::cbi_call_constructor_hook(this, p, d, 0);
 
261
#endif
 
262
    }
 
263
 
 
264
    virtual void dispose() // nothrow
 
265
    {
 
266
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
267
        detail::cbi_call_destructor_hook(this, ptr, del, 0);
 
268
#endif
 
269
        del(ptr);
 
270
    }
 
271
 
 
272
    virtual void * get_deleter(std::type_info const & ti)
 
273
    {
 
274
        return ti == typeid(D)? &del: 0;
 
275
    }
 
276
 
 
277
#if defined(BOOST_SP_USE_STD_ALLOCATOR)
 
278
 
 
279
    void * operator new(std::size_t)
 
280
    {
 
281
        return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0));
 
282
    }
 
283
 
 
284
    void operator delete(void * p)
 
285
    {
 
286
        std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
 
287
    }
 
288
 
 
289
#endif
 
290
 
 
291
#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
 
292
 
 
293
    void * operator new(std::size_t)
 
294
    {
 
295
        return boost::detail::quick_allocator<this_type>::alloc();
 
296
    }
 
297
 
 
298
    void operator delete(void * p)
 
299
    {
 
300
        boost::detail::quick_allocator<this_type>::dealloc(p);
 
301
    }
 
302
 
 
303
#endif
 
304
};
 
305
 
 
306
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
307
 
 
308
int const shared_count_id = 0x2C35F101;
 
309
int const   weak_count_id = 0x298C38A4;
 
310
 
 
311
#endif
 
312
 
 
313
class weak_count;
 
314
 
 
315
class shared_count
 
316
{
 
317
//private:
 
318
public:
 
319
    sp_counted_base * pi_;
 
320
 
 
321
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
322
    int id_;
 
323
#endif
 
324
 
 
325
    friend class weak_count;
 
326
 
 
327
public:
 
328
 
 
329
    shared_count(): pi_(0) // nothrow
 
330
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
331
        , id_(shared_count_id)
 
332
#endif
 
333
    {
 
334
    }
 
335
 
 
336
    template<class P, class D> shared_count(P p, D d): pi_(0)
 
337
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
338
        , id_(shared_count_id)
 
339
#endif
 
340
    {
 
341
#ifndef BOOST_NO_EXCEPTIONS
 
342
 
 
343
        try
 
344
        {
 
345
            pi_ = new sp_counted_base_impl<P, D>(p, d);
 
346
        }
 
347
        catch(...)
 
348
        {
 
349
            d(p); // delete p
 
350
            throw;
 
351
        }
 
352
 
 
353
#else
 
354
 
 
355
        pi_ = new sp_counted_base_impl<P, D>(p, d);
 
356
 
 
357
        if(pi_ == 0)
 
358
        {
 
359
            d(p); // delete p
 
360
            boost::serialization::throw_exception(std::bad_alloc());
 
361
        }
 
362
 
 
363
#endif
 
364
    }
 
365
 
 
366
#ifndef BOOST_NO_AUTO_PTR
 
367
 
 
368
    // auto_ptr<Y> is special cased to provide the strong guarantee
 
369
 
 
370
    template<class Y>
 
371
    explicit shared_count(std::auto_ptr<Y> & r): pi_(
 
372
        new sp_counted_base_impl<
 
373
            Y *, 
 
374
            boost::checked_deleter<Y>
 
375
        >(r.get(), boost::checked_deleter<Y>()))
 
376
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
377
        , id_(shared_count_id)
 
378
#endif
 
379
    {
 
380
        r.release();
 
381
    }
 
382
 
 
383
#endif 
 
384
 
 
385
    ~shared_count() // nothrow
 
386
    {
 
387
        if(pi_ != 0) pi_->release();
 
388
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
389
        id_ = 0;
 
390
#endif
 
391
    }
 
392
 
 
393
    shared_count(shared_count const & r): pi_(r.pi_) // nothrow
 
394
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
395
        , id_(shared_count_id)
 
396
#endif
 
397
    {
 
398
        if(pi_ != 0) pi_->add_ref_copy();
 
399
    }
 
400
 
 
401
    explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
 
402
 
 
403
    shared_count & operator= (shared_count const & r) // nothrow
 
404
    {
 
405
        sp_counted_base * tmp = r.pi_;
 
406
 
 
407
        if(tmp != pi_)
 
408
        {
 
409
            if(tmp != 0) tmp->add_ref_copy();
 
410
            if(pi_ != 0) pi_->release();
 
411
            pi_ = tmp;
 
412
        }
 
413
 
 
414
        return *this;
 
415
    }
 
416
 
 
417
    void swap(shared_count & r) // nothrow
 
418
    {
 
419
        sp_counted_base * tmp = r.pi_;
 
420
        r.pi_ = pi_;
 
421
        pi_ = tmp;
 
422
    }
 
423
 
 
424
    long use_count() const // nothrow
 
425
    {
 
426
        return pi_ != 0? pi_->use_count(): 0;
 
427
    }
 
428
 
 
429
    bool unique() const // nothrow
 
430
    {
 
431
        return use_count() == 1;
 
432
    }
 
433
 
 
434
    friend inline bool operator==(shared_count const & a, shared_count const & b)
 
435
    {
 
436
        return a.pi_ == b.pi_;
 
437
    }
 
438
 
 
439
    friend inline bool operator<(shared_count const & a, shared_count const & b)
 
440
    {
 
441
        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
 
442
    }
 
443
 
 
444
    void * get_deleter(std::type_info const & ti) const
 
445
    {
 
446
        return pi_? pi_->get_deleter(ti): 0;
 
447
    }
 
448
};
 
449
 
 
450
#ifdef __CODEGUARD__
 
451
# pragma option pop
 
452
#endif
 
453
 
 
454
 
 
455
class weak_count
 
456
{
 
457
private:
 
458
 
 
459
    sp_counted_base * pi_;
 
460
 
 
461
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
462
    int id_;
 
463
#endif
 
464
 
 
465
    friend class shared_count;
 
466
 
 
467
public:
 
468
 
 
469
    weak_count(): pi_(0) // nothrow
 
470
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
471
        , id_(weak_count_id)
 
472
#endif
 
473
    {
 
474
    }
 
475
 
 
476
    weak_count(shared_count const & r): pi_(r.pi_) // nothrow
 
477
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
478
        , id_(shared_count_id)
 
479
#endif
 
480
    {
 
481
        if(pi_ != 0) pi_->weak_add_ref();
 
482
    }
 
483
 
 
484
    weak_count(weak_count const & r): pi_(r.pi_) // nothrow
 
485
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
486
        , id_(shared_count_id)
 
487
#endif
 
488
    {
 
489
        if(pi_ != 0) pi_->weak_add_ref();
 
490
    }
 
491
 
 
492
    ~weak_count() // nothrow
 
493
    {
 
494
        if(pi_ != 0) pi_->weak_release();
 
495
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
496
        id_ = 0;
 
497
#endif
 
498
    }
 
499
 
 
500
    weak_count & operator= (shared_count const & r) // nothrow
 
501
    {
 
502
        sp_counted_base * tmp = r.pi_;
 
503
        if(tmp != 0) tmp->weak_add_ref();
 
504
        if(pi_ != 0) pi_->weak_release();
 
505
        pi_ = tmp;
 
506
 
 
507
        return *this;
 
508
    }
 
509
 
 
510
    weak_count & operator= (weak_count const & r) // nothrow
 
511
    {
 
512
        sp_counted_base * tmp = r.pi_;
 
513
        if(tmp != 0) tmp->weak_add_ref();
 
514
        if(pi_ != 0) pi_->weak_release();
 
515
        pi_ = tmp;
 
516
 
 
517
        return *this;
 
518
    }
 
519
 
 
520
    void swap(weak_count & r) // nothrow
 
521
    {
 
522
        sp_counted_base * tmp = r.pi_;
 
523
        r.pi_ = pi_;
 
524
        pi_ = tmp;
 
525
    }
 
526
 
 
527
    long use_count() const // nothrow
 
528
    {
 
529
        return pi_ != 0? pi_->use_count(): 0;
 
530
    }
 
531
 
 
532
    friend inline bool operator==(weak_count const & a, weak_count const & b)
 
533
    {
 
534
        return a.pi_ == b.pi_;
 
535
    }
 
536
 
 
537
    friend inline bool operator<(weak_count const & a, weak_count const & b)
 
538
    {
 
539
        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
 
540
    }
 
541
};
 
542
 
 
543
inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
 
544
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
 
545
        , id_(shared_count_id)
 
546
#endif
 
547
{
 
548
    if(pi_ != 0)
 
549
    {
 
550
        pi_->add_ref_lock();
 
551
    }
 
552
    else
 
553
    {
 
554
        boost::serialization::throw_exception(bad_weak_ptr());
 
555
    }
 
556
}
 
557
 
 
558
} // namespace detail
 
559
 
 
560
} // namespace boost
 
561
 
 
562
BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base)
 
563
 
 
564
#ifdef __BORLANDC__
 
565
# pragma warn .8027     // Functions containing try are not expanded inline
 
566
# pragma warn .8026     // Functions with excep. spec. are not expanded inline
 
567
#endif
 
568
 
 
569
#endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED