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
24namespace boost
25{
26
27namespace detail
28{
29
30class local_counted_base
31{
32private:
33
34 local_counted_base & operator= ( local_counted_base const & );
35
36private:
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
43public:
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
92class local_counted_impl: public local_counted_base
93{
94private:
95
96 local_counted_impl( local_counted_impl const & );
97
98private:
99
100 shared_count pn_;
101
102public:
103
104 explicit local_counted_impl( shared_count const& pn ): pn_( pn )
105 {
106 }
107
108#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
109
110 explicit local_counted_impl( shared_count && pn ): pn_( std::move(pn) )
111 {
112 }
113
114#endif
115
116 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
117 {
118 delete this;
119 }
120
121 virtual boost::detail::shared_count local_cb_get_shared_count() const BOOST_SP_NOEXCEPT
122 {
123 return pn_;
124 }
125};
126
127class local_counted_impl_em: public local_counted_base
128{
129public:
130
131 shared_count pn_;
132
133 virtual void local_cb_destroy() BOOST_SP_NOEXCEPT
134 {
135 shared_count().swap( pn_ );
136 }
137
138 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