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