PageRenderTime 26ms CodeModel.GetById 21ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/extlibs/Boost/include/boost/smart_ptr/detail/sp_counted_base_spin.hpp

https://bitbucket.org/hugoruscitti/pilascpp
C++ Header | 131 lines | 86 code | 31 blank | 14 comment | 8 complexity | 8dedcb1ce8856fbf76d35f71c5d64913 MD5 | raw file
  1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED
  2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_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/sp_counted_base_spin.hpp - spinlock pool atomic emulation
 12//
 13//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
 14//  Copyright 2004-2008 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#include <boost/detail/sp_typeinfo.hpp>
 22#include <boost/smart_ptr/detail/spinlock_pool.hpp>
 23
 24namespace boost
 25{
 26
 27namespace detail
 28{
 29
 30inline int atomic_exchange_and_add( int * pw, int dv )
 31{
 32    spinlock_pool<1>::scoped_lock lock( pw );
 33
 34    int r = *pw;
 35    *pw += dv;
 36    return r;
 37}
 38
 39inline void atomic_increment( int * pw )
 40{
 41    spinlock_pool<1>::scoped_lock lock( pw );
 42    ++*pw;
 43}
 44
 45inline int atomic_conditional_increment( int * pw )
 46{
 47    spinlock_pool<1>::scoped_lock lock( pw );
 48
 49    int rv = *pw;
 50    if( rv != 0 ) ++*pw;
 51    return rv;
 52}
 53
 54class sp_counted_base
 55{
 56private:
 57
 58    sp_counted_base( sp_counted_base const & );
 59    sp_counted_base & operator= ( sp_counted_base const & );
 60
 61    int use_count_;        // #shared
 62    int weak_count_;       // #weak + (#shared != 0)
 63
 64public:
 65
 66    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
 67    {
 68    }
 69
 70    virtual ~sp_counted_base() // nothrow
 71    {
 72    }
 73
 74    // dispose() is called when use_count_ drops to zero, to release
 75    // the resources managed by *this.
 76
 77    virtual void dispose() = 0; // nothrow
 78
 79    // destroy() is called when weak_count_ drops to zero.
 80
 81    virtual void destroy() // nothrow
 82    {
 83        delete this;
 84    }
 85
 86    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
 87
 88    void add_ref_copy()
 89    {
 90        atomic_increment( &use_count_ );
 91    }
 92
 93    bool add_ref_lock() // true on success
 94    {
 95        return atomic_conditional_increment( &use_count_ ) != 0;
 96    }
 97
 98    void release() // nothrow
 99    {
100        if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
101        {
102            dispose();
103            weak_release();
104        }
105    }
106
107    void weak_add_ref() // nothrow
108    {
109        atomic_increment( &weak_count_ );
110    }
111
112    void weak_release() // nothrow
113    {
114        if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
115        {
116            destroy();
117        }
118    }
119
120    long use_count() const // nothrow
121    {
122        spinlock_pool<1>::scoped_lock lock( &use_count_ );
123        return use_count_;
124    }
125};
126
127} // namespace detail
128
129} // namespace boost
130
131#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_SPIN_HPP_INCLUDED