1 1.1 mrg // -*- C++ -*- header. 2 1.1 mrg 3 1.13 mrg // Copyright (C) 2008-2022 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.3 mrg /** @file include/atomic 26 1.1 mrg * This is a Standard C++ Library header. 27 1.1 mrg */ 28 1.1 mrg 29 1.1 mrg // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl. 30 1.1 mrg // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html 31 1.1 mrg 32 1.1 mrg #ifndef _GLIBCXX_ATOMIC 33 1.1 mrg #define _GLIBCXX_ATOMIC 1 34 1.1 mrg 35 1.1 mrg #pragma GCC system_header 36 1.1 mrg 37 1.3 mrg #if __cplusplus < 201103L 38 1.1 mrg # include <bits/c++0x_warning.h> 39 1.5 mrg #else 40 1.1 mrg 41 1.1 mrg #include <bits/atomic_base.h> 42 1.1 mrg 43 1.3 mrg namespace std _GLIBCXX_VISIBILITY(default) 44 1.3 mrg { 45 1.3 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 1.1 mrg 47 1.1 mrg /** 48 1.1 mrg * @addtogroup atomics 49 1.1 mrg * @{ 50 1.1 mrg */ 51 1.1 mrg 52 1.11 mrg #if __cplusplus >= 201703L 53 1.13 mrg # define __cpp_lib_atomic_is_always_lock_free 201603L 54 1.9 mrg #endif 55 1.9 mrg 56 1.5 mrg template<typename _Tp> 57 1.5 mrg struct atomic; 58 1.5 mrg 59 1.5 mrg /// atomic<bool> 60 1.3 mrg // NB: No operators or fetch-operations for this type. 61 1.5 mrg template<> 62 1.5 mrg struct atomic<bool> 63 1.3 mrg { 64 1.11 mrg using value_type = bool; 65 1.11 mrg 66 1.3 mrg private: 67 1.3 mrg __atomic_base<bool> _M_base; 68 1.3 mrg 69 1.3 mrg public: 70 1.5 mrg atomic() noexcept = default; 71 1.5 mrg ~atomic() noexcept = default; 72 1.5 mrg atomic(const atomic&) = delete; 73 1.5 mrg atomic& operator=(const atomic&) = delete; 74 1.5 mrg atomic& operator=(const atomic&) volatile = delete; 75 1.3 mrg 76 1.5 mrg constexpr atomic(bool __i) noexcept : _M_base(__i) { } 77 1.3 mrg 78 1.3 mrg bool 79 1.3 mrg operator=(bool __i) noexcept 80 1.3 mrg { return _M_base.operator=(__i); } 81 1.3 mrg 82 1.3 mrg bool 83 1.3 mrg operator=(bool __i) volatile noexcept 84 1.3 mrg { return _M_base.operator=(__i); } 85 1.3 mrg 86 1.3 mrg operator bool() const noexcept 87 1.3 mrg { return _M_base.load(); } 88 1.3 mrg 89 1.3 mrg operator bool() const volatile noexcept 90 1.3 mrg { return _M_base.load(); } 91 1.3 mrg 92 1.3 mrg bool 93 1.3 mrg is_lock_free() const noexcept { return _M_base.is_lock_free(); } 94 1.3 mrg 95 1.3 mrg bool 96 1.3 mrg is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } 97 1.3 mrg 98 1.11 mrg #if __cplusplus >= 201703L 99 1.9 mrg static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2; 100 1.9 mrg #endif 101 1.9 mrg 102 1.3 mrg void 103 1.3 mrg store(bool __i, memory_order __m = memory_order_seq_cst) noexcept 104 1.3 mrg { _M_base.store(__i, __m); } 105 1.3 mrg 106 1.3 mrg void 107 1.3 mrg store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept 108 1.3 mrg { _M_base.store(__i, __m); } 109 1.3 mrg 110 1.3 mrg bool 111 1.3 mrg load(memory_order __m = memory_order_seq_cst) const noexcept 112 1.3 mrg { return _M_base.load(__m); } 113 1.3 mrg 114 1.3 mrg bool 115 1.3 mrg load(memory_order __m = memory_order_seq_cst) const volatile noexcept 116 1.3 mrg { return _M_base.load(__m); } 117 1.3 mrg 118 1.3 mrg bool 119 1.3 mrg exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept 120 1.3 mrg { return _M_base.exchange(__i, __m); } 121 1.3 mrg 122 1.3 mrg bool 123 1.3 mrg exchange(bool __i, 124 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 125 1.3 mrg { return _M_base.exchange(__i, __m); } 126 1.3 mrg 127 1.3 mrg bool 128 1.3 mrg compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 129 1.3 mrg memory_order __m2) noexcept 130 1.3 mrg { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 131 1.3 mrg 132 1.3 mrg bool 133 1.3 mrg compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 134 1.3 mrg memory_order __m2) volatile noexcept 135 1.3 mrg { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 136 1.3 mrg 137 1.3 mrg bool 138 1.3 mrg compare_exchange_weak(bool& __i1, bool __i2, 139 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 140 1.3 mrg { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 141 1.3 mrg 142 1.3 mrg bool 143 1.3 mrg compare_exchange_weak(bool& __i1, bool __i2, 144 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 145 1.3 mrg { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 146 1.3 mrg 147 1.3 mrg bool 148 1.3 mrg compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 149 1.3 mrg memory_order __m2) noexcept 150 1.3 mrg { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 151 1.3 mrg 152 1.3 mrg bool 153 1.3 mrg compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 154 1.3 mrg memory_order __m2) volatile noexcept 155 1.3 mrg { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 156 1.3 mrg 157 1.3 mrg bool 158 1.3 mrg compare_exchange_strong(bool& __i1, bool __i2, 159 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 160 1.3 mrg { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 161 1.3 mrg 162 1.3 mrg bool 163 1.3 mrg compare_exchange_strong(bool& __i1, bool __i2, 164 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 165 1.3 mrg { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 166 1.13 mrg 167 1.13 mrg #if __cpp_lib_atomic_wait 168 1.13 mrg void 169 1.13 mrg wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept 170 1.13 mrg { _M_base.wait(__old, __m); } 171 1.13 mrg 172 1.13 mrg // TODO add const volatile overload 173 1.13 mrg 174 1.13 mrg void 175 1.13 mrg notify_one() noexcept 176 1.13 mrg { _M_base.notify_one(); } 177 1.13 mrg 178 1.13 mrg void 179 1.13 mrg notify_all() noexcept 180 1.13 mrg { _M_base.notify_all(); } 181 1.13 mrg #endif // __cpp_lib_atomic_wait 182 1.3 mrg }; 183 1.1 mrg 184 1.13 mrg /// @cond undocumented 185 1.13 mrg #if __cpp_lib_atomic_value_initialization 186 1.13 mrg # define _GLIBCXX20_INIT(I) = I 187 1.13 mrg #else 188 1.12 mrg # define _GLIBCXX20_INIT(I) 189 1.12 mrg #endif 190 1.13 mrg /// @endcond 191 1.1 mrg 192 1.3 mrg /** 193 1.3 mrg * @brief Generic atomic type, primary class template. 194 1.3 mrg * 195 1.12 mrg * @tparam _Tp Type to be made atomic, must be trivially copyable. 196 1.3 mrg */ 197 1.1 mrg template<typename _Tp> 198 1.1 mrg struct atomic 199 1.1 mrg { 200 1.11 mrg using value_type = _Tp; 201 1.11 mrg 202 1.1 mrg private: 203 1.5 mrg // Align 1/2/4/8/16-byte types to at least their size. 204 1.5 mrg static constexpr int _S_min_alignment 205 1.5 mrg = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16 206 1.5 mrg ? 0 : sizeof(_Tp); 207 1.5 mrg 208 1.5 mrg static constexpr int _S_alignment 209 1.5 mrg = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp); 210 1.5 mrg 211 1.12 mrg alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp()); 212 1.5 mrg 213 1.5 mrg static_assert(__is_trivially_copyable(_Tp), 214 1.5 mrg "std::atomic requires a trivially copyable type"); 215 1.5 mrg 216 1.5 mrg static_assert(sizeof(_Tp) > 0, 217 1.5 mrg "Incomplete or zero-sized types are not supported"); 218 1.1 mrg 219 1.12 mrg #if __cplusplus > 201703L 220 1.12 mrg static_assert(is_copy_constructible_v<_Tp>); 221 1.12 mrg static_assert(is_move_constructible_v<_Tp>); 222 1.12 mrg static_assert(is_copy_assignable_v<_Tp>); 223 1.12 mrg static_assert(is_move_assignable_v<_Tp>); 224 1.12 mrg #endif 225 1.12 mrg 226 1.1 mrg public: 227 1.12 mrg atomic() = default; 228 1.3 mrg ~atomic() noexcept = default; 229 1.1 mrg atomic(const atomic&) = delete; 230 1.3 mrg atomic& operator=(const atomic&) = delete; 231 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 232 1.1 mrg 233 1.3 mrg constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } 234 1.3 mrg 235 1.3 mrg operator _Tp() const noexcept 236 1.3 mrg { return load(); } 237 1.1 mrg 238 1.3 mrg operator _Tp() const volatile noexcept 239 1.3 mrg { return load(); } 240 1.1 mrg 241 1.1 mrg _Tp 242 1.9 mrg operator=(_Tp __i) noexcept 243 1.3 mrg { store(__i); return __i; } 244 1.3 mrg 245 1.3 mrg _Tp 246 1.9 mrg operator=(_Tp __i) volatile noexcept 247 1.3 mrg { store(__i); return __i; } 248 1.3 mrg 249 1.3 mrg bool 250 1.3 mrg is_lock_free() const noexcept 251 1.5 mrg { 252 1.5 mrg // Produce a fake, minimally aligned pointer. 253 1.5 mrg return __atomic_is_lock_free(sizeof(_M_i), 254 1.11 mrg reinterpret_cast<void *>(-_S_alignment)); 255 1.5 mrg } 256 1.1 mrg 257 1.1 mrg bool 258 1.3 mrg is_lock_free() const volatile noexcept 259 1.5 mrg { 260 1.5 mrg // Produce a fake, minimally aligned pointer. 261 1.5 mrg return __atomic_is_lock_free(sizeof(_M_i), 262 1.11 mrg reinterpret_cast<void *>(-_S_alignment)); 263 1.5 mrg } 264 1.3 mrg 265 1.11 mrg #if __cplusplus >= 201703L 266 1.9 mrg static constexpr bool is_always_lock_free 267 1.9 mrg = __atomic_always_lock_free(sizeof(_M_i), 0); 268 1.9 mrg #endif 269 1.9 mrg 270 1.3 mrg void 271 1.5 mrg store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 272 1.13 mrg { 273 1.13 mrg __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); 274 1.13 mrg } 275 1.1 mrg 276 1.1 mrg void 277 1.5 mrg store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept 278 1.13 mrg { 279 1.13 mrg __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); 280 1.13 mrg } 281 1.1 mrg 282 1.1 mrg _Tp 283 1.5 mrg load(memory_order __m = memory_order_seq_cst) const noexcept 284 1.6 mrg { 285 1.6 mrg alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 286 1.6 mrg _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 287 1.11 mrg __atomic_load(std::__addressof(_M_i), __ptr, int(__m)); 288 1.6 mrg return *__ptr; 289 1.3 mrg } 290 1.3 mrg 291 1.3 mrg _Tp 292 1.5 mrg load(memory_order __m = memory_order_seq_cst) const volatile noexcept 293 1.6 mrg { 294 1.6 mrg alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 295 1.6 mrg _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 296 1.11 mrg __atomic_load(std::__addressof(_M_i), __ptr, int(__m)); 297 1.6 mrg return *__ptr; 298 1.3 mrg } 299 1.3 mrg 300 1.3 mrg _Tp 301 1.5 mrg exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept 302 1.6 mrg { 303 1.6 mrg alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 304 1.6 mrg _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 305 1.9 mrg __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), 306 1.11 mrg __ptr, int(__m)); 307 1.6 mrg return *__ptr; 308 1.3 mrg } 309 1.1 mrg 310 1.1 mrg _Tp 311 1.9 mrg exchange(_Tp __i, 312 1.5 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 313 1.6 mrg { 314 1.6 mrg alignas(_Tp) unsigned char __buf[sizeof(_Tp)]; 315 1.6 mrg _Tp* __ptr = reinterpret_cast<_Tp*>(__buf); 316 1.9 mrg __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i), 317 1.11 mrg __ptr, int(__m)); 318 1.6 mrg return *__ptr; 319 1.3 mrg } 320 1.3 mrg 321 1.3 mrg bool 322 1.9 mrg compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 323 1.3 mrg memory_order __f) noexcept 324 1.3 mrg { 325 1.13 mrg __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); 326 1.13 mrg 327 1.9 mrg return __atomic_compare_exchange(std::__addressof(_M_i), 328 1.9 mrg std::__addressof(__e), 329 1.9 mrg std::__addressof(__i), 330 1.11 mrg true, int(__s), int(__f)); 331 1.3 mrg } 332 1.1 mrg 333 1.1 mrg bool 334 1.9 mrg compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 335 1.3 mrg memory_order __f) volatile noexcept 336 1.3 mrg { 337 1.13 mrg __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); 338 1.13 mrg 339 1.9 mrg return __atomic_compare_exchange(std::__addressof(_M_i), 340 1.9 mrg std::__addressof(__e), 341 1.9 mrg std::__addressof(__i), 342 1.11 mrg true, int(__s), int(__f)); 343 1.3 mrg } 344 1.1 mrg 345 1.1 mrg bool 346 1.3 mrg compare_exchange_weak(_Tp& __e, _Tp __i, 347 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 348 1.5 mrg { return compare_exchange_weak(__e, __i, __m, 349 1.5 mrg __cmpexch_failure_order(__m)); } 350 1.1 mrg 351 1.1 mrg bool 352 1.3 mrg compare_exchange_weak(_Tp& __e, _Tp __i, 353 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 354 1.5 mrg { return compare_exchange_weak(__e, __i, __m, 355 1.5 mrg __cmpexch_failure_order(__m)); } 356 1.1 mrg 357 1.1 mrg bool 358 1.9 mrg compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 359 1.3 mrg memory_order __f) noexcept 360 1.3 mrg { 361 1.13 mrg __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); 362 1.13 mrg 363 1.9 mrg return __atomic_compare_exchange(std::__addressof(_M_i), 364 1.9 mrg std::__addressof(__e), 365 1.9 mrg std::__addressof(__i), 366 1.11 mrg false, int(__s), int(__f)); 367 1.3 mrg } 368 1.3 mrg 369 1.3 mrg bool 370 1.9 mrg compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 371 1.3 mrg memory_order __f) volatile noexcept 372 1.3 mrg { 373 1.13 mrg __glibcxx_assert(__is_valid_cmpexch_failure_order(__f)); 374 1.13 mrg 375 1.9 mrg return __atomic_compare_exchange(std::__addressof(_M_i), 376 1.9 mrg std::__addressof(__e), 377 1.9 mrg std::__addressof(__i), 378 1.11 mrg false, int(__s), int(__f)); 379 1.3 mrg } 380 1.3 mrg 381 1.3 mrg bool 382 1.3 mrg compare_exchange_strong(_Tp& __e, _Tp __i, 383 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 384 1.5 mrg { return compare_exchange_strong(__e, __i, __m, 385 1.5 mrg __cmpexch_failure_order(__m)); } 386 1.3 mrg 387 1.3 mrg bool 388 1.3 mrg compare_exchange_strong(_Tp& __e, _Tp __i, 389 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 390 1.5 mrg { return compare_exchange_strong(__e, __i, __m, 391 1.5 mrg __cmpexch_failure_order(__m)); } 392 1.13 mrg 393 1.13 mrg #if __cpp_lib_atomic_wait 394 1.13 mrg void 395 1.13 mrg wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept 396 1.13 mrg { 397 1.13 mrg std::__atomic_wait_address_v(&_M_i, __old, 398 1.13 mrg [__m, this] { return this->load(__m); }); 399 1.13 mrg } 400 1.13 mrg 401 1.13 mrg // TODO add const volatile overload 402 1.13 mrg 403 1.13 mrg void 404 1.13 mrg notify_one() noexcept 405 1.13 mrg { std::__atomic_notify_address(&_M_i, false); } 406 1.13 mrg 407 1.13 mrg void 408 1.13 mrg notify_all() noexcept 409 1.13 mrg { std::__atomic_notify_address(&_M_i, true); } 410 1.13 mrg #endif // __cpp_lib_atomic_wait 411 1.13 mrg 412 1.1 mrg }; 413 1.12 mrg #undef _GLIBCXX20_INIT 414 1.1 mrg 415 1.1 mrg /// Partial specialization for pointer types. 416 1.1 mrg template<typename _Tp> 417 1.3 mrg struct atomic<_Tp*> 418 1.1 mrg { 419 1.11 mrg using value_type = _Tp*; 420 1.11 mrg using difference_type = ptrdiff_t; 421 1.11 mrg 422 1.3 mrg typedef _Tp* __pointer_type; 423 1.3 mrg typedef __atomic_base<_Tp*> __base_type; 424 1.3 mrg __base_type _M_b; 425 1.3 mrg 426 1.3 mrg atomic() noexcept = default; 427 1.3 mrg ~atomic() noexcept = default; 428 1.1 mrg atomic(const atomic&) = delete; 429 1.3 mrg atomic& operator=(const atomic&) = delete; 430 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 431 1.1 mrg 432 1.3 mrg constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 433 1.3 mrg 434 1.3 mrg operator __pointer_type() const noexcept 435 1.3 mrg { return __pointer_type(_M_b); } 436 1.3 mrg 437 1.3 mrg operator __pointer_type() const volatile noexcept 438 1.3 mrg { return __pointer_type(_M_b); } 439 1.3 mrg 440 1.3 mrg __pointer_type 441 1.3 mrg operator=(__pointer_type __p) noexcept 442 1.3 mrg { return _M_b.operator=(__p); } 443 1.3 mrg 444 1.3 mrg __pointer_type 445 1.3 mrg operator=(__pointer_type __p) volatile noexcept 446 1.3 mrg { return _M_b.operator=(__p); } 447 1.3 mrg 448 1.3 mrg __pointer_type 449 1.3 mrg operator++(int) noexcept 450 1.11 mrg { 451 1.11 mrg #if __cplusplus >= 201703L 452 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 453 1.11 mrg #endif 454 1.11 mrg return _M_b++; 455 1.11 mrg } 456 1.3 mrg 457 1.3 mrg __pointer_type 458 1.3 mrg operator++(int) volatile noexcept 459 1.11 mrg { 460 1.11 mrg #if __cplusplus >= 201703L 461 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 462 1.11 mrg #endif 463 1.11 mrg return _M_b++; 464 1.11 mrg } 465 1.1 mrg 466 1.3 mrg __pointer_type 467 1.3 mrg operator--(int) noexcept 468 1.11 mrg { 469 1.11 mrg #if __cplusplus >= 201703L 470 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 471 1.11 mrg #endif 472 1.11 mrg return _M_b--; 473 1.11 mrg } 474 1.3 mrg 475 1.3 mrg __pointer_type 476 1.3 mrg operator--(int) volatile noexcept 477 1.11 mrg { 478 1.11 mrg #if __cplusplus >= 201703L 479 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 480 1.11 mrg #endif 481 1.11 mrg return _M_b--; 482 1.11 mrg } 483 1.3 mrg 484 1.3 mrg __pointer_type 485 1.3 mrg operator++() noexcept 486 1.11 mrg { 487 1.11 mrg #if __cplusplus >= 201703L 488 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 489 1.11 mrg #endif 490 1.11 mrg return ++_M_b; 491 1.11 mrg } 492 1.3 mrg 493 1.3 mrg __pointer_type 494 1.3 mrg operator++() volatile noexcept 495 1.11 mrg { 496 1.11 mrg #if __cplusplus >= 201703L 497 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 498 1.11 mrg #endif 499 1.11 mrg return ++_M_b; 500 1.11 mrg } 501 1.3 mrg 502 1.3 mrg __pointer_type 503 1.3 mrg operator--() noexcept 504 1.11 mrg { 505 1.11 mrg #if __cplusplus >= 201703L 506 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 507 1.11 mrg #endif 508 1.11 mrg return --_M_b; 509 1.11 mrg } 510 1.3 mrg 511 1.3 mrg __pointer_type 512 1.3 mrg operator--() volatile noexcept 513 1.11 mrg { 514 1.11 mrg #if __cplusplus >= 201703L 515 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 516 1.11 mrg #endif 517 1.11 mrg return --_M_b; 518 1.11 mrg } 519 1.1 mrg 520 1.3 mrg __pointer_type 521 1.3 mrg operator+=(ptrdiff_t __d) noexcept 522 1.11 mrg { 523 1.11 mrg #if __cplusplus >= 201703L 524 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 525 1.11 mrg #endif 526 1.11 mrg return _M_b.operator+=(__d); 527 1.11 mrg } 528 1.1 mrg 529 1.3 mrg __pointer_type 530 1.3 mrg operator+=(ptrdiff_t __d) volatile noexcept 531 1.11 mrg { 532 1.11 mrg #if __cplusplus >= 201703L 533 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 534 1.11 mrg #endif 535 1.11 mrg return _M_b.operator+=(__d); 536 1.11 mrg } 537 1.1 mrg 538 1.3 mrg __pointer_type 539 1.3 mrg operator-=(ptrdiff_t __d) noexcept 540 1.11 mrg { 541 1.11 mrg #if __cplusplus >= 201703L 542 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 543 1.11 mrg #endif 544 1.11 mrg return _M_b.operator-=(__d); 545 1.11 mrg } 546 1.1 mrg 547 1.3 mrg __pointer_type 548 1.3 mrg operator-=(ptrdiff_t __d) volatile noexcept 549 1.11 mrg { 550 1.11 mrg #if __cplusplus >= 201703L 551 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 552 1.11 mrg #endif 553 1.11 mrg return _M_b.operator-=(__d); 554 1.11 mrg } 555 1.1 mrg 556 1.1 mrg bool 557 1.3 mrg is_lock_free() const noexcept 558 1.3 mrg { return _M_b.is_lock_free(); } 559 1.1 mrg 560 1.1 mrg bool 561 1.3 mrg is_lock_free() const volatile noexcept 562 1.3 mrg { return _M_b.is_lock_free(); } 563 1.1 mrg 564 1.11 mrg #if __cplusplus >= 201703L 565 1.13 mrg static constexpr bool is_always_lock_free 566 1.13 mrg = ATOMIC_POINTER_LOCK_FREE == 2; 567 1.9 mrg #endif 568 1.9 mrg 569 1.3 mrg void 570 1.3 mrg store(__pointer_type __p, 571 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 572 1.3 mrg { return _M_b.store(__p, __m); } 573 1.1 mrg 574 1.3 mrg void 575 1.3 mrg store(__pointer_type __p, 576 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 577 1.3 mrg { return _M_b.store(__p, __m); } 578 1.3 mrg 579 1.3 mrg __pointer_type 580 1.3 mrg load(memory_order __m = memory_order_seq_cst) const noexcept 581 1.3 mrg { return _M_b.load(__m); } 582 1.3 mrg 583 1.3 mrg __pointer_type 584 1.3 mrg load(memory_order __m = memory_order_seq_cst) const volatile noexcept 585 1.3 mrg { return _M_b.load(__m); } 586 1.3 mrg 587 1.3 mrg __pointer_type 588 1.3 mrg exchange(__pointer_type __p, 589 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 590 1.3 mrg { return _M_b.exchange(__p, __m); } 591 1.3 mrg 592 1.3 mrg __pointer_type 593 1.3 mrg exchange(__pointer_type __p, 594 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 595 1.3 mrg { return _M_b.exchange(__p, __m); } 596 1.1 mrg 597 1.3 mrg bool 598 1.3 mrg compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 599 1.3 mrg memory_order __m1, memory_order __m2) noexcept 600 1.13 mrg { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); } 601 1.3 mrg 602 1.3 mrg bool 603 1.3 mrg compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 604 1.3 mrg memory_order __m1, 605 1.3 mrg memory_order __m2) volatile noexcept 606 1.13 mrg { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); } 607 1.1 mrg 608 1.3 mrg bool 609 1.3 mrg compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 610 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 611 1.1 mrg { 612 1.3 mrg return compare_exchange_weak(__p1, __p2, __m, 613 1.3 mrg __cmpexch_failure_order(__m)); 614 1.1 mrg } 615 1.1 mrg 616 1.3 mrg bool 617 1.3 mrg compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 618 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 619 1.3 mrg { 620 1.3 mrg return compare_exchange_weak(__p1, __p2, __m, 621 1.3 mrg __cmpexch_failure_order(__m)); 622 1.3 mrg } 623 1.1 mrg 624 1.3 mrg bool 625 1.3 mrg compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 626 1.3 mrg memory_order __m1, memory_order __m2) noexcept 627 1.3 mrg { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 628 1.1 mrg 629 1.3 mrg bool 630 1.3 mrg compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 631 1.3 mrg memory_order __m1, 632 1.3 mrg memory_order __m2) volatile noexcept 633 1.3 mrg { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 634 1.1 mrg 635 1.3 mrg bool 636 1.3 mrg compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 637 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 638 1.3 mrg { 639 1.3 mrg return _M_b.compare_exchange_strong(__p1, __p2, __m, 640 1.3 mrg __cmpexch_failure_order(__m)); 641 1.3 mrg } 642 1.1 mrg 643 1.3 mrg bool 644 1.3 mrg compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 645 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 646 1.3 mrg { 647 1.3 mrg return _M_b.compare_exchange_strong(__p1, __p2, __m, 648 1.3 mrg __cmpexch_failure_order(__m)); 649 1.3 mrg } 650 1.1 mrg 651 1.13 mrg #if __cpp_lib_atomic_wait 652 1.13 mrg void 653 1.13 mrg wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept 654 1.13 mrg { _M_b.wait(__old, __m); } 655 1.13 mrg 656 1.13 mrg // TODO add const volatile overload 657 1.13 mrg 658 1.13 mrg void 659 1.13 mrg notify_one() noexcept 660 1.13 mrg { _M_b.notify_one(); } 661 1.13 mrg 662 1.13 mrg void 663 1.13 mrg notify_all() noexcept 664 1.13 mrg { _M_b.notify_all(); } 665 1.13 mrg #endif // __cpp_lib_atomic_wait 666 1.13 mrg 667 1.3 mrg __pointer_type 668 1.3 mrg fetch_add(ptrdiff_t __d, 669 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 670 1.11 mrg { 671 1.11 mrg #if __cplusplus >= 201703L 672 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 673 1.11 mrg #endif 674 1.11 mrg return _M_b.fetch_add(__d, __m); 675 1.11 mrg } 676 1.3 mrg 677 1.3 mrg __pointer_type 678 1.3 mrg fetch_add(ptrdiff_t __d, 679 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 680 1.11 mrg { 681 1.11 mrg #if __cplusplus >= 201703L 682 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 683 1.11 mrg #endif 684 1.11 mrg return _M_b.fetch_add(__d, __m); 685 1.11 mrg } 686 1.3 mrg 687 1.3 mrg __pointer_type 688 1.3 mrg fetch_sub(ptrdiff_t __d, 689 1.3 mrg memory_order __m = memory_order_seq_cst) noexcept 690 1.11 mrg { 691 1.11 mrg #if __cplusplus >= 201703L 692 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 693 1.11 mrg #endif 694 1.11 mrg return _M_b.fetch_sub(__d, __m); 695 1.11 mrg } 696 1.3 mrg 697 1.3 mrg __pointer_type 698 1.3 mrg fetch_sub(ptrdiff_t __d, 699 1.3 mrg memory_order __m = memory_order_seq_cst) volatile noexcept 700 1.11 mrg { 701 1.11 mrg #if __cplusplus >= 201703L 702 1.11 mrg static_assert( is_object<_Tp>::value, "pointer to object type" ); 703 1.11 mrg #endif 704 1.11 mrg return _M_b.fetch_sub(__d, __m); 705 1.11 mrg } 706 1.1 mrg }; 707 1.1 mrg 708 1.1 mrg 709 1.1 mrg /// Explicit specialization for char. 710 1.1 mrg template<> 711 1.5 mrg struct atomic<char> : __atomic_base<char> 712 1.1 mrg { 713 1.1 mrg typedef char __integral_type; 714 1.5 mrg typedef __atomic_base<char> __base_type; 715 1.1 mrg 716 1.3 mrg atomic() noexcept = default; 717 1.3 mrg ~atomic() noexcept = default; 718 1.1 mrg atomic(const atomic&) = delete; 719 1.3 mrg atomic& operator=(const atomic&) = delete; 720 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 721 1.1 mrg 722 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 723 1.1 mrg 724 1.1 mrg using __base_type::operator __integral_type; 725 1.1 mrg using __base_type::operator=; 726 1.9 mrg 727 1.11 mrg #if __cplusplus >= 201703L 728 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; 729 1.9 mrg #endif 730 1.1 mrg }; 731 1.1 mrg 732 1.1 mrg /// Explicit specialization for signed char. 733 1.1 mrg template<> 734 1.5 mrg struct atomic<signed char> : __atomic_base<signed char> 735 1.1 mrg { 736 1.1 mrg typedef signed char __integral_type; 737 1.5 mrg typedef __atomic_base<signed char> __base_type; 738 1.1 mrg 739 1.3 mrg atomic() noexcept= default; 740 1.3 mrg ~atomic() noexcept = default; 741 1.1 mrg atomic(const atomic&) = delete; 742 1.3 mrg atomic& operator=(const atomic&) = delete; 743 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 744 1.1 mrg 745 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 746 1.1 mrg 747 1.1 mrg using __base_type::operator __integral_type; 748 1.1 mrg using __base_type::operator=; 749 1.9 mrg 750 1.11 mrg #if __cplusplus >= 201703L 751 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; 752 1.9 mrg #endif 753 1.1 mrg }; 754 1.1 mrg 755 1.1 mrg /// Explicit specialization for unsigned char. 756 1.1 mrg template<> 757 1.5 mrg struct atomic<unsigned char> : __atomic_base<unsigned char> 758 1.1 mrg { 759 1.1 mrg typedef unsigned char __integral_type; 760 1.5 mrg typedef __atomic_base<unsigned char> __base_type; 761 1.1 mrg 762 1.3 mrg atomic() noexcept= default; 763 1.3 mrg ~atomic() noexcept = default; 764 1.1 mrg atomic(const atomic&) = delete; 765 1.3 mrg atomic& operator=(const atomic&) = delete; 766 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 767 1.1 mrg 768 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 769 1.1 mrg 770 1.1 mrg using __base_type::operator __integral_type; 771 1.1 mrg using __base_type::operator=; 772 1.9 mrg 773 1.11 mrg #if __cplusplus >= 201703L 774 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2; 775 1.9 mrg #endif 776 1.1 mrg }; 777 1.1 mrg 778 1.1 mrg /// Explicit specialization for short. 779 1.1 mrg template<> 780 1.5 mrg struct atomic<short> : __atomic_base<short> 781 1.1 mrg { 782 1.1 mrg typedef short __integral_type; 783 1.5 mrg typedef __atomic_base<short> __base_type; 784 1.1 mrg 785 1.3 mrg atomic() noexcept = default; 786 1.3 mrg ~atomic() noexcept = default; 787 1.1 mrg atomic(const atomic&) = delete; 788 1.3 mrg atomic& operator=(const atomic&) = delete; 789 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 790 1.1 mrg 791 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 792 1.1 mrg 793 1.1 mrg using __base_type::operator __integral_type; 794 1.1 mrg using __base_type::operator=; 795 1.9 mrg 796 1.11 mrg #if __cplusplus >= 201703L 797 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; 798 1.9 mrg #endif 799 1.1 mrg }; 800 1.1 mrg 801 1.1 mrg /// Explicit specialization for unsigned short. 802 1.1 mrg template<> 803 1.5 mrg struct atomic<unsigned short> : __atomic_base<unsigned short> 804 1.1 mrg { 805 1.1 mrg typedef unsigned short __integral_type; 806 1.5 mrg typedef __atomic_base<unsigned short> __base_type; 807 1.1 mrg 808 1.3 mrg atomic() noexcept = default; 809 1.3 mrg ~atomic() noexcept = default; 810 1.1 mrg atomic(const atomic&) = delete; 811 1.3 mrg atomic& operator=(const atomic&) = delete; 812 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 813 1.1 mrg 814 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 815 1.1 mrg 816 1.1 mrg using __base_type::operator __integral_type; 817 1.1 mrg using __base_type::operator=; 818 1.9 mrg 819 1.11 mrg #if __cplusplus >= 201703L 820 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2; 821 1.9 mrg #endif 822 1.1 mrg }; 823 1.1 mrg 824 1.1 mrg /// Explicit specialization for int. 825 1.1 mrg template<> 826 1.5 mrg struct atomic<int> : __atomic_base<int> 827 1.1 mrg { 828 1.1 mrg typedef int __integral_type; 829 1.5 mrg typedef __atomic_base<int> __base_type; 830 1.1 mrg 831 1.3 mrg atomic() noexcept = default; 832 1.3 mrg ~atomic() noexcept = default; 833 1.1 mrg atomic(const atomic&) = delete; 834 1.3 mrg atomic& operator=(const atomic&) = delete; 835 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 836 1.1 mrg 837 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 838 1.1 mrg 839 1.1 mrg using __base_type::operator __integral_type; 840 1.1 mrg using __base_type::operator=; 841 1.9 mrg 842 1.11 mrg #if __cplusplus >= 201703L 843 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; 844 1.9 mrg #endif 845 1.1 mrg }; 846 1.1 mrg 847 1.1 mrg /// Explicit specialization for unsigned int. 848 1.1 mrg template<> 849 1.5 mrg struct atomic<unsigned int> : __atomic_base<unsigned int> 850 1.1 mrg { 851 1.1 mrg typedef unsigned int __integral_type; 852 1.5 mrg typedef __atomic_base<unsigned int> __base_type; 853 1.1 mrg 854 1.3 mrg atomic() noexcept = default; 855 1.3 mrg ~atomic() noexcept = default; 856 1.1 mrg atomic(const atomic&) = delete; 857 1.3 mrg atomic& operator=(const atomic&) = delete; 858 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 859 1.1 mrg 860 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 861 1.1 mrg 862 1.1 mrg using __base_type::operator __integral_type; 863 1.1 mrg using __base_type::operator=; 864 1.9 mrg 865 1.11 mrg #if __cplusplus >= 201703L 866 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2; 867 1.9 mrg #endif 868 1.1 mrg }; 869 1.1 mrg 870 1.1 mrg /// Explicit specialization for long. 871 1.1 mrg template<> 872 1.5 mrg struct atomic<long> : __atomic_base<long> 873 1.1 mrg { 874 1.1 mrg typedef long __integral_type; 875 1.5 mrg typedef __atomic_base<long> __base_type; 876 1.1 mrg 877 1.3 mrg atomic() noexcept = default; 878 1.3 mrg ~atomic() noexcept = default; 879 1.1 mrg atomic(const atomic&) = delete; 880 1.3 mrg atomic& operator=(const atomic&) = delete; 881 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 882 1.1 mrg 883 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 884 1.1 mrg 885 1.1 mrg using __base_type::operator __integral_type; 886 1.1 mrg using __base_type::operator=; 887 1.9 mrg 888 1.11 mrg #if __cplusplus >= 201703L 889 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; 890 1.9 mrg #endif 891 1.1 mrg }; 892 1.1 mrg 893 1.1 mrg /// Explicit specialization for unsigned long. 894 1.1 mrg template<> 895 1.5 mrg struct atomic<unsigned long> : __atomic_base<unsigned long> 896 1.1 mrg { 897 1.1 mrg typedef unsigned long __integral_type; 898 1.5 mrg typedef __atomic_base<unsigned long> __base_type; 899 1.1 mrg 900 1.3 mrg atomic() noexcept = default; 901 1.3 mrg ~atomic() noexcept = default; 902 1.1 mrg atomic(const atomic&) = delete; 903 1.3 mrg atomic& operator=(const atomic&) = delete; 904 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 905 1.1 mrg 906 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 907 1.1 mrg 908 1.1 mrg using __base_type::operator __integral_type; 909 1.1 mrg using __base_type::operator=; 910 1.9 mrg 911 1.11 mrg #if __cplusplus >= 201703L 912 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2; 913 1.9 mrg #endif 914 1.1 mrg }; 915 1.1 mrg 916 1.1 mrg /// Explicit specialization for long long. 917 1.1 mrg template<> 918 1.5 mrg struct atomic<long long> : __atomic_base<long long> 919 1.1 mrg { 920 1.1 mrg typedef long long __integral_type; 921 1.5 mrg typedef __atomic_base<long long> __base_type; 922 1.1 mrg 923 1.3 mrg atomic() noexcept = default; 924 1.3 mrg ~atomic() noexcept = default; 925 1.1 mrg atomic(const atomic&) = delete; 926 1.3 mrg atomic& operator=(const atomic&) = delete; 927 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 928 1.1 mrg 929 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 930 1.1 mrg 931 1.1 mrg using __base_type::operator __integral_type; 932 1.1 mrg using __base_type::operator=; 933 1.9 mrg 934 1.11 mrg #if __cplusplus >= 201703L 935 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; 936 1.9 mrg #endif 937 1.1 mrg }; 938 1.1 mrg 939 1.1 mrg /// Explicit specialization for unsigned long long. 940 1.1 mrg template<> 941 1.5 mrg struct atomic<unsigned long long> : __atomic_base<unsigned long long> 942 1.1 mrg { 943 1.1 mrg typedef unsigned long long __integral_type; 944 1.5 mrg typedef __atomic_base<unsigned long long> __base_type; 945 1.1 mrg 946 1.3 mrg atomic() noexcept = default; 947 1.3 mrg ~atomic() noexcept = default; 948 1.1 mrg atomic(const atomic&) = delete; 949 1.3 mrg atomic& operator=(const atomic&) = delete; 950 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 951 1.1 mrg 952 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 953 1.1 mrg 954 1.1 mrg using __base_type::operator __integral_type; 955 1.1 mrg using __base_type::operator=; 956 1.9 mrg 957 1.11 mrg #if __cplusplus >= 201703L 958 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2; 959 1.9 mrg #endif 960 1.1 mrg }; 961 1.1 mrg 962 1.1 mrg /// Explicit specialization for wchar_t. 963 1.1 mrg template<> 964 1.5 mrg struct atomic<wchar_t> : __atomic_base<wchar_t> 965 1.1 mrg { 966 1.1 mrg typedef wchar_t __integral_type; 967 1.5 mrg typedef __atomic_base<wchar_t> __base_type; 968 1.1 mrg 969 1.3 mrg atomic() noexcept = default; 970 1.3 mrg ~atomic() noexcept = default; 971 1.1 mrg atomic(const atomic&) = delete; 972 1.3 mrg atomic& operator=(const atomic&) = delete; 973 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 974 1.1 mrg 975 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 976 1.1 mrg 977 1.1 mrg using __base_type::operator __integral_type; 978 1.1 mrg using __base_type::operator=; 979 1.9 mrg 980 1.11 mrg #if __cplusplus >= 201703L 981 1.13 mrg static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2; 982 1.11 mrg #endif 983 1.11 mrg }; 984 1.11 mrg 985 1.11 mrg #ifdef _GLIBCXX_USE_CHAR8_T 986 1.11 mrg /// Explicit specialization for char8_t. 987 1.11 mrg template<> 988 1.11 mrg struct atomic<char8_t> : __atomic_base<char8_t> 989 1.11 mrg { 990 1.11 mrg typedef char8_t __integral_type; 991 1.11 mrg typedef __atomic_base<char8_t> __base_type; 992 1.11 mrg 993 1.11 mrg atomic() noexcept = default; 994 1.11 mrg ~atomic() noexcept = default; 995 1.11 mrg atomic(const atomic&) = delete; 996 1.11 mrg atomic& operator=(const atomic&) = delete; 997 1.11 mrg atomic& operator=(const atomic&) volatile = delete; 998 1.11 mrg 999 1.11 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 1000 1.11 mrg 1001 1.11 mrg using __base_type::operator __integral_type; 1002 1.11 mrg using __base_type::operator=; 1003 1.11 mrg 1004 1.9 mrg #if __cplusplus > 201402L 1005 1.13 mrg static constexpr bool is_always_lock_free 1006 1.13 mrg = ATOMIC_CHAR8_T_LOCK_FREE == 2; 1007 1.9 mrg #endif 1008 1.1 mrg }; 1009 1.11 mrg #endif 1010 1.1 mrg 1011 1.1 mrg /// Explicit specialization for char16_t. 1012 1.1 mrg template<> 1013 1.5 mrg struct atomic<char16_t> : __atomic_base<char16_t> 1014 1.1 mrg { 1015 1.1 mrg typedef char16_t __integral_type; 1016 1.5 mrg typedef __atomic_base<char16_t> __base_type; 1017 1.1 mrg 1018 1.3 mrg atomic() noexcept = default; 1019 1.3 mrg ~atomic() noexcept = default; 1020 1.1 mrg atomic(const atomic&) = delete; 1021 1.3 mrg atomic& operator=(const atomic&) = delete; 1022 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 1023 1.1 mrg 1024 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 1025 1.1 mrg 1026 1.1 mrg using __base_type::operator __integral_type; 1027 1.1 mrg using __base_type::operator=; 1028 1.9 mrg 1029 1.11 mrg #if __cplusplus >= 201703L 1030 1.13 mrg static constexpr bool is_always_lock_free 1031 1.13 mrg = ATOMIC_CHAR16_T_LOCK_FREE == 2; 1032 1.9 mrg #endif 1033 1.1 mrg }; 1034 1.1 mrg 1035 1.1 mrg /// Explicit specialization for char32_t. 1036 1.1 mrg template<> 1037 1.5 mrg struct atomic<char32_t> : __atomic_base<char32_t> 1038 1.1 mrg { 1039 1.1 mrg typedef char32_t __integral_type; 1040 1.5 mrg typedef __atomic_base<char32_t> __base_type; 1041 1.1 mrg 1042 1.3 mrg atomic() noexcept = default; 1043 1.3 mrg ~atomic() noexcept = default; 1044 1.1 mrg atomic(const atomic&) = delete; 1045 1.3 mrg atomic& operator=(const atomic&) = delete; 1046 1.1 mrg atomic& operator=(const atomic&) volatile = delete; 1047 1.1 mrg 1048 1.3 mrg constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 1049 1.1 mrg 1050 1.1 mrg using __base_type::operator __integral_type; 1051 1.1 mrg using __base_type::operator=; 1052 1.9 mrg 1053 1.11 mrg #if __cplusplus >= 201703L 1054 1.13 mrg static constexpr bool is_always_lock_free 1055 1.13 mrg = ATOMIC_CHAR32_T_LOCK_FREE == 2; 1056 1.9 mrg #endif 1057 1.1 mrg }; 1058 1.1 mrg 1059 1.1 mrg 1060 1.5 mrg /// atomic_bool 1061 1.5 mrg typedef atomic<bool> atomic_bool; 1062 1.5 mrg 1063 1.5 mrg /// atomic_char 1064 1.5 mrg typedef atomic<char> atomic_char; 1065 1.5 mrg 1066 1.5 mrg /// atomic_schar 1067 1.5 mrg typedef atomic<signed char> atomic_schar; 1068 1.5 mrg 1069 1.5 mrg /// atomic_uchar 1070 1.5 mrg typedef atomic<unsigned char> atomic_uchar; 1071 1.5 mrg 1072 1.5 mrg /// atomic_short 1073 1.5 mrg typedef atomic<short> atomic_short; 1074 1.5 mrg 1075 1.5 mrg /// atomic_ushort 1076 1.5 mrg typedef atomic<unsigned short> atomic_ushort; 1077 1.5 mrg 1078 1.5 mrg /// atomic_int 1079 1.5 mrg typedef atomic<int> atomic_int; 1080 1.5 mrg 1081 1.5 mrg /// atomic_uint 1082 1.5 mrg typedef atomic<unsigned int> atomic_uint; 1083 1.5 mrg 1084 1.5 mrg /// atomic_long 1085 1.5 mrg typedef atomic<long> atomic_long; 1086 1.5 mrg 1087 1.5 mrg /// atomic_ulong 1088 1.5 mrg typedef atomic<unsigned long> atomic_ulong; 1089 1.5 mrg 1090 1.5 mrg /// atomic_llong 1091 1.5 mrg typedef atomic<long long> atomic_llong; 1092 1.5 mrg 1093 1.5 mrg /// atomic_ullong 1094 1.5 mrg typedef atomic<unsigned long long> atomic_ullong; 1095 1.5 mrg 1096 1.5 mrg /// atomic_wchar_t 1097 1.5 mrg typedef atomic<wchar_t> atomic_wchar_t; 1098 1.5 mrg 1099 1.11 mrg #ifdef _GLIBCXX_USE_CHAR8_T 1100 1.11 mrg /// atomic_char8_t 1101 1.11 mrg typedef atomic<char8_t> atomic_char8_t; 1102 1.11 mrg #endif 1103 1.11 mrg 1104 1.5 mrg /// atomic_char16_t 1105 1.5 mrg typedef atomic<char16_t> atomic_char16_t; 1106 1.5 mrg 1107 1.5 mrg /// atomic_char32_t 1108 1.5 mrg typedef atomic<char32_t> atomic_char32_t; 1109 1.5 mrg 1110 1.10 mrg #ifdef _GLIBCXX_USE_C99_STDINT_TR1 1111 1.9 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1112 1.9 mrg // 2441. Exact-width atomic typedefs should be provided 1113 1.9 mrg 1114 1.9 mrg /// atomic_int8_t 1115 1.9 mrg typedef atomic<int8_t> atomic_int8_t; 1116 1.9 mrg 1117 1.9 mrg /// atomic_uint8_t 1118 1.9 mrg typedef atomic<uint8_t> atomic_uint8_t; 1119 1.9 mrg 1120 1.9 mrg /// atomic_int16_t 1121 1.9 mrg typedef atomic<int16_t> atomic_int16_t; 1122 1.9 mrg 1123 1.9 mrg /// atomic_uint16_t 1124 1.9 mrg typedef atomic<uint16_t> atomic_uint16_t; 1125 1.9 mrg 1126 1.9 mrg /// atomic_int32_t 1127 1.9 mrg typedef atomic<int32_t> atomic_int32_t; 1128 1.9 mrg 1129 1.9 mrg /// atomic_uint32_t 1130 1.9 mrg typedef atomic<uint32_t> atomic_uint32_t; 1131 1.9 mrg 1132 1.9 mrg /// atomic_int64_t 1133 1.9 mrg typedef atomic<int64_t> atomic_int64_t; 1134 1.9 mrg 1135 1.9 mrg /// atomic_uint64_t 1136 1.9 mrg typedef atomic<uint64_t> atomic_uint64_t; 1137 1.9 mrg 1138 1.9 mrg 1139 1.5 mrg /// atomic_int_least8_t 1140 1.5 mrg typedef atomic<int_least8_t> atomic_int_least8_t; 1141 1.5 mrg 1142 1.5 mrg /// atomic_uint_least8_t 1143 1.5 mrg typedef atomic<uint_least8_t> atomic_uint_least8_t; 1144 1.5 mrg 1145 1.5 mrg /// atomic_int_least16_t 1146 1.5 mrg typedef atomic<int_least16_t> atomic_int_least16_t; 1147 1.5 mrg 1148 1.5 mrg /// atomic_uint_least16_t 1149 1.5 mrg typedef atomic<uint_least16_t> atomic_uint_least16_t; 1150 1.5 mrg 1151 1.5 mrg /// atomic_int_least32_t 1152 1.5 mrg typedef atomic<int_least32_t> atomic_int_least32_t; 1153 1.5 mrg 1154 1.5 mrg /// atomic_uint_least32_t 1155 1.5 mrg typedef atomic<uint_least32_t> atomic_uint_least32_t; 1156 1.5 mrg 1157 1.5 mrg /// atomic_int_least64_t 1158 1.5 mrg typedef atomic<int_least64_t> atomic_int_least64_t; 1159 1.5 mrg 1160 1.5 mrg /// atomic_uint_least64_t 1161 1.5 mrg typedef atomic<uint_least64_t> atomic_uint_least64_t; 1162 1.5 mrg 1163 1.5 mrg 1164 1.5 mrg /// atomic_int_fast8_t 1165 1.5 mrg typedef atomic<int_fast8_t> atomic_int_fast8_t; 1166 1.5 mrg 1167 1.5 mrg /// atomic_uint_fast8_t 1168 1.5 mrg typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1169 1.5 mrg 1170 1.5 mrg /// atomic_int_fast16_t 1171 1.5 mrg typedef atomic<int_fast16_t> atomic_int_fast16_t; 1172 1.5 mrg 1173 1.5 mrg /// atomic_uint_fast16_t 1174 1.5 mrg typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1175 1.5 mrg 1176 1.5 mrg /// atomic_int_fast32_t 1177 1.5 mrg typedef atomic<int_fast32_t> atomic_int_fast32_t; 1178 1.5 mrg 1179 1.5 mrg /// atomic_uint_fast32_t 1180 1.5 mrg typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1181 1.5 mrg 1182 1.5 mrg /// atomic_int_fast64_t 1183 1.5 mrg typedef atomic<int_fast64_t> atomic_int_fast64_t; 1184 1.5 mrg 1185 1.5 mrg /// atomic_uint_fast64_t 1186 1.5 mrg typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1187 1.10 mrg #endif 1188 1.5 mrg 1189 1.5 mrg 1190 1.5 mrg /// atomic_intptr_t 1191 1.5 mrg typedef atomic<intptr_t> atomic_intptr_t; 1192 1.5 mrg 1193 1.5 mrg /// atomic_uintptr_t 1194 1.5 mrg typedef atomic<uintptr_t> atomic_uintptr_t; 1195 1.5 mrg 1196 1.5 mrg /// atomic_size_t 1197 1.5 mrg typedef atomic<size_t> atomic_size_t; 1198 1.5 mrg 1199 1.10 mrg /// atomic_ptrdiff_t 1200 1.10 mrg typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1201 1.10 mrg 1202 1.10 mrg #ifdef _GLIBCXX_USE_C99_STDINT_TR1 1203 1.5 mrg /// atomic_intmax_t 1204 1.5 mrg typedef atomic<intmax_t> atomic_intmax_t; 1205 1.5 mrg 1206 1.5 mrg /// atomic_uintmax_t 1207 1.5 mrg typedef atomic<uintmax_t> atomic_uintmax_t; 1208 1.10 mrg #endif 1209 1.5 mrg 1210 1.3 mrg // Function definitions, atomic_flag operations. 1211 1.3 mrg inline bool 1212 1.3 mrg atomic_flag_test_and_set_explicit(atomic_flag* __a, 1213 1.3 mrg memory_order __m) noexcept 1214 1.3 mrg { return __a->test_and_set(__m); } 1215 1.1 mrg 1216 1.1 mrg inline bool 1217 1.3 mrg atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 1218 1.3 mrg memory_order __m) noexcept 1219 1.1 mrg { return __a->test_and_set(__m); } 1220 1.1 mrg 1221 1.13 mrg #if __cpp_lib_atomic_flag_test 1222 1.13 mrg inline bool 1223 1.13 mrg atomic_flag_test(const atomic_flag* __a) noexcept 1224 1.13 mrg { return __a->test(); } 1225 1.13 mrg 1226 1.13 mrg inline bool 1227 1.13 mrg atomic_flag_test(const volatile atomic_flag* __a) noexcept 1228 1.13 mrg { return __a->test(); } 1229 1.13 mrg 1230 1.13 mrg inline bool 1231 1.13 mrg atomic_flag_test_explicit(const atomic_flag* __a, 1232 1.13 mrg memory_order __m) noexcept 1233 1.13 mrg { return __a->test(__m); } 1234 1.13 mrg 1235 1.13 mrg inline bool 1236 1.13 mrg atomic_flag_test_explicit(const volatile atomic_flag* __a, 1237 1.13 mrg memory_order __m) noexcept 1238 1.13 mrg { return __a->test(__m); } 1239 1.13 mrg #endif 1240 1.13 mrg 1241 1.1 mrg inline void 1242 1.3 mrg atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 1243 1.3 mrg { __a->clear(__m); } 1244 1.1 mrg 1245 1.3 mrg inline void 1246 1.3 mrg atomic_flag_clear_explicit(volatile atomic_flag* __a, 1247 1.3 mrg memory_order __m) noexcept 1248 1.3 mrg { __a->clear(__m); } 1249 1.3 mrg 1250 1.3 mrg inline bool 1251 1.3 mrg atomic_flag_test_and_set(atomic_flag* __a) noexcept 1252 1.3 mrg { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 1253 1.1 mrg 1254 1.1 mrg inline bool 1255 1.3 mrg atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 1256 1.3 mrg { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 1257 1.1 mrg 1258 1.1 mrg inline void 1259 1.3 mrg atomic_flag_clear(atomic_flag* __a) noexcept 1260 1.3 mrg { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 1261 1.1 mrg 1262 1.1 mrg inline void 1263 1.3 mrg atomic_flag_clear(volatile atomic_flag* __a) noexcept 1264 1.3 mrg { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 1265 1.1 mrg 1266 1.13 mrg #if __cpp_lib_atomic_wait 1267 1.13 mrg inline void 1268 1.13 mrg atomic_flag_wait(atomic_flag* __a, bool __old) noexcept 1269 1.13 mrg { __a->wait(__old); } 1270 1.13 mrg 1271 1.13 mrg inline void 1272 1.13 mrg atomic_flag_wait_explicit(atomic_flag* __a, bool __old, 1273 1.13 mrg memory_order __m) noexcept 1274 1.13 mrg { __a->wait(__old, __m); } 1275 1.13 mrg 1276 1.13 mrg inline void 1277 1.13 mrg atomic_flag_notify_one(atomic_flag* __a) noexcept 1278 1.13 mrg { __a->notify_one(); } 1279 1.13 mrg 1280 1.13 mrg inline void 1281 1.13 mrg atomic_flag_notify_all(atomic_flag* __a) noexcept 1282 1.13 mrg { __a->notify_all(); } 1283 1.13 mrg #endif // __cpp_lib_atomic_wait 1284 1.13 mrg 1285 1.13 mrg /// @cond undocumented 1286 1.12 mrg // _GLIBCXX_RESOLVE_LIB_DEFECTS 1287 1.12 mrg // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr 1288 1.11 mrg template<typename _Tp> 1289 1.12 mrg using __atomic_val_t = __type_identity_t<_Tp>; 1290 1.11 mrg template<typename _Tp> 1291 1.11 mrg using __atomic_diff_t = typename atomic<_Tp>::difference_type; 1292 1.13 mrg /// @endcond 1293 1.11 mrg 1294 1.11 mrg // [atomics.nonmembers] Non-member functions. 1295 1.3 mrg // Function templates generally applicable to atomic types. 1296 1.3 mrg template<typename _ITp> 1297 1.3 mrg inline bool 1298 1.3 mrg atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 1299 1.3 mrg { return __a->is_lock_free(); } 1300 1.1 mrg 1301 1.3 mrg template<typename _ITp> 1302 1.3 mrg inline bool 1303 1.3 mrg atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 1304 1.3 mrg { return __a->is_lock_free(); } 1305 1.1 mrg 1306 1.3 mrg template<typename _ITp> 1307 1.3 mrg inline void 1308 1.11 mrg atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept 1309 1.5 mrg { __a->store(__i, memory_order_relaxed); } 1310 1.1 mrg 1311 1.3 mrg template<typename _ITp> 1312 1.3 mrg inline void 1313 1.11 mrg atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept 1314 1.5 mrg { __a->store(__i, memory_order_relaxed); } 1315 1.1 mrg 1316 1.3 mrg template<typename _ITp> 1317 1.3 mrg inline void 1318 1.11 mrg atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i, 1319 1.3 mrg memory_order __m) noexcept 1320 1.3 mrg { __a->store(__i, __m); } 1321 1.1 mrg 1322 1.3 mrg template<typename _ITp> 1323 1.3 mrg inline void 1324 1.11 mrg atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i, 1325 1.3 mrg memory_order __m) noexcept 1326 1.3 mrg { __a->store(__i, __m); } 1327 1.1 mrg 1328 1.3 mrg template<typename _ITp> 1329 1.3 mrg inline _ITp 1330 1.3 mrg atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 1331 1.3 mrg { return __a->load(__m); } 1332 1.1 mrg 1333 1.3 mrg template<typename _ITp> 1334 1.3 mrg inline _ITp 1335 1.3 mrg atomic_load_explicit(const volatile atomic<_ITp>* __a, 1336 1.3 mrg memory_order __m) noexcept 1337 1.3 mrg { return __a->load(__m); } 1338 1.1 mrg 1339 1.3 mrg template<typename _ITp> 1340 1.3 mrg inline _ITp 1341 1.11 mrg atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i, 1342 1.3 mrg memory_order __m) noexcept 1343 1.3 mrg { return __a->exchange(__i, __m); } 1344 1.1 mrg 1345 1.3 mrg template<typename _ITp> 1346 1.3 mrg inline _ITp 1347 1.11 mrg atomic_exchange_explicit(volatile atomic<_ITp>* __a, 1348 1.11 mrg __atomic_val_t<_ITp> __i, 1349 1.3 mrg memory_order __m) noexcept 1350 1.3 mrg { return __a->exchange(__i, __m); } 1351 1.1 mrg 1352 1.3 mrg template<typename _ITp> 1353 1.3 mrg inline bool 1354 1.3 mrg atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 1355 1.11 mrg __atomic_val_t<_ITp>* __i1, 1356 1.11 mrg __atomic_val_t<_ITp> __i2, 1357 1.3 mrg memory_order __m1, 1358 1.3 mrg memory_order __m2) noexcept 1359 1.3 mrg { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 1360 1.1 mrg 1361 1.3 mrg template<typename _ITp> 1362 1.3 mrg inline bool 1363 1.3 mrg atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 1364 1.11 mrg __atomic_val_t<_ITp>* __i1, 1365 1.11 mrg __atomic_val_t<_ITp> __i2, 1366 1.3 mrg memory_order __m1, 1367 1.3 mrg memory_order __m2) noexcept 1368 1.3 mrg { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 1369 1.1 mrg 1370 1.3 mrg template<typename _ITp> 1371 1.3 mrg inline bool 1372 1.3 mrg atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 1373 1.11 mrg __atomic_val_t<_ITp>* __i1, 1374 1.11 mrg __atomic_val_t<_ITp> __i2, 1375 1.3 mrg memory_order __m1, 1376 1.3 mrg memory_order __m2) noexcept 1377 1.3 mrg { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 1378 1.1 mrg 1379 1.3 mrg template<typename _ITp> 1380 1.3 mrg inline bool 1381 1.3 mrg atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 1382 1.11 mrg __atomic_val_t<_ITp>* __i1, 1383 1.11 mrg __atomic_val_t<_ITp> __i2, 1384 1.3 mrg memory_order __m1, 1385 1.3 mrg memory_order __m2) noexcept 1386 1.3 mrg { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 1387 1.1 mrg 1388 1.1 mrg 1389 1.3 mrg template<typename _ITp> 1390 1.3 mrg inline void 1391 1.11 mrg atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept 1392 1.3 mrg { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 1393 1.1 mrg 1394 1.3 mrg template<typename _ITp> 1395 1.3 mrg inline void 1396 1.11 mrg atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept 1397 1.3 mrg { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 1398 1.1 mrg 1399 1.3 mrg template<typename _ITp> 1400 1.3 mrg inline _ITp 1401 1.3 mrg atomic_load(const atomic<_ITp>* __a) noexcept 1402 1.3 mrg { return atomic_load_explicit(__a, memory_order_seq_cst); } 1403 1.1 mrg 1404 1.1 mrg template<typename _ITp> 1405 1.3 mrg inline _ITp 1406 1.3 mrg atomic_load(const volatile atomic<_ITp>* __a) noexcept 1407 1.3 mrg { return atomic_load_explicit(__a, memory_order_seq_cst); } 1408 1.1 mrg 1409 1.1 mrg template<typename _ITp> 1410 1.1 mrg inline _ITp 1411 1.11 mrg atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept 1412 1.3 mrg { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 1413 1.1 mrg 1414 1.1 mrg template<typename _ITp> 1415 1.1 mrg inline _ITp 1416 1.11 mrg atomic_exchange(volatile atomic<_ITp>* __a, 1417 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1418 1.3 mrg { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 1419 1.3 mrg 1420 1.3 mrg template<typename _ITp> 1421 1.3 mrg inline bool 1422 1.3 mrg atomic_compare_exchange_weak(atomic<_ITp>* __a, 1423 1.11 mrg __atomic_val_t<_ITp>* __i1, 1424 1.11 mrg __atomic_val_t<_ITp> __i2) noexcept 1425 1.3 mrg { 1426 1.3 mrg return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 1427 1.3 mrg memory_order_seq_cst, 1428 1.3 mrg memory_order_seq_cst); 1429 1.3 mrg } 1430 1.3 mrg 1431 1.3 mrg template<typename _ITp> 1432 1.3 mrg inline bool 1433 1.3 mrg atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 1434 1.11 mrg __atomic_val_t<_ITp>* __i1, 1435 1.11 mrg __atomic_val_t<_ITp> __i2) noexcept 1436 1.3 mrg { 1437 1.3 mrg return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 1438 1.3 mrg memory_order_seq_cst, 1439 1.3 mrg memory_order_seq_cst); 1440 1.3 mrg } 1441 1.1 mrg 1442 1.1 mrg template<typename _ITp> 1443 1.1 mrg inline bool 1444 1.3 mrg atomic_compare_exchange_strong(atomic<_ITp>* __a, 1445 1.11 mrg __atomic_val_t<_ITp>* __i1, 1446 1.11 mrg __atomic_val_t<_ITp> __i2) noexcept 1447 1.3 mrg { 1448 1.3 mrg return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 1449 1.3 mrg memory_order_seq_cst, 1450 1.3 mrg memory_order_seq_cst); 1451 1.3 mrg } 1452 1.1 mrg 1453 1.1 mrg template<typename _ITp> 1454 1.1 mrg inline bool 1455 1.3 mrg atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 1456 1.11 mrg __atomic_val_t<_ITp>* __i1, 1457 1.11 mrg __atomic_val_t<_ITp> __i2) noexcept 1458 1.3 mrg { 1459 1.3 mrg return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 1460 1.3 mrg memory_order_seq_cst, 1461 1.3 mrg memory_order_seq_cst); 1462 1.3 mrg } 1463 1.1 mrg 1464 1.13 mrg 1465 1.13 mrg #if __cpp_lib_atomic_wait 1466 1.13 mrg template<typename _Tp> 1467 1.13 mrg inline void 1468 1.13 mrg atomic_wait(const atomic<_Tp>* __a, 1469 1.13 mrg typename std::atomic<_Tp>::value_type __old) noexcept 1470 1.13 mrg { __a->wait(__old); } 1471 1.13 mrg 1472 1.13 mrg template<typename _Tp> 1473 1.13 mrg inline void 1474 1.13 mrg atomic_wait_explicit(const atomic<_Tp>* __a, 1475 1.13 mrg typename std::atomic<_Tp>::value_type __old, 1476 1.13 mrg std::memory_order __m) noexcept 1477 1.13 mrg { __a->wait(__old, __m); } 1478 1.13 mrg 1479 1.13 mrg template<typename _Tp> 1480 1.13 mrg inline void 1481 1.13 mrg atomic_notify_one(atomic<_Tp>* __a) noexcept 1482 1.13 mrg { __a->notify_one(); } 1483 1.13 mrg 1484 1.13 mrg template<typename _Tp> 1485 1.13 mrg inline void 1486 1.13 mrg atomic_notify_all(atomic<_Tp>* __a) noexcept 1487 1.13 mrg { __a->notify_all(); } 1488 1.13 mrg #endif // __cpp_lib_atomic_wait 1489 1.13 mrg 1490 1.11 mrg // Function templates for atomic_integral and atomic_pointer operations only. 1491 1.11 mrg // Some operations (and, or, xor) are only available for atomic integrals, 1492 1.11 mrg // which is implemented by taking a parameter of type __atomic_base<_ITp>*. 1493 1.11 mrg 1494 1.1 mrg template<typename _ITp> 1495 1.1 mrg inline _ITp 1496 1.11 mrg atomic_fetch_add_explicit(atomic<_ITp>* __a, 1497 1.11 mrg __atomic_diff_t<_ITp> __i, 1498 1.3 mrg memory_order __m) noexcept 1499 1.3 mrg { return __a->fetch_add(__i, __m); } 1500 1.3 mrg 1501 1.3 mrg template<typename _ITp> 1502 1.3 mrg inline _ITp 1503 1.11 mrg atomic_fetch_add_explicit(volatile atomic<_ITp>* __a, 1504 1.11 mrg __atomic_diff_t<_ITp> __i, 1505 1.3 mrg memory_order __m) noexcept 1506 1.1 mrg { return __a->fetch_add(__i, __m); } 1507 1.1 mrg 1508 1.1 mrg template<typename _ITp> 1509 1.1 mrg inline _ITp 1510 1.11 mrg atomic_fetch_sub_explicit(atomic<_ITp>* __a, 1511 1.11 mrg __atomic_diff_t<_ITp> __i, 1512 1.3 mrg memory_order __m) noexcept 1513 1.3 mrg { return __a->fetch_sub(__i, __m); } 1514 1.3 mrg 1515 1.3 mrg template<typename _ITp> 1516 1.3 mrg inline _ITp 1517 1.11 mrg atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a, 1518 1.11 mrg __atomic_diff_t<_ITp> __i, 1519 1.3 mrg memory_order __m) noexcept 1520 1.1 mrg { return __a->fetch_sub(__i, __m); } 1521 1.1 mrg 1522 1.1 mrg template<typename _ITp> 1523 1.1 mrg inline _ITp 1524 1.11 mrg atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, 1525 1.11 mrg __atomic_val_t<_ITp> __i, 1526 1.3 mrg memory_order __m) noexcept 1527 1.3 mrg { return __a->fetch_and(__i, __m); } 1528 1.3 mrg 1529 1.3 mrg template<typename _ITp> 1530 1.3 mrg inline _ITp 1531 1.11 mrg atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, 1532 1.11 mrg __atomic_val_t<_ITp> __i, 1533 1.3 mrg memory_order __m) noexcept 1534 1.1 mrg { return __a->fetch_and(__i, __m); } 1535 1.1 mrg 1536 1.1 mrg template<typename _ITp> 1537 1.1 mrg inline _ITp 1538 1.11 mrg atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, 1539 1.11 mrg __atomic_val_t<_ITp> __i, 1540 1.3 mrg memory_order __m) noexcept 1541 1.3 mrg { return __a->fetch_or(__i, __m); } 1542 1.3 mrg 1543 1.3 mrg template<typename _ITp> 1544 1.3 mrg inline _ITp 1545 1.11 mrg atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, 1546 1.11 mrg __atomic_val_t<_ITp> __i, 1547 1.3 mrg memory_order __m) noexcept 1548 1.1 mrg { return __a->fetch_or(__i, __m); } 1549 1.1 mrg 1550 1.1 mrg template<typename _ITp> 1551 1.1 mrg inline _ITp 1552 1.11 mrg atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, 1553 1.11 mrg __atomic_val_t<_ITp> __i, 1554 1.3 mrg memory_order __m) noexcept 1555 1.1 mrg { return __a->fetch_xor(__i, __m); } 1556 1.1 mrg 1557 1.1 mrg template<typename _ITp> 1558 1.3 mrg inline _ITp 1559 1.11 mrg atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, 1560 1.11 mrg __atomic_val_t<_ITp> __i, 1561 1.3 mrg memory_order __m) noexcept 1562 1.3 mrg { return __a->fetch_xor(__i, __m); } 1563 1.1 mrg 1564 1.1 mrg template<typename _ITp> 1565 1.3 mrg inline _ITp 1566 1.11 mrg atomic_fetch_add(atomic<_ITp>* __a, 1567 1.11 mrg __atomic_diff_t<_ITp> __i) noexcept 1568 1.3 mrg { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1569 1.1 mrg 1570 1.1 mrg template<typename _ITp> 1571 1.1 mrg inline _ITp 1572 1.11 mrg atomic_fetch_add(volatile atomic<_ITp>* __a, 1573 1.11 mrg __atomic_diff_t<_ITp> __i) noexcept 1574 1.3 mrg { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1575 1.1 mrg 1576 1.1 mrg template<typename _ITp> 1577 1.1 mrg inline _ITp 1578 1.11 mrg atomic_fetch_sub(atomic<_ITp>* __a, 1579 1.11 mrg __atomic_diff_t<_ITp> __i) noexcept 1580 1.3 mrg { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1581 1.1 mrg 1582 1.1 mrg template<typename _ITp> 1583 1.3 mrg inline _ITp 1584 1.11 mrg atomic_fetch_sub(volatile atomic<_ITp>* __a, 1585 1.11 mrg __atomic_diff_t<_ITp> __i) noexcept 1586 1.3 mrg { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1587 1.1 mrg 1588 1.1 mrg template<typename _ITp> 1589 1.3 mrg inline _ITp 1590 1.11 mrg atomic_fetch_and(__atomic_base<_ITp>* __a, 1591 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1592 1.3 mrg { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1593 1.1 mrg 1594 1.1 mrg template<typename _ITp> 1595 1.1 mrg inline _ITp 1596 1.11 mrg atomic_fetch_and(volatile __atomic_base<_ITp>* __a, 1597 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1598 1.3 mrg { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1599 1.1 mrg 1600 1.1 mrg template<typename _ITp> 1601 1.1 mrg inline _ITp 1602 1.11 mrg atomic_fetch_or(__atomic_base<_ITp>* __a, 1603 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1604 1.3 mrg { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1605 1.1 mrg 1606 1.1 mrg template<typename _ITp> 1607 1.1 mrg inline _ITp 1608 1.11 mrg atomic_fetch_or(volatile __atomic_base<_ITp>* __a, 1609 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1610 1.3 mrg { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1611 1.1 mrg 1612 1.1 mrg template<typename _ITp> 1613 1.1 mrg inline _ITp 1614 1.11 mrg atomic_fetch_xor(__atomic_base<_ITp>* __a, 1615 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1616 1.3 mrg { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1617 1.1 mrg 1618 1.1 mrg template<typename _ITp> 1619 1.1 mrg inline _ITp 1620 1.11 mrg atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, 1621 1.11 mrg __atomic_val_t<_ITp> __i) noexcept 1622 1.1 mrg { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1623 1.1 mrg 1624 1.12 mrg #if __cplusplus > 201703L 1625 1.12 mrg #define __cpp_lib_atomic_float 201711L 1626 1.12 mrg template<> 1627 1.12 mrg struct atomic<float> : __atomic_float<float> 1628 1.12 mrg { 1629 1.12 mrg atomic() noexcept = default; 1630 1.12 mrg 1631 1.12 mrg constexpr 1632 1.12 mrg atomic(float __fp) noexcept : __atomic_float<float>(__fp) 1633 1.12 mrg { } 1634 1.12 mrg 1635 1.12 mrg atomic& operator=(const atomic&) volatile = delete; 1636 1.12 mrg atomic& operator=(const atomic&) = delete; 1637 1.12 mrg 1638 1.12 mrg using __atomic_float<float>::operator=; 1639 1.12 mrg }; 1640 1.12 mrg 1641 1.12 mrg template<> 1642 1.12 mrg struct atomic<double> : __atomic_float<double> 1643 1.12 mrg { 1644 1.12 mrg atomic() noexcept = default; 1645 1.12 mrg 1646 1.12 mrg constexpr 1647 1.12 mrg atomic(double __fp) noexcept : __atomic_float<double>(__fp) 1648 1.12 mrg { } 1649 1.12 mrg 1650 1.12 mrg atomic& operator=(const atomic&) volatile = delete; 1651 1.12 mrg atomic& operator=(const atomic&) = delete; 1652 1.12 mrg 1653 1.12 mrg using __atomic_float<double>::operator=; 1654 1.12 mrg }; 1655 1.12 mrg 1656 1.12 mrg template<> 1657 1.12 mrg struct atomic<long double> : __atomic_float<long double> 1658 1.12 mrg { 1659 1.12 mrg atomic() noexcept = default; 1660 1.12 mrg 1661 1.12 mrg constexpr 1662 1.12 mrg atomic(long double __fp) noexcept : __atomic_float<long double>(__fp) 1663 1.12 mrg { } 1664 1.12 mrg 1665 1.12 mrg atomic& operator=(const atomic&) volatile = delete; 1666 1.12 mrg atomic& operator=(const atomic&) = delete; 1667 1.12 mrg 1668 1.12 mrg using __atomic_float<long double>::operator=; 1669 1.12 mrg }; 1670 1.12 mrg 1671 1.12 mrg #define __cpp_lib_atomic_ref 201806L 1672 1.12 mrg 1673 1.12 mrg /// Class template to provide atomic operations on a non-atomic variable. 1674 1.12 mrg template<typename _Tp> 1675 1.12 mrg struct atomic_ref : __atomic_ref<_Tp> 1676 1.12 mrg { 1677 1.12 mrg explicit 1678 1.12 mrg atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t) 1679 1.12 mrg { } 1680 1.12 mrg 1681 1.12 mrg atomic_ref& operator=(const atomic_ref&) = delete; 1682 1.12 mrg 1683 1.12 mrg atomic_ref(const atomic_ref&) = default; 1684 1.12 mrg 1685 1.12 mrg using __atomic_ref<_Tp>::operator=; 1686 1.12 mrg }; 1687 1.12 mrg 1688 1.12 mrg #endif // C++2a 1689 1.12 mrg 1690 1.12 mrg /// @} group atomics 1691 1.1 mrg 1692 1.3 mrg _GLIBCXX_END_NAMESPACE_VERSION 1693 1.3 mrg } // namespace 1694 1.1 mrg 1695 1.5 mrg #endif // C++11 1696 1.5 mrg 1697 1.5 mrg #endif // _GLIBCXX_ATOMIC 1698