]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / sp_counted_base_std_atomic.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED
2#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_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/sp_counted_base_std_atomic.hpp - C++11 std::atomic
11//
12// Copyright (c) 2007, 2013 Peter Dimov
13//
14// Distributed under the Boost Software License, Version 1.0.
15// See accompanying file LICENSE_1_0.txt or copy at
16// http://www.boost.org/LICENSE_1_0.txt
17
92f5a8d4
TL
18#include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
19#include <boost/smart_ptr/detail/sp_noexcept.hpp>
20#include <boost/config.hpp>
7c673cae
FG
21#include <atomic>
22#include <cstdint>
23
20effc67
TL
24#if defined(BOOST_SP_REPORT_IMPLEMENTATION)
25
26#include <boost/config/pragma_message.hpp>
27BOOST_PRAGMA_MESSAGE("Using std::atomic sp_counted_base")
28
29#endif
30
7c673cae
FG
31namespace boost
32{
33
34namespace detail
35{
36
92f5a8d4 37inline void atomic_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
7c673cae
FG
38{
39 pw->fetch_add( 1, std::memory_order_relaxed );
40}
41
92f5a8d4 42inline std::int_least32_t atomic_decrement( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
7c673cae
FG
43{
44 return pw->fetch_sub( 1, std::memory_order_acq_rel );
45}
46
92f5a8d4 47inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
7c673cae
FG
48{
49 // long r = *pw;
50 // if( r != 0 ) ++*pw;
51 // return r;
52
53 std::int_least32_t r = pw->load( std::memory_order_relaxed );
54
55 for( ;; )
56 {
57 if( r == 0 )
58 {
59 return r;
60 }
61
62 if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
63 {
64 return r;
65 }
66 }
67}
68
92f5a8d4 69class BOOST_SYMBOL_VISIBLE sp_counted_base
7c673cae
FG
70{
71private:
72
73 sp_counted_base( sp_counted_base const & );
74 sp_counted_base & operator= ( sp_counted_base const & );
75
11fdf7f2
TL
76 std::atomic_int_least32_t use_count_; // #shared
77 std::atomic_int_least32_t weak_count_; // #weak + (#shared != 0)
7c673cae
FG
78
79public:
80
92f5a8d4 81 sp_counted_base() BOOST_SP_NOEXCEPT: use_count_( 1 ), weak_count_( 1 )
7c673cae
FG
82 {
83 }
84
92f5a8d4 85 virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
7c673cae
FG
86 {
87 }
88
89 // dispose() is called when use_count_ drops to zero, to release
90 // the resources managed by *this.
91
92f5a8d4 92 virtual void dispose() BOOST_SP_NOEXCEPT = 0;
7c673cae
FG
93
94 // destroy() is called when weak_count_ drops to zero.
95
92f5a8d4 96 virtual void destroy() BOOST_SP_NOEXCEPT
7c673cae
FG
97 {
98 delete this;
99 }
100
92f5a8d4
TL
101 virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
102 virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
103 virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
7c673cae 104
92f5a8d4 105 void add_ref_copy() BOOST_SP_NOEXCEPT
7c673cae
FG
106 {
107 atomic_increment( &use_count_ );
108 }
109
92f5a8d4 110 bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
7c673cae
FG
111 {
112 return atomic_conditional_increment( &use_count_ ) != 0;
113 }
114
92f5a8d4 115 void release() BOOST_SP_NOEXCEPT
7c673cae
FG
116 {
117 if( atomic_decrement( &use_count_ ) == 1 )
118 {
119 dispose();
120 weak_release();
121 }
122 }
123
92f5a8d4 124 void weak_add_ref() BOOST_SP_NOEXCEPT
7c673cae
FG
125 {
126 atomic_increment( &weak_count_ );
127 }
128
92f5a8d4 129 void weak_release() BOOST_SP_NOEXCEPT
7c673cae
FG
130 {
131 if( atomic_decrement( &weak_count_ ) == 1 )
132 {
133 destroy();
134 }
135 }
136
92f5a8d4 137 long use_count() const BOOST_SP_NOEXCEPT
7c673cae
FG
138 {
139 return use_count_.load( std::memory_order_acquire );
140 }
141};
142
143} // namespace detail
144
145} // namespace boost
146
147#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_STD_ATOMIC_HPP_INCLUDED