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