1 #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED 2 #define BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_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 // detail/local_counted_base.hpp 11 // 12 // Copyright 2017 Peter Dimov 13 // 14 // Distributed under the Boost Software License, Version 1.0. (See 15 // accompanying file LICENSE_1_0.txt or copy at 16 // http://www.boost.org/LICENSE_1_0.txt) 17 // 18 // See http://www.boost.org/libs/smart_ptr/ for documentation. 19 20 #include <boost/smart_ptr/detail/shared_count.hpp> 21 #include <boost/config.hpp> 22 #include <utility> 23 24 namespace boost 25 { 26 27 namespace detail 28 { 29 30 class local_counted_base 31 { 32 private: 33 34 local_counted_base & operator= ( local_counted_base const & ); 35 36 private: 37 38 // not 'int' or 'unsigned' to avoid aliasing and enable optimizations 39 enum count_type { min_ = 0, initial_ = 1, max_ = 2147483647 }; 40 41 count_type local_use_count_; 42 43 public: 44 local_counted_base()45 BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) 46 { 47 } 48 local_counted_base(local_counted_base const &)49 BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) 50 { 51 } 52 ~local_counted_base()53 virtual ~local_counted_base() /*BOOST_SP_NOEXCEPT*/ 54 { 55 } 56 57 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT = 0; 58 59 virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT = 0; 60 add_ref()61 void add_ref() BOOST_SP_NOEXCEPT 62 { 63 #if !defined(__NVCC__) 64 #if defined( __has_builtin ) 65 # if __has_builtin( __builtin_assume ) 66 67 __builtin_assume( local_use_count_ >= 1 ); 68 69 # endif 70 #endif 71 #endif 72 73 local_use_count_ = static_cast<count_type>( local_use_count_ + 1 ); 74 } 75 release()76 void release() BOOST_SP_NOEXCEPT 77 { 78 local_use_count_ = static_cast<count_type>( local_use_count_ - 1 ); 79 80 if( local_use_count_ == 0 ) 81 { 82 local_cb_destroy(); 83 } 84 } 85 local_use_count() const86 long local_use_count() const BOOST_SP_NOEXCEPT 87 { 88 return local_use_count_; 89 } 90 }; 91 92 class local_counted_impl: public local_counted_base 93 { 94 private: 95 96 local_counted_impl( local_counted_impl const & ); 97 98 private: 99 100 shared_count pn_; 101 102 public: 103 local_counted_impl(shared_count const & pn)104 explicit local_counted_impl( shared_count const& pn ): pn_( pn ) 105 { 106 } 107 108 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) 109 local_counted_impl(shared_count && pn)110 explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) ) 111 { 112 } 113 114 #endif 115 local_cb_destroy()116 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT 117 { 118 delete this; 119 } 120 local_cb_get_shared_count() const121 virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT 122 { 123 return pn_; 124 } 125 }; 126 127 class local_counted_impl_em: public local_counted_base 128 { 129 public: 130 131 shared_count pn_; 132 local_cb_destroy()133 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT 134 { 135 shared_count().swap( pn_ ); 136 } 137 local_cb_get_shared_count() const138 virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT 139 { 140 return pn_; 141 } 142 }; 143 144 } // namespace detail 145 146 } // namespace boost 147 148 #endif // #ifndef BOOST_SMART_PTR_DETAIL_LOCAL_COUNTED_BASE_HPP_INCLUDED 149