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