]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/smart_ptr/detail/sp_counted_base_clang.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / smart_ptr / detail / sp_counted_base_clang.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
2 #define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_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_clang.hpp - __c11 clang intrinsics
11 //
12 //  Copyright (c) 2007, 2013, 2015 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
18 #include <boost/smart_ptr/detail/sp_typeinfo_.hpp>
19 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
20 #include <boost/config.hpp>
21 #include <boost/cstdint.hpp>
22
23 namespace boost
24 {
25
26 namespace detail
27 {
28
29 typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
30
31 inline void atomic_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
32 {
33     __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
34 }
35
36 inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
37 {
38     return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
39 }
40
41 inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
42 {
43     // long r = *pw;
44     // if( r != 0 ) ++*pw;
45     // return r;
46
47     boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
48
49     for( ;; )
50     {
51         if( r == 0 )
52         {
53             return r;
54         }
55
56         if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
57         {
58             return r;
59         }
60     }    
61 }
62
63 #if defined(__clang__)
64 # pragma clang diagnostic push
65 # pragma clang diagnostic ignored "-Wweak-vtables"
66 #endif
67
68 class BOOST_SYMBOL_VISIBLE sp_counted_base
69 {
70 private:
71
72     sp_counted_base( sp_counted_base const & );
73     sp_counted_base & operator= ( sp_counted_base const & );
74
75     atomic_int_least32_t use_count_;    // #shared
76     atomic_int_least32_t weak_count_;   // #weak + (#shared != 0)
77
78 public:
79
80     sp_counted_base() BOOST_SP_NOEXCEPT
81     {
82         __c11_atomic_init( &use_count_, 1 );
83         __c11_atomic_init( &weak_count_, 1 );
84     }
85
86     virtual ~sp_counted_base() /*BOOST_SP_NOEXCEPT*/
87     {
88     }
89
90     // dispose() is called when use_count_ drops to zero, to release
91     // the resources managed by *this.
92
93     virtual void dispose() BOOST_SP_NOEXCEPT = 0; // nothrow
94
95     // destroy() is called when weak_count_ drops to zero.
96
97     virtual void destroy() BOOST_SP_NOEXCEPT // nothrow
98     {
99         delete this;
100     }
101
102     virtual void * get_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
103     virtual void * get_local_deleter( sp_typeinfo_ const & ti ) BOOST_SP_NOEXCEPT = 0;
104     virtual void * get_untyped_deleter() BOOST_SP_NOEXCEPT = 0;
105
106     void add_ref_copy() BOOST_SP_NOEXCEPT
107     {
108         atomic_increment( &use_count_ );
109     }
110
111     bool add_ref_lock() BOOST_SP_NOEXCEPT // true on success
112     {
113         return atomic_conditional_increment( &use_count_ ) != 0;
114     }
115
116     void release() BOOST_SP_NOEXCEPT
117     {
118         if( atomic_decrement( &use_count_ ) == 1 )
119         {
120             dispose();
121             weak_release();
122         }
123     }
124
125     void weak_add_ref() BOOST_SP_NOEXCEPT
126     {
127         atomic_increment( &weak_count_ );
128     }
129
130     void weak_release() BOOST_SP_NOEXCEPT
131     {
132         if( atomic_decrement( &weak_count_ ) == 1 )
133         {
134             destroy();
135         }
136     }
137
138     long use_count() const BOOST_SP_NOEXCEPT
139     {
140         return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
141     }
142 };
143
144 #if defined(__clang__)
145 # pragma clang diagnostic pop
146 #endif
147
148 } // namespace detail
149
150 } // namespace boost
151
152 #endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED