epoc32/include/stdapis/boost/detail/sp_counted_base_w32.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
     1 #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED
     2 #define BOOST_DETAIL_SP_COUNTED_BASE_W32_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_w32.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 //  Lock-free algorithm by Alexander Terekhov
    22 //
    23 //  Thanks to Ben Hitchings for the #weak + (#shared != 0)
    24 //  formulation
    25 //
    26 
    27 #include <boost/detail/interlocked.hpp>
    28 #include <boost/detail/workaround.hpp>
    29 #include <typeinfo>
    30 
    31 namespace boost
    32 {
    33 
    34 namespace detail
    35 {
    36 
    37 class sp_counted_base
    38 {
    39 private:
    40 
    41     sp_counted_base( sp_counted_base const & );
    42     sp_counted_base & operator= ( sp_counted_base const & );
    43 
    44     long use_count_;        // #shared
    45     long weak_count_;       // #weak + (#shared != 0)
    46 
    47 public:
    48 
    49     sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
    50     {
    51     }
    52 
    53     virtual ~sp_counted_base() // nothrow
    54     {
    55     }
    56 
    57     // dispose() is called when use_count_ drops to zero, to release
    58     // the resources managed by *this.
    59 
    60     virtual void dispose() = 0; // nothrow
    61 
    62     // destroy() is called when weak_count_ drops to zero.
    63 
    64     virtual void destroy() // nothrow
    65     {
    66         delete this;
    67     }
    68 
    69     virtual void * get_deleter( std::type_info const & ti ) = 0;
    70 
    71     void add_ref_copy()
    72     {
    73         BOOST_INTERLOCKED_INCREMENT( &use_count_ );
    74     }
    75 
    76     bool add_ref_lock() // true on success
    77     {
    78         for( ;; )
    79         {
    80             long tmp = static_cast< long const volatile& >( use_count_ );
    81             if( tmp == 0 ) return false;
    82 
    83 #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1200 )
    84 
    85             // work around a code generation bug
    86 
    87             long tmp2 = tmp + 1;
    88             if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp2, tmp ) == tmp2 - 1 ) return true;
    89 
    90 #else
    91 
    92             if( BOOST_INTERLOCKED_COMPARE_EXCHANGE( &use_count_, tmp + 1, tmp ) == tmp ) return true;
    93 
    94 #endif
    95         }
    96     }
    97 
    98     void release() // nothrow
    99     {
   100         if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
   101         {
   102             dispose();
   103             weak_release();
   104         }
   105     }
   106 
   107     void weak_add_ref() // nothrow
   108     {
   109         BOOST_INTERLOCKED_INCREMENT( &weak_count_ );
   110     }
   111 
   112     void weak_release() // nothrow
   113     {
   114         if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
   115         {
   116             destroy();
   117         }
   118     }
   119 
   120     long use_count() const // nothrow
   121     {
   122         return static_cast<long const volatile &>( use_count_ );
   123     }
   124 };
   125 
   126 } // namespace detail
   127 
   128 } // namespace boost
   129 
   130 #endif  // #ifndef BOOST_DETAIL_SP_COUNTED_BASE_W32_HPP_INCLUDED