os/ossrv/ossrv_pub/boost_apis/boost/detail/shared_count.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
sl@0
     2
#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
sl@0
     3
sl@0
     4
// MS compatible compilers support #pragma once
sl@0
     5
sl@0
     6
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
sl@0
     7
# pragma once
sl@0
     8
#endif
sl@0
     9
sl@0
    10
//
sl@0
    11
//  detail/shared_count.hpp
sl@0
    12
//
sl@0
    13
//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
sl@0
    14
//  Copyright 2004-2005 Peter Dimov
sl@0
    15
//
sl@0
    16
// Distributed under the Boost Software License, Version 1.0. (See
sl@0
    17
// accompanying file LICENSE_1_0.txt or copy at
sl@0
    18
// http://www.boost.org/LICENSE_1_0.txt)
sl@0
    19
//
sl@0
    20
sl@0
    21
#ifdef __BORLANDC__
sl@0
    22
# pragma warn -8027     // Functions containing try are not expanded inline
sl@0
    23
#endif
sl@0
    24
sl@0
    25
#include <boost/config.hpp>
sl@0
    26
#include <boost/checked_delete.hpp>
sl@0
    27
#include <boost/throw_exception.hpp>
sl@0
    28
#include <boost/detail/bad_weak_ptr.hpp>
sl@0
    29
#include <boost/detail/sp_counted_base.hpp>
sl@0
    30
#include <boost/detail/sp_counted_impl.hpp>
sl@0
    31
sl@0
    32
#include <memory>           // std::auto_ptr
sl@0
    33
#include <functional>       // std::less
sl@0
    34
#include <new>              // std::bad_alloc
sl@0
    35
#include <typeinfo>         // std::type_info in get_deleter
sl@0
    36
sl@0
    37
