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