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 BOOST_SYMBOL_VISIBLE 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 | |
45 | BOOST_CONSTEXPR local_counted_base() BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) |
46 | { |
47 | } |
48 | |
49 | BOOST_CONSTEXPR local_counted_base( local_counted_base const & ) BOOST_SP_NOEXCEPT: local_use_count_( initial_ ) |
50 | { |
51 | } |
52 | |
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 | |
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 | |
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 | |
86 | long local_use_count() const BOOST_SP_NOEXCEPT |
87 | { |
88 | return local_use_count_; |
89 | } |
90 | }; |
91 | |
92 | class BOOST_SYMBOL_VISIBLE 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 | |
104 | explicit local_counted_impl( shared_count const& pn ) BOOST_SP_NOEXCEPT: pn_( pn ) |
105 | { |
106 | } |
107 | |
108 | #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) |
109 | |
110 | explicit local_counted_impl( shared_count && pn ) BOOST_SP_NOEXCEPT: pn_( std::move(pn) ) |
111 | { |
112 | } |
113 | |
114 | #endif |
115 | |
116 | void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE |
117 | { |
118 | delete this; |
119 | } |
120 | |
121 | boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE |
122 | { |
123 | return pn_; |
124 | } |
125 | }; |
126 | |
127 | class BOOST_SYMBOL_VISIBLE local_counted_impl_em: public local_counted_base |
128 | { |
129 | public: |
130 | |
131 | shared_count pn_; |
132 | |
133 | void local_cb_destroy() BOOST_SP_NOEXCEPT BOOST_OVERRIDE |
134 | { |
135 | shared_count().swap( r&: pn_ ); |
136 | } |
137 | |
138 | boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT BOOST_OVERRIDE |
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 |