]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Distributed under the Boost Software License, Version 1.0. | |
3 | * (See accompanying file LICENSE_1_0.txt or copy at | |
4 | * http://www.boost.org/LICENSE_1_0.txt) | |
5 | * | |
6 | * Copyright (c) 2011 Helge Bahmann | |
7 | * Copyright (c) 2013 Tim Blechmann | |
20effc67 | 8 | * Copyright (c) 2014, 2020 Andrey Semashev |
7c673cae FG |
9 | */ |
10 | /*! | |
11 | * \file atomic/atomic.hpp | |
12 | * | |
20effc67 | 13 | * This header contains definition of \c atomic template. |
7c673cae FG |
14 | */ |
15 | ||
16 | #ifndef BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ | |
17 | #define BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ | |
18 | ||
20effc67 TL |
19 | #include <cstddef> |
20 | #include <boost/cstdint.hpp> | |
21 | #include <boost/static_assert.hpp> | |
22 | #include <boost/memory_order.hpp> | |
7c673cae | 23 | #include <boost/atomic/capabilities.hpp> |
20effc67 TL |
24 | #include <boost/atomic/detail/config.hpp> |
25 | #include <boost/atomic/detail/classify.hpp> | |
26 | #include <boost/atomic/detail/atomic_impl.hpp> | |
27 | #include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp> | |
1e59de90 | 28 | #include <boost/atomic/detail/type_traits/is_nothrow_default_constructible.hpp> |
20effc67 | 29 | #include <boost/atomic/detail/header.hpp> |
7c673cae FG |
30 | |
31 | #ifdef BOOST_HAS_PRAGMA_ONCE | |
32 | #pragma once | |
33 | #endif | |
34 | ||
35 | namespace boost { | |
20effc67 TL |
36 | namespace atomics { |
37 | ||
38 | //! Atomic object | |
39 | template< typename T > | |
40 | class atomic : | |
41 | public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, false > | |
42 | { | |
43 | private: | |
44 | typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, false > base_type; | |
45 | typedef typename base_type::value_arg_type value_arg_type; | |
46 | ||
47 | public: | |
48 | typedef typename base_type::value_type value_type; | |
49 | // Deprecated, use value_type instead | |
50 | BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED | |
51 | typedef typename base_type::storage_type storage_type; | |
52 | ||
53 | BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::atomic<T> requires T to be a complete type"); | |
54 | #if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE) | |
55 | BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::atomic<T> requires T to be a trivially copyable type"); | |
56 | #endif | |
57 | ||
58 | public: | |
1e59de90 TL |
59 | BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic() BOOST_NOEXCEPT_IF(atomics::detail::is_nothrow_default_constructible< value_type >::value) : base_type() |
60 | { | |
61 | } | |
62 | ||
63 | BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) | |
64 | { | |
65 | } | |
20effc67 TL |
66 | |
67 | BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT | |
68 | { | |
69 | this->store(v); | |
70 | return v; | |
71 | } | |
72 | ||
73 | BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT | |
74 | { | |
75 | this->store(v); | |
76 | return v; | |
77 | } | |
78 | ||
79 | BOOST_FORCEINLINE operator value_type() const volatile BOOST_NOEXCEPT | |
80 | { | |
81 | return this->load(); | |
82 | } | |
83 | ||
84 | // Deprecated, use value() instead | |
85 | BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED | |
86 | BOOST_FORCEINLINE typename base_type::storage_type& storage() BOOST_NOEXCEPT { return base_type::storage(); } | |
87 | BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED | |
88 | BOOST_FORCEINLINE typename base_type::storage_type volatile& storage() volatile BOOST_NOEXCEPT { return base_type::storage(); } | |
89 | BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED | |
90 | BOOST_FORCEINLINE typename base_type::storage_type const& storage() const BOOST_NOEXCEPT { return base_type::storage(); } | |
91 | BOOST_ATOMIC_DETAIL_STORAGE_DEPRECATED | |
92 | BOOST_FORCEINLINE typename base_type::storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return base_type::storage(); } | |
93 | ||
94 | BOOST_DELETED_FUNCTION(atomic(atomic const&)) | |
95 | BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&)) | |
96 | BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile) | |
97 | }; | |
98 | ||
99 | typedef atomic< char > atomic_char; | |
100 | typedef atomic< unsigned char > atomic_uchar; | |
101 | typedef atomic< signed char > atomic_schar; | |
102 | typedef atomic< uint8_t > atomic_uint8_t; | |
103 | typedef atomic< int8_t > atomic_int8_t; | |
104 | typedef atomic< unsigned short > atomic_ushort; | |
105 | typedef atomic< short > atomic_short; | |
106 | typedef atomic< uint16_t > atomic_uint16_t; | |
107 | typedef atomic< int16_t > atomic_int16_t; | |
108 | typedef atomic< unsigned int > atomic_uint; | |
109 | typedef atomic< int > atomic_int; | |
110 | typedef atomic< uint32_t > atomic_uint32_t; | |
111 | typedef atomic< int32_t > atomic_int32_t; | |
112 | typedef atomic< unsigned long > atomic_ulong; | |
113 | typedef atomic< long > atomic_long; | |
114 | typedef atomic< uint64_t > atomic_uint64_t; | |
115 | typedef atomic< int64_t > atomic_int64_t; | |
116 | #ifdef BOOST_HAS_LONG_LONG | |
117 | typedef atomic< boost::ulong_long_type > atomic_ullong; | |
118 | typedef atomic< boost::long_long_type > atomic_llong; | |
119 | #endif | |
120 | typedef atomic< void* > atomic_address; | |
121 | typedef atomic< bool > atomic_bool; | |
122 | typedef atomic< wchar_t > atomic_wchar_t; | |
123 | #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811 | |
124 | typedef atomic< char8_t > atomic_char8_t; | |
125 | #endif | |
126 | #if !defined(BOOST_NO_CXX11_CHAR16_T) | |
127 | typedef atomic< char16_t > atomic_char16_t; | |
128 | #endif | |
129 | #if !defined(BOOST_NO_CXX11_CHAR32_T) | |
130 | typedef atomic< char32_t > atomic_char32_t; | |
131 | #endif | |
132 | ||
133 | typedef atomic< int_least8_t > atomic_int_least8_t; | |
134 | typedef atomic< uint_least8_t > atomic_uint_least8_t; | |
135 | typedef atomic< int_least16_t > atomic_int_least16_t; | |
136 | typedef atomic< uint_least16_t > atomic_uint_least16_t; | |
137 | typedef atomic< int_least32_t > atomic_int_least32_t; | |
138 | typedef atomic< uint_least32_t > atomic_uint_least32_t; | |
139 | typedef atomic< int_least64_t > atomic_int_least64_t; | |
140 | typedef atomic< uint_least64_t > atomic_uint_least64_t; | |
141 | typedef atomic< int_fast8_t > atomic_int_fast8_t; | |
142 | typedef atomic< uint_fast8_t > atomic_uint_fast8_t; | |
143 | typedef atomic< int_fast16_t > atomic_int_fast16_t; | |
144 | typedef atomic< uint_fast16_t > atomic_uint_fast16_t; | |
145 | typedef atomic< int_fast32_t > atomic_int_fast32_t; | |
146 | typedef atomic< uint_fast32_t > atomic_uint_fast32_t; | |
147 | typedef atomic< int_fast64_t > atomic_int_fast64_t; | |
148 | typedef atomic< uint_fast64_t > atomic_uint_fast64_t; | |
149 | typedef atomic< intmax_t > atomic_intmax_t; | |
150 | typedef atomic< uintmax_t > atomic_uintmax_t; | |
151 | ||
152 | #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) | |
153 | typedef atomic< float > atomic_float_t; | |
154 | typedef atomic< double > atomic_double_t; | |
155 | typedef atomic< long double > atomic_long_double_t; | |
156 | #endif | |
157 | ||
158 | typedef atomic< std::size_t > atomic_size_t; | |
159 | typedef atomic< std::ptrdiff_t > atomic_ptrdiff_t; | |
160 | ||
161 | #if defined(BOOST_HAS_INTPTR_T) | |
162 | typedef atomic< boost::intptr_t > atomic_intptr_t; | |
163 | typedef atomic< boost::uintptr_t > atomic_uintptr_t; | |
164 | #endif | |
165 | ||
166 | // Select the lock-free atomic types that has natively supported waiting/notifying operations. | |
167 | // Prefer 32-bit types the most as those have the best performance on current 32 and 64-bit architectures. | |
168 | #if BOOST_ATOMIC_INT32_LOCK_FREE == 2 && BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY == 2 | |
169 | typedef atomic< uint32_t > atomic_unsigned_lock_free; | |
170 | typedef atomic< int32_t > atomic_signed_lock_free; | |
171 | #elif BOOST_ATOMIC_INT64_LOCK_FREE == 2 && BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY == 2 | |
172 | typedef atomic< uint64_t > atomic_unsigned_lock_free; | |
173 | typedef atomic< int64_t > atomic_signed_lock_free; | |
174 | #elif BOOST_ATOMIC_INT16_LOCK_FREE == 2 && BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY == 2 | |
175 | typedef atomic< uint16_t > atomic_unsigned_lock_free; | |
176 | typedef atomic< int16_t > atomic_signed_lock_free; | |
177 | #elif BOOST_ATOMIC_INT8_LOCK_FREE == 2 && BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY == 2 | |
178 | typedef atomic< uint8_t > atomic_unsigned_lock_free; | |
179 | typedef atomic< int8_t > atomic_signed_lock_free; | |
180 | #elif BOOST_ATOMIC_INT32_LOCK_FREE == 2 | |
181 | typedef atomic< uint32_t > atomic_unsigned_lock_free; | |
182 | typedef atomic< int32_t > atomic_signed_lock_free; | |
183 | #elif BOOST_ATOMIC_INT64_LOCK_FREE == 2 | |
184 | typedef atomic< uint64_t > atomic_unsigned_lock_free; | |
185 | typedef atomic< int64_t > atomic_signed_lock_free; | |
186 | #elif BOOST_ATOMIC_INT16_LOCK_FREE == 2 | |
187 | typedef atomic< uint16_t > atomic_unsigned_lock_free; | |
188 | typedef atomic< int16_t > atomic_signed_lock_free; | |
189 | #elif BOOST_ATOMIC_INT8_LOCK_FREE == 2 | |
190 | typedef atomic< uint8_t > atomic_unsigned_lock_free; | |
191 | typedef atomic< int8_t > atomic_signed_lock_free; | |
192 | #else | |
193 | #define BOOST_ATOMIC_DETAIL_NO_LOCK_FREE_TYPEDEFS | |
194 | #endif | |
195 | ||
196 | } // namespace atomics | |
7c673cae FG |
197 | |
198 | using atomics::atomic; | |
199 | ||
200 | using atomics::atomic_char; | |
201 | using atomics::atomic_uchar; | |
202 | using atomics::atomic_schar; | |
203 | using atomics::atomic_uint8_t; | |
204 | using atomics::atomic_int8_t; | |
205 | using atomics::atomic_ushort; | |
206 | using atomics::atomic_short; | |
207 | using atomics::atomic_uint16_t; | |
208 | using atomics::atomic_int16_t; | |
209 | using atomics::atomic_uint; | |
210 | using atomics::atomic_int; | |
211 | using atomics::atomic_uint32_t; | |
212 | using atomics::atomic_int32_t; | |
213 | using atomics::atomic_ulong; | |
214 | using atomics::atomic_long; | |
215 | using atomics::atomic_uint64_t; | |
216 | using atomics::atomic_int64_t; | |
217 | #ifdef BOOST_HAS_LONG_LONG | |
218 | using atomics::atomic_ullong; | |
219 | using atomics::atomic_llong; | |
220 | #endif | |
221 | using atomics::atomic_address; | |
222 | using atomics::atomic_bool; | |
223 | using atomics::atomic_wchar_t; | |
20effc67 TL |
224 | #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811 |
225 | using atomics::atomic_char8_t; | |
226 | #endif | |
7c673cae FG |
227 | #if !defined(BOOST_NO_CXX11_CHAR16_T) |
228 | using atomics::atomic_char16_t; | |
229 | #endif | |
230 | #if !defined(BOOST_NO_CXX11_CHAR32_T) | |
231 | using atomics::atomic_char32_t; | |
232 | #endif | |
233 | ||
234 | using atomics::atomic_int_least8_t; | |
235 | using atomics::atomic_uint_least8_t; | |
236 | using atomics::atomic_int_least16_t; | |
237 | using atomics::atomic_uint_least16_t; | |
238 | using atomics::atomic_int_least32_t; | |
239 | using atomics::atomic_uint_least32_t; | |
240 | using atomics::atomic_int_least64_t; | |
241 | using atomics::atomic_uint_least64_t; | |
242 | using atomics::atomic_int_fast8_t; | |
243 | using atomics::atomic_uint_fast8_t; | |
244 | using atomics::atomic_int_fast16_t; | |
245 | using atomics::atomic_uint_fast16_t; | |
246 | using atomics::atomic_int_fast32_t; | |
247 | using atomics::atomic_uint_fast32_t; | |
248 | using atomics::atomic_int_fast64_t; | |
249 | using atomics::atomic_uint_fast64_t; | |
250 | using atomics::atomic_intmax_t; | |
251 | using atomics::atomic_uintmax_t; | |
252 | ||
11fdf7f2 TL |
253 | #if !defined(BOOST_ATOMIC_NO_FLOATING_POINT) |
254 | using atomics::atomic_float_t; | |
255 | using atomics::atomic_double_t; | |
256 | using atomics::atomic_long_double_t; | |
257 | #endif | |
258 | ||
7c673cae FG |
259 | using atomics::atomic_size_t; |
260 | using atomics::atomic_ptrdiff_t; | |
261 | ||
262 | #if defined(BOOST_HAS_INTPTR_T) | |
263 | using atomics::atomic_intptr_t; | |
264 | using atomics::atomic_uintptr_t; | |
265 | #endif | |
266 | ||
20effc67 TL |
267 | #if !defined(BOOST_ATOMIC_DETAIL_NO_LOCK_FREE_TYPEDEFS) |
268 | using atomics::atomic_unsigned_lock_free; | |
269 | using atomics::atomic_signed_lock_free; | |
270 | #endif | |
271 | #undef BOOST_ATOMIC_DETAIL_NO_LOCK_FREE_TYPEDEFS | |
272 | ||
7c673cae FG |
273 | } // namespace boost |
274 | ||
20effc67 TL |
275 | #include <boost/atomic/detail/footer.hpp> |
276 | ||
7c673cae | 277 | #endif // BOOST_ATOMIC_ATOMIC_HPP_INCLUDED_ |