namespace boost
sl@0
    38
{
sl@0
    39
sl@0
    40
namespace detail
sl@0
    41
{
sl@0
    42
sl@0
    43
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
    44
sl@0
    45
int const shared_count_id = 0x2C35F101;
sl@0
    46
int const   weak_count_id = 0x298C38A4;
sl@0
    47
sl@0
    48
#endif
sl@0
    49
sl@0
    50
class weak_count;
sl@0
    51
sl@0
    52
class shared_count
sl@0
    53
{
sl@0
    54
private:
sl@0
    55
sl@0
    56
    sp_counted_base * pi_;
sl@0
    57
sl@0
    58
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
    59
    int id_;
sl@0
    60
#endif
sl@0
    61
sl@0
    62
    friend class weak_count;
sl@0
    63
sl@0
    64
public:
sl@0
    65
sl@0
    66
    shared_count(): pi_(0) // nothrow
sl@0
    67
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
    68
        , id_(shared_count_id)
sl@0
    69
#endif
sl@0
    70
    {
sl@0
    71
    }
sl@0
    72
sl@0
    73
    template<class Y> explicit shared_count( Y * p ): pi_( 0 )
sl@0
    74
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
    75
        , id_(shared_count_id)
sl@0
    76
#endif
sl@0
    77
    {
sl@0
    78
#ifndef BOOST_NO_EXCEPTIONS
sl@0
    79
sl@0
    80
        try
sl@0
    81
        {
sl@0
    82
            pi_ = new sp_counted_impl_p<Y>( p );
sl@0
    83
        }
sl@0
    84
        catch(...)
sl@0
    85
        {
sl@0
    86
            boost::checked_delete( p );
sl@0
    87
            throw;
sl@0
    88
        }
sl@0
    89
sl@0
    90
#else
sl@0
    91
sl@0
    92
        pi_ = new sp_counted_impl_p<Y>( p );
sl@0
    93
sl@0
    94
        if( pi_ == 0 )
sl@0
    95
        {
sl@0
    96
            boost::checked_delete( p );
sl@0
    97
            boost::throw_exception( std::bad_alloc() );
sl@0
    98
        }
sl@0
    99
sl@0
   100
#endif
sl@0
   101
    }
sl@0
   102
sl@0
   103
    template<class P, class D> shared_count(P p, D d): pi_(0)
sl@0
   104
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   105
        , id_(shared_count_id)
sl@0
   106
#endif
sl@0
   107
    {
sl@0
   108
#ifndef BOOST_NO_EXCEPTIONS
sl@0
   109
sl@0
   110
        try
sl@0
   111
        {
sl@0
   112
            pi_ = new sp_counted_impl_pd<P, D>(p, d);
sl@0
   113
        }
sl@0
   114
        catch(...)
sl@0
   115
        {
sl@0
   116
            d(p); // delete p
sl@0
   117
            throw;
sl@0
   118
        }
sl@0
   119
sl@0
   120
#else
sl@0
   121
sl@0
   122
        pi_ = new sp_counted_impl_pd<P, D>(p, d);
sl@0
   123
sl@0
   124
        if(pi_ == 0)
sl@0
   125
        {
sl@0
   126
            d(p); // delete p
sl@0
   127
            boost::throw_exception(std::bad_alloc());
sl@0
   128
        }
sl@0
   129
sl@0
   130
#endif
sl@0
   131
    }
sl@0
   132
sl@0
   133
    template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
sl@0
   134
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   135
        , id_(shared_count_id)
sl@0
   136
#endif
sl@0
   137
    {
sl@0
   138
        typedef sp_counted_impl_pda<P, D, A> impl_type;
sl@0
   139
        typedef typename A::template rebind< impl_type >::other A2;
sl@0
   140
sl@0
   141
        A2 a2( a );
sl@0
   142
sl@0
   143
#ifndef BOOST_NO_EXCEPTIONS
sl@0
   144
sl@0
   145
        try
sl@0
   146
        {
sl@0
   147
            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
sl@0
   148
            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
sl@0
   149
        }
sl@0
   150
        catch(...)
sl@0
   151
        {
sl@0
   152
            d( p );
sl@0
   153
sl@0
   154
            if( pi_ != 0 )
sl@0
   155
            {
sl@0
   156
                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
sl@0
   157
            }
sl@0
   158
sl@0
   159
            throw;
sl@0
   160
        }
sl@0
   161
sl@0
   162
#else
sl@0
   163
sl@0
   164
        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
sl@0
   165
sl@0
   166
        if( pi_ != 0 )
sl@0
   167
        {
sl@0
   168
            new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
sl@0
   169
        }
sl@0
   170
        else
sl@0
   171
        {
sl@0
   172
            d( p );
sl@0
   173
            boost::throw_exception( std::bad_alloc() );
sl@0
   174
        }
sl@0
   175
sl@0
   176
#endif
sl@0
   177
    }
sl@0
   178
sl@0
   179
#ifndef BOOST_NO_AUTO_PTR
sl@0
   180
sl@0
   181
    // auto_ptr<Y> is special cased to provide the strong guarantee
sl@0
   182
sl@0
   183
    template<class Y>
sl@0
   184
    explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
sl@0
   185
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   186
        , id_(shared_count_id)
sl@0
   187
#endif
sl@0
   188
    {
sl@0
   189
#ifdef BOOST_NO_EXCEPTIONS
sl@0
   190
sl@0
   191
        if( pi_ == 0 )
sl@0
   192
        {
sl@0
   193
            boost::throw_exception(std::bad_alloc());
sl@0
   194
        }
sl@0
   195
sl@0
   196
#endif
sl@0
   197
sl@0
   198
        r.release();
sl@0
   199
    }
sl@0
   200
sl@0
   201
#endif 
sl@0
   202
sl@0
   203
    ~shared_count() // nothrow
sl@0
   204
    {
sl@0
   205
        if( pi_ != 0 ) pi_->release();
sl@0
   206
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   207
        id_ = 0;
sl@0
   208
#endif
sl@0
   209
    }
sl@0
   210
sl@0
   211
    shared_count(shared_count const & r): pi_(r.pi_) // nothrow
sl@0
   212
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   213
        , id_(shared_count_id)
sl@0
   214
#endif
sl@0
   215
    {
sl@0
   216
        if( pi_ != 0 ) pi_->add_ref_copy();
sl@0
   217
    }
sl@0
   218
sl@0
   219
    explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
sl@0
   220
sl@0
   221
    shared_count & operator= (shared_count const & r) // nothrow
sl@0
   222
    {
sl@0
   223
        sp_counted_base * tmp = r.pi_;
sl@0
   224
sl@0
   225
        if( tmp != pi_ )
sl@0
   226
        {
sl@0
   227
            if( tmp != 0 ) tmp->add_ref_copy();
sl@0
   228
            if( pi_ != 0 ) pi_->release();
sl@0
   229
            pi_ = tmp;
sl@0
   230
        }
sl@0
   231
sl@0
   232
        return *this;
sl@0
   233
    }
sl@0
   234
sl@0
   235
    void swap(shared_count & r) // nothrow
sl@0
   236
    {
sl@0
   237
        sp_counted_base * tmp = r.pi_;
sl@0
   238
        r.pi_ = pi_;
sl@0
   239
        pi_ = tmp;
sl@0
   240
    }
sl@0
   241
sl@0
   242
    long use_count() const // nothrow
sl@0
   243
    {
sl@0
   244
        return pi_ != 0? pi_->use_count(): 0;
sl@0
   245
    }
sl@0
   246
sl@0
   247
    bool unique() const // nothrow
sl@0
   248
    {
sl@0
   249
        return use_count() == 1;
sl@0
   250
    }
sl@0
   251
sl@0
   252
    friend inline bool operator==(shared_count const & a, shared_count const & b)
sl@0
   253
    {
sl@0
   254
        return a.pi_ == b.pi_;
sl@0
   255
    }
sl@0
   256
sl@0
   257
    friend inline bool operator<(shared_count const & a, shared_count const & b)
sl@0
   258
    {
sl@0
   259
        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
sl@0
   260
    }
sl@0
   261
sl@0
   262
    void * get_deleter(std::type_info const & ti) const
sl@0
   263
    {
sl@0
   264
        return pi_? pi_->get_deleter( ti ): 0;
sl@0
   265
    }
sl@0
   266
};
sl@0
   267
sl@0
   268
sl@0
   269
class weak_count
sl@0
   270
{
sl@0
   271
private:
sl@0
   272
sl@0
   273
    sp_counted_base * pi_;
sl@0
   274
sl@0
   275
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   276
    int id_;
sl@0
   277
#endif
sl@0
   278
sl@0
   279
    friend class shared_count;
sl@0
   280
sl@0
   281
public:
sl@0
   282
sl@0
   283
    weak_count(): pi_(0) // nothrow
sl@0
   284
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   285
        , id_(weak_count_id)
sl@0
   286
#endif
sl@0
   287
    {
sl@0
   288
    }
sl@0
   289
sl@0
   290
    weak_count(shared_count const & r): pi_(r.pi_) // nothrow
sl@0
   291
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   292
        , id_(shared_count_id)
sl@0
   293
#endif
sl@0
   294
    {
sl@0
   295
        if(pi_ != 0) pi_->weak_add_ref();
sl@0
   296
    }
sl@0
   297
sl@0
   298
    weak_count(weak_count const & r): pi_(r.pi_) // nothrow
sl@0
   299
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   300
        , id_(shared_count_id)
sl@0
   301
#endif
sl@0
   302
    {
sl@0
   303
        if(pi_ != 0) pi_->weak_add_ref();
sl@0
   304
    }
sl@0
   305
sl@0
   306
    ~weak_count() // nothrow
sl@0
   307
    {
sl@0
   308
        if(pi_ != 0) pi_->weak_release();
sl@0
   309
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   310
        id_ = 0;
sl@0
   311
#endif
sl@0
   312
    }
sl@0
   313
sl@0
   314
    weak_count & operator= (shared_count const & r) // nothrow
sl@0
   315
    {
sl@0
   316
        sp_counted_base * tmp = r.pi_;
sl@0
   317
        if(tmp != 0) tmp->weak_add_ref();
sl@0
   318
        if(pi_ != 0) pi_->weak_release();
sl@0
   319
        pi_ = tmp;
sl@0
   320
sl@0
   321
        return *this;
sl@0
   322
    }
sl@0
   323
sl@0
   324
    weak_count & operator= (weak_count const & r) // nothrow
sl@0
   325
    {
sl@0
   326
        sp_counted_base * tmp = r.pi_;
sl@0
   327
        if(tmp != 0) tmp->weak_add_ref();
sl@0
   328
        if(pi_ != 0) pi_->weak_release();
sl@0
   329
        pi_ = tmp;
sl@0
   330
sl@0
   331
        return *this;
sl@0
   332
    }
sl@0
   333
sl@0
   334
    void swap(weak_count & r) // nothrow
sl@0
   335
    {
sl@0
   336
        sp_counted_base * tmp = r.pi_;
sl@0
   337
        r.pi_ = pi_;
sl@0
   338
        pi_ = tmp;
sl@0
   339
    }
sl@0
   340
sl@0
   341
    long use_count() const // nothrow
sl@0
   342
    {
sl@0
   343
        return pi_ != 0? pi_->use_count(): 0;
sl@0
   344
    }
sl@0
   345
sl@0
   346
    friend inline bool operator==(weak_count const & a, weak_count const & b)
sl@0
   347
    {
sl@0
   348
        return a.pi_ == b.pi_;
sl@0
   349
    }
sl@0
   350
sl@0
   351
    friend inline bool operator<(weak_count const & a, weak_count const & b)
sl@0
   352
    {
sl@0
   353
        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
sl@0
   354
    }
sl@0
   355
};
sl@0
   356
sl@0
   357
inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
sl@0
   358
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
sl@0
   359
        , id_(shared_count_id)
sl@0
   360
#endif
sl@0
   361
{
sl@0
   362
    if( pi_ == 0 || !pi_->add_ref_lock() )
sl@0
   363
    {
sl@0
   364
        boost::throw_exception( boost::bad_weak_ptr() );
sl@0
   365
    }
sl@0
   366
}
sl@0
   367
sl@0
   368
} // namespace detail
sl@0
   369
sl@0
   370
} // namespace boost
sl@0
   371
sl@0
   372
#ifdef __BORLANDC__
sl@0
   373
# pragma warn .8027     // Functions containing try are not expanded inline
sl@0
   374
#endif
sl@0
   375
sl@0
   376
#endif  // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED