1 // -*- C++ -*- header. 2 3 // Copyright (C) 2008-2014 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 #endif 40 41 #include <bits/atomic_base.h> 42 43 namespace std _GLIBCXX_VISIBILITY(default) 44 { 45 _GLIBCXX_BEGIN_NAMESPACE_VERSION 46 47 /** 48 * @addtogroup atomics 49 * @{ 50 */ 51 52 /// atomic_bool 53 // NB: No operators or fetch-operations for this type. 54 struct atomic_bool 55 { 56 private: 57 __atomic_base<bool> _M_base; 58 59 public: 60 atomic_bool() noexcept = default; 61 ~atomic_bool() noexcept = default; 62 atomic_bool(const atomic_bool&) = delete; 63 atomic_bool& operator=(const atomic_bool&) = delete; 64 atomic_bool& operator=(const atomic_bool&) volatile = delete; 65 66 constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { } 67 68 bool 69 operator=(bool __i) noexcept 70 { return _M_base.operator=(__i); } 71 72 bool 73 operator=(bool __i) volatile noexcept 74 { return _M_base.operator=(__i); } 75 76 operator bool() const noexcept 77 { return _M_base.load(); } 78 79 operator bool() const volatile noexcept 80 { return _M_base.load(); } 81 82 bool 83 is_lock_free() const noexcept { return _M_base.is_lock_free(); } 84 85 bool 86 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); } 87 88 void 89 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept 90 { _M_base.store(__i, __m); } 91 92 void 93 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept 94 { _M_base.store(__i, __m); } 95 96 bool 97 load(memory_order __m = memory_order_seq_cst) const noexcept 98 { return _M_base.load(__m); } 99 100 bool 101 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 102 { return _M_base.load(__m); } 103 104 bool 105 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept 106 { return _M_base.exchange(__i, __m); } 107 108 bool 109 exchange(bool __i, 110 memory_order __m = memory_order_seq_cst) volatile noexcept 111 { return _M_base.exchange(__i, __m); } 112 113 bool 114 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 115 memory_order __m2) noexcept 116 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 117 118 bool 119 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1, 120 memory_order __m2) volatile noexcept 121 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); } 122 123 bool 124 compare_exchange_weak(bool& __i1, bool __i2, 125 memory_order __m = memory_order_seq_cst) noexcept 126 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 127 128 bool 129 compare_exchange_weak(bool& __i1, bool __i2, 130 memory_order __m = memory_order_seq_cst) volatile noexcept 131 { return _M_base.compare_exchange_weak(__i1, __i2, __m); } 132 133 bool 134 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 135 memory_order __m2) noexcept 136 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 137 138 bool 139 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1, 140 memory_order __m2) volatile noexcept 141 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); } 142 143 bool 144 compare_exchange_strong(bool& __i1, bool __i2, 145 memory_order __m = memory_order_seq_cst) noexcept 146 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 147 148 bool 149 compare_exchange_strong(bool& __i1, bool __i2, 150 memory_order __m = memory_order_seq_cst) volatile noexcept 151 { return _M_base.compare_exchange_strong(__i1, __i2, __m); } 152 }; 153 154 155 /** 156 * @brief Generic atomic type, primary class template. 157 * 158 * @tparam _Tp Type to be made atomic, must be trivally copyable. 159 */ 160 template<typename _Tp> 161 struct atomic 162 { 163 private: 164 _Tp _M_i; 165 166 public: 167 atomic() noexcept = default; 168 ~atomic() noexcept = default; 169 atomic(const atomic&) = delete; 170 atomic& operator=(const atomic&) = delete; 171 atomic& operator=(const atomic&) volatile = delete; 172 173 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { } 174 175 operator _Tp() const noexcept 176 { return load(); } 177 178 operator _Tp() const volatile noexcept 179 { return load(); } 180 181 _Tp 182 operator=(_Tp __i) noexcept 183 { store(__i); return __i; } 184 185 _Tp 186 operator=(_Tp __i) volatile noexcept 187 { store(__i); return __i; } 188 189 bool 190 is_lock_free() const noexcept 191 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); } 192 193 bool 194 is_lock_free() const volatile noexcept 195 { return __atomic_is_lock_free(sizeof(_M_i), nullptr); } 196 197 void 198 store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 199 { __atomic_store(&_M_i, &__i, _m); } 200 201 void 202 store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept 203 { __atomic_store(&_M_i, &__i, _m); } 204 205 _Tp 206 load(memory_order _m = memory_order_seq_cst) const noexcept 207 { 208 _Tp tmp; 209 __atomic_load(&_M_i, &tmp, _m); 210 return tmp; 211 } 212 213 _Tp 214 load(memory_order _m = memory_order_seq_cst) const volatile noexcept 215 { 216 _Tp tmp; 217 __atomic_load(&_M_i, &tmp, _m); 218 return tmp; 219 } 220 221 _Tp 222 exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept 223 { 224 _Tp tmp; 225 __atomic_exchange(&_M_i, &__i, &tmp, _m); 226 return tmp; 227 } 228 229 _Tp 230 exchange(_Tp __i, 231 memory_order _m = memory_order_seq_cst) volatile noexcept 232 { 233 _Tp tmp; 234 __atomic_exchange(&_M_i, &__i, &tmp, _m); 235 return tmp; 236 } 237 238 bool 239 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 240 memory_order __f) noexcept 241 { 242 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 243 } 244 245 bool 246 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 247 memory_order __f) volatile noexcept 248 { 249 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 250 } 251 252 bool 253 compare_exchange_weak(_Tp& __e, _Tp __i, 254 memory_order __m = memory_order_seq_cst) noexcept 255 { return compare_exchange_weak(__e, __i, __m, 256 __cmpexch_failure_order(__m)); } 257 258 bool 259 compare_exchange_weak(_Tp& __e, _Tp __i, 260 memory_order __m = memory_order_seq_cst) volatile noexcept 261 { return compare_exchange_weak(__e, __i, __m, 262 __cmpexch_failure_order(__m)); } 263 264 bool 265 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 266 memory_order __f) noexcept 267 { 268 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 269 } 270 271 bool 272 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 273 memory_order __f) volatile noexcept 274 { 275 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 276 } 277 278 bool 279 compare_exchange_strong(_Tp& __e, _Tp __i, 280 memory_order __m = memory_order_seq_cst) noexcept 281 { return compare_exchange_strong(__e, __i, __m, 282 __cmpexch_failure_order(__m)); } 283 284 bool 285 compare_exchange_strong(_Tp& __e, _Tp __i, 286 memory_order __m = memory_order_seq_cst) volatile noexcept 287 { return compare_exchange_strong(__e, __i, __m, 288 __cmpexch_failure_order(__m)); } 289 }; 290 291 292 /// Partial specialization for pointer types. 293 template<typename _Tp> 294 struct atomic<_Tp*> 295 { 296 typedef _Tp* __pointer_type; 297 typedef __atomic_base<_Tp*> __base_type; 298 __base_type _M_b; 299 300 atomic() noexcept = default; 301 ~atomic() noexcept = default; 302 atomic(const atomic&) = delete; 303 atomic& operator=(const atomic&) = delete; 304 atomic& operator=(const atomic&) volatile = delete; 305 306 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { } 307 308 operator __pointer_type() const noexcept 309 { return __pointer_type(_M_b); } 310 311 operator __pointer_type() const volatile noexcept 312 { return __pointer_type(_M_b); } 313 314 __pointer_type 315 operator=(__pointer_type __p) noexcept 316 { return _M_b.operator=(__p); } 317 318 __pointer_type 319 operator=(__pointer_type __p) volatile noexcept 320 { return _M_b.operator=(__p); } 321 322 __pointer_type 323 operator++(int) noexcept 324 { return _M_b++; } 325 326 __pointer_type 327 operator++(int) volatile noexcept 328 { return _M_b++; } 329 330 __pointer_type 331 operator--(int) noexcept 332 { return _M_b--; } 333 334 __pointer_type 335 operator--(int) volatile noexcept 336 { return _M_b--; } 337 338 __pointer_type 339 operator++() noexcept 340 { return ++_M_b; } 341 342 __pointer_type 343 operator++() volatile noexcept 344 { return ++_M_b; } 345 346 __pointer_type 347 operator--() noexcept 348 { return --_M_b; } 349 350 __pointer_type 351 operator--() volatile noexcept 352 { return --_M_b; } 353 354 __pointer_type 355 operator+=(ptrdiff_t __d) noexcept 356 { return _M_b.operator+=(__d); } 357 358 __pointer_type 359 operator+=(ptrdiff_t __d) volatile noexcept 360 { return _M_b.operator+=(__d); } 361 362 __pointer_type 363 operator-=(ptrdiff_t __d) noexcept 364 { return _M_b.operator-=(__d); } 365 366 __pointer_type 367 operator-=(ptrdiff_t __d) volatile noexcept 368 { return _M_b.operator-=(__d); } 369 370 bool 371 is_lock_free() const noexcept 372 { return _M_b.is_lock_free(); } 373 374 bool 375 is_lock_free() const volatile noexcept 376 { return _M_b.is_lock_free(); } 377 378 void 379 store(__pointer_type __p, 380 memory_order __m = memory_order_seq_cst) noexcept 381 { return _M_b.store(__p, __m); } 382 383 void 384 store(__pointer_type __p, 385 memory_order __m = memory_order_seq_cst) volatile noexcept 386 { return _M_b.store(__p, __m); } 387 388 __pointer_type 389 load(memory_order __m = memory_order_seq_cst) const noexcept 390 { return _M_b.load(__m); } 391 392 __pointer_type 393 load(memory_order __m = memory_order_seq_cst) const volatile noexcept 394 { return _M_b.load(__m); } 395 396 __pointer_type 397 exchange(__pointer_type __p, 398 memory_order __m = memory_order_seq_cst) noexcept 399 { return _M_b.exchange(__p, __m); } 400 401 __pointer_type 402 exchange(__pointer_type __p, 403 memory_order __m = memory_order_seq_cst) volatile noexcept 404 { return _M_b.exchange(__p, __m); } 405 406 bool 407 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 408 memory_order __m1, memory_order __m2) noexcept 409 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 410 411 bool 412 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 413 memory_order __m1, 414 memory_order __m2) volatile noexcept 415 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 416 417 bool 418 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 419 memory_order __m = memory_order_seq_cst) noexcept 420 { 421 return compare_exchange_weak(__p1, __p2, __m, 422 __cmpexch_failure_order(__m)); 423 } 424 425 bool 426 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2, 427 memory_order __m = memory_order_seq_cst) volatile noexcept 428 { 429 return compare_exchange_weak(__p1, __p2, __m, 430 __cmpexch_failure_order(__m)); 431 } 432 433 bool 434 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 435 memory_order __m1, memory_order __m2) noexcept 436 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 437 438 bool 439 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 440 memory_order __m1, 441 memory_order __m2) volatile noexcept 442 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); } 443 444 bool 445 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 446 memory_order __m = memory_order_seq_cst) noexcept 447 { 448 return _M_b.compare_exchange_strong(__p1, __p2, __m, 449 __cmpexch_failure_order(__m)); 450 } 451 452 bool 453 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2, 454 memory_order __m = memory_order_seq_cst) volatile noexcept 455 { 456 return _M_b.compare_exchange_strong(__p1, __p2, __m, 457 __cmpexch_failure_order(__m)); 458 } 459 460 __pointer_type 461 fetch_add(ptrdiff_t __d, 462 memory_order __m = memory_order_seq_cst) noexcept 463 { return _M_b.fetch_add(__d, __m); } 464 465 __pointer_type 466 fetch_add(ptrdiff_t __d, 467 memory_order __m = memory_order_seq_cst) volatile noexcept 468 { return _M_b.fetch_add(__d, __m); } 469 470 __pointer_type 471 fetch_sub(ptrdiff_t __d, 472 memory_order __m = memory_order_seq_cst) noexcept 473 { return _M_b.fetch_sub(__d, __m); } 474 475 __pointer_type 476 fetch_sub(ptrdiff_t __d, 477 memory_order __m = memory_order_seq_cst) volatile noexcept 478 { return _M_b.fetch_sub(__d, __m); } 479 }; 480 481 482 /// Explicit specialization for bool. 483 template<> 484 struct atomic<bool> : public atomic_bool 485 { 486 typedef bool __integral_type; 487 typedef atomic_bool __base_type; 488 489 atomic() noexcept = default; 490 ~atomic() noexcept = default; 491 atomic(const atomic&) = delete; 492 atomic& operator=(const atomic&) = delete; 493 atomic& operator=(const atomic&) volatile = delete; 494 495 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 496 497 using __base_type::operator __integral_type; 498 using __base_type::operator=; 499 }; 500 501 /// Explicit specialization for char. 502 template<> 503 struct atomic<char> : public atomic_char 504 { 505 typedef char __integral_type; 506 typedef atomic_char __base_type; 507 508 atomic() noexcept = default; 509 ~atomic() noexcept = default; 510 atomic(const atomic&) = delete; 511 atomic& operator=(const atomic&) = delete; 512 atomic& operator=(const atomic&) volatile = delete; 513 514 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 515 516 using __base_type::operator __integral_type; 517 using __base_type::operator=; 518 }; 519 520 /// Explicit specialization for signed char. 521 template<> 522 struct atomic<signed char> : public atomic_schar 523 { 524 typedef signed char __integral_type; 525 typedef atomic_schar __base_type; 526 527 atomic() noexcept= default; 528 ~atomic() noexcept = default; 529 atomic(const atomic&) = delete; 530 atomic& operator=(const atomic&) = delete; 531 atomic& operator=(const atomic&) volatile = delete; 532 533 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 534 535 using __base_type::operator __integral_type; 536 using __base_type::operator=; 537 }; 538 539 /// Explicit specialization for unsigned char. 540 template<> 541 struct atomic<unsigned char> : public atomic_uchar 542 { 543 typedef unsigned char __integral_type; 544 typedef atomic_uchar __base_type; 545 546 atomic() noexcept= default; 547 ~atomic() noexcept = default; 548 atomic(const atomic&) = delete; 549 atomic& operator=(const atomic&) = delete; 550 atomic& operator=(const atomic&) volatile = delete; 551 552 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 553 554 using __base_type::operator __integral_type; 555 using __base_type::operator=; 556 }; 557 558 /// Explicit specialization for short. 559 template<> 560 struct atomic<short> : public atomic_short 561 { 562 typedef short __integral_type; 563 typedef atomic_short __base_type; 564 565 atomic() noexcept = default; 566 ~atomic() noexcept = default; 567 atomic(const atomic&) = delete; 568 atomic& operator=(const atomic&) = delete; 569 atomic& operator=(const atomic&) volatile = delete; 570 571 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 572 573 using __base_type::operator __integral_type; 574 using __base_type::operator=; 575 }; 576 577 /// Explicit specialization for unsigned short. 578 template<> 579 struct atomic<unsigned short> : public atomic_ushort 580 { 581 typedef unsigned short __integral_type; 582 typedef atomic_ushort __base_type; 583 584 atomic() noexcept = default; 585 ~atomic() noexcept = default; 586 atomic(const atomic&) = delete; 587 atomic& operator=(const atomic&) = delete; 588 atomic& operator=(const atomic&) volatile = delete; 589 590 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 591 592 using __base_type::operator __integral_type; 593 using __base_type::operator=; 594 }; 595 596 /// Explicit specialization for int. 597 template<> 598 struct atomic<int> : atomic_int 599 { 600 typedef int __integral_type; 601 typedef atomic_int __base_type; 602 603 atomic() noexcept = default; 604 ~atomic() noexcept = default; 605 atomic(const atomic&) = delete; 606 atomic& operator=(const atomic&) = delete; 607 atomic& operator=(const atomic&) volatile = delete; 608 609 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 610 611 using __base_type::operator __integral_type; 612 using __base_type::operator=; 613 }; 614 615 /// Explicit specialization for unsigned int. 616 template<> 617 struct atomic<unsigned int> : public atomic_uint 618 { 619 typedef unsigned int __integral_type; 620 typedef atomic_uint __base_type; 621 622 atomic() noexcept = default; 623 ~atomic() noexcept = default; 624 atomic(const atomic&) = delete; 625 atomic& operator=(const atomic&) = delete; 626 atomic& operator=(const atomic&) volatile = delete; 627 628 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 629 630 using __base_type::operator __integral_type; 631 using __base_type::operator=; 632 }; 633 634 /// Explicit specialization for long. 635 template<> 636 struct atomic<long> : public atomic_long 637 { 638 typedef long __integral_type; 639 typedef atomic_long __base_type; 640 641 atomic() noexcept = default; 642 ~atomic() noexcept = default; 643 atomic(const atomic&) = delete; 644 atomic& operator=(const atomic&) = delete; 645 atomic& operator=(const atomic&) volatile = delete; 646 647 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 648 649 using __base_type::operator __integral_type; 650 using __base_type::operator=; 651 }; 652 653 /// Explicit specialization for unsigned long. 654 template<> 655 struct atomic<unsigned long> : public atomic_ulong 656 { 657 typedef unsigned long __integral_type; 658 typedef atomic_ulong __base_type; 659 660 atomic() noexcept = default; 661 ~atomic() noexcept = default; 662 atomic(const atomic&) = delete; 663 atomic& operator=(const atomic&) = delete; 664 atomic& operator=(const atomic&) volatile = delete; 665 666 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 667 668 using __base_type::operator __integral_type; 669 using __base_type::operator=; 670 }; 671 672 /// Explicit specialization for long long. 673 template<> 674 struct atomic<long long> : public atomic_llong 675 { 676 typedef long long __integral_type; 677 typedef atomic_llong __base_type; 678 679 atomic() noexcept = default; 680 ~atomic() noexcept = default; 681 atomic(const atomic&) = delete; 682 atomic& operator=(const atomic&) = delete; 683 atomic& operator=(const atomic&) volatile = delete; 684 685 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 686 687 using __base_type::operator __integral_type; 688 using __base_type::operator=; 689 }; 690 691 /// Explicit specialization for unsigned long long. 692 template<> 693 struct atomic<unsigned long long> : public atomic_ullong 694 { 695 typedef unsigned long long __integral_type; 696 typedef atomic_ullong __base_type; 697 698 atomic() noexcept = default; 699 ~atomic() noexcept = default; 700 atomic(const atomic&) = delete; 701 atomic& operator=(const atomic&) = delete; 702 atomic& operator=(const atomic&) volatile = delete; 703 704 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 705 706 using __base_type::operator __integral_type; 707 using __base_type::operator=; 708 }; 709 710 /// Explicit specialization for wchar_t. 711 template<> 712 struct atomic<wchar_t> : public atomic_wchar_t 713 { 714 typedef wchar_t __integral_type; 715 typedef atomic_wchar_t __base_type; 716 717 atomic() noexcept = default; 718 ~atomic() noexcept = default; 719 atomic(const atomic&) = delete; 720 atomic& operator=(const atomic&) = delete; 721 atomic& operator=(const atomic&) volatile = delete; 722 723 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 724 725 using __base_type::operator __integral_type; 726 using __base_type::operator=; 727 }; 728 729 /// Explicit specialization for char16_t. 730 template<> 731 struct atomic<char16_t> : public atomic_char16_t 732 { 733 typedef char16_t __integral_type; 734 typedef atomic_char16_t __base_type; 735 736 atomic() noexcept = default; 737 ~atomic() noexcept = default; 738 atomic(const atomic&) = delete; 739 atomic& operator=(const atomic&) = delete; 740 atomic& operator=(const atomic&) volatile = delete; 741 742 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 743 744 using __base_type::operator __integral_type; 745 using __base_type::operator=; 746 }; 747 748 /// Explicit specialization for char32_t. 749 template<> 750 struct atomic<char32_t> : public atomic_char32_t 751 { 752 typedef char32_t __integral_type; 753 typedef atomic_char32_t __base_type; 754 755 atomic() noexcept = default; 756 ~atomic() noexcept = default; 757 atomic(const atomic&) = delete; 758 atomic& operator=(const atomic&) = delete; 759 atomic& operator=(const atomic&) volatile = delete; 760 761 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } 762 763 using __base_type::operator __integral_type; 764 using __base_type::operator=; 765 }; 766 767 768 // Function definitions, atomic_flag operations. 769 inline bool 770 atomic_flag_test_and_set_explicit(atomic_flag* __a, 771 memory_order __m) noexcept 772 { return __a->test_and_set(__m); } 773 774 inline bool 775 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, 776 memory_order __m) noexcept 777 { return __a->test_and_set(__m); } 778 779 inline void 780 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept 781 { __a->clear(__m); } 782 783 inline void 784 atomic_flag_clear_explicit(volatile atomic_flag* __a, 785 memory_order __m) noexcept 786 { __a->clear(__m); } 787 788 inline bool 789 atomic_flag_test_and_set(atomic_flag* __a) noexcept 790 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 791 792 inline bool 793 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept 794 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); } 795 796 inline void 797 atomic_flag_clear(atomic_flag* __a) noexcept 798 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 799 800 inline void 801 atomic_flag_clear(volatile atomic_flag* __a) noexcept 802 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); } 803 804 805 // Function templates generally applicable to atomic types. 806 template<typename _ITp> 807 inline bool 808 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept 809 { return __a->is_lock_free(); } 810 811 template<typename _ITp> 812 inline bool 813 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept 814 { return __a->is_lock_free(); } 815 816 template<typename _ITp> 817 inline void 818 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept; 819 820 template<typename _ITp> 821 inline void 822 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept; 823 824 template<typename _ITp> 825 inline void 826 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, 827 memory_order __m) noexcept 828 { __a->store(__i, __m); } 829 830 template<typename _ITp> 831 inline void 832 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i, 833 memory_order __m) noexcept 834 { __a->store(__i, __m); } 835 836 template<typename _ITp> 837 inline _ITp 838 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept 839 { return __a->load(__m); } 840 841 template<typename _ITp> 842 inline _ITp 843 atomic_load_explicit(const volatile atomic<_ITp>* __a, 844 memory_order __m) noexcept 845 { return __a->load(__m); } 846 847 template<typename _ITp> 848 inline _ITp 849 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i, 850 memory_order __m) noexcept 851 { return __a->exchange(__i, __m); } 852 853 template<typename _ITp> 854 inline _ITp 855 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i, 856 memory_order __m) noexcept 857 { return __a->exchange(__i, __m); } 858 859 template<typename _ITp> 860 inline bool 861 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a, 862 _ITp* __i1, _ITp __i2, 863 memory_order __m1, 864 memory_order __m2) noexcept 865 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 866 867 template<typename _ITp> 868 inline bool 869 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a, 870 _ITp* __i1, _ITp __i2, 871 memory_order __m1, 872 memory_order __m2) noexcept 873 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); } 874 875 template<typename _ITp> 876 inline bool 877 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a, 878 _ITp* __i1, _ITp __i2, 879 memory_order __m1, 880 memory_order __m2) noexcept 881 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 882 883 template<typename _ITp> 884 inline bool 885 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a, 886 _ITp* __i1, _ITp __i2, 887 memory_order __m1, 888 memory_order __m2) noexcept 889 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); } 890 891 892 template<typename _ITp> 893 inline void 894 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept 895 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 896 897 template<typename _ITp> 898 inline void 899 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept 900 { atomic_store_explicit(__a, __i, memory_order_seq_cst); } 901 902 template<typename _ITp> 903 inline _ITp 904 atomic_load(const atomic<_ITp>* __a) noexcept 905 { return atomic_load_explicit(__a, memory_order_seq_cst); } 906 907 template<typename _ITp> 908 inline _ITp 909 atomic_load(const volatile atomic<_ITp>* __a) noexcept 910 { return atomic_load_explicit(__a, memory_order_seq_cst); } 911 912 template<typename _ITp> 913 inline _ITp 914 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept 915 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 916 917 template<typename _ITp> 918 inline _ITp 919 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept 920 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); } 921 922 template<typename _ITp> 923 inline bool 924 atomic_compare_exchange_weak(atomic<_ITp>* __a, 925 _ITp* __i1, _ITp __i2) noexcept 926 { 927 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 928 memory_order_seq_cst, 929 memory_order_seq_cst); 930 } 931 932 template<typename _ITp> 933 inline bool 934 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a, 935 _ITp* __i1, _ITp __i2) noexcept 936 { 937 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2, 938 memory_order_seq_cst, 939 memory_order_seq_cst); 940 } 941 942 template<typename _ITp> 943 inline bool 944 atomic_compare_exchange_strong(atomic<_ITp>* __a, 945 _ITp* __i1, _ITp __i2) noexcept 946 { 947 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 948 memory_order_seq_cst, 949 memory_order_seq_cst); 950 } 951 952 template<typename _ITp> 953 inline bool 954 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a, 955 _ITp* __i1, _ITp __i2) noexcept 956 { 957 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2, 958 memory_order_seq_cst, 959 memory_order_seq_cst); 960 } 961 962 // Function templates for atomic_integral operations only, using 963 // __atomic_base. Template argument should be constricted to 964 // intergral types as specified in the standard, excluding address 965 // types. 966 template<typename _ITp> 967 inline _ITp 968 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i, 969 memory_order __m) noexcept 970 { return __a->fetch_add(__i, __m); } 971 972 template<typename _ITp> 973 inline _ITp 974 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 975 memory_order __m) noexcept 976 { return __a->fetch_add(__i, __m); } 977 978 template<typename _ITp> 979 inline _ITp 980 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i, 981 memory_order __m) noexcept 982 { return __a->fetch_sub(__i, __m); } 983 984 template<typename _ITp> 985 inline _ITp 986 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 987 memory_order __m) noexcept 988 { return __a->fetch_sub(__i, __m); } 989 990 template<typename _ITp> 991 inline _ITp 992 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i, 993 memory_order __m) noexcept 994 { return __a->fetch_and(__i, __m); } 995 996 template<typename _ITp> 997 inline _ITp 998 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 999 memory_order __m) noexcept 1000 { return __a->fetch_and(__i, __m); } 1001 1002 template<typename _ITp> 1003 inline _ITp 1004 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1005 memory_order __m) noexcept 1006 { return __a->fetch_or(__i, __m); } 1007 1008 template<typename _ITp> 1009 inline _ITp 1010 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1011 memory_order __m) noexcept 1012 { return __a->fetch_or(__i, __m); } 1013 1014 template<typename _ITp> 1015 inline _ITp 1016 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i, 1017 memory_order __m) noexcept 1018 { return __a->fetch_xor(__i, __m); } 1019 1020 template<typename _ITp> 1021 inline _ITp 1022 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i, 1023 memory_order __m) noexcept 1024 { return __a->fetch_xor(__i, __m); } 1025 1026 template<typename _ITp> 1027 inline _ITp 1028 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1029 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1030 1031 template<typename _ITp> 1032 inline _ITp 1033 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1034 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); } 1035 1036 template<typename _ITp> 1037 inline _ITp 1038 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1039 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1040 1041 template<typename _ITp> 1042 inline _ITp 1043 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1044 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); } 1045 1046 template<typename _ITp> 1047 inline _ITp 1048 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1049 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1050 1051 template<typename _ITp> 1052 inline _ITp 1053 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1054 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); } 1055 1056 template<typename _ITp> 1057 inline _ITp 1058 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1059 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1060 1061 template<typename _ITp> 1062 inline _ITp 1063 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1064 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); } 1065 1066 template<typename _ITp> 1067 inline _ITp 1068 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept 1069 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1070 1071 template<typename _ITp> 1072 inline _ITp 1073 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept 1074 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); } 1075 1076 1077 // Partial specializations for pointers. 1078 template<typename _ITp> 1079 inline _ITp* 1080 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 1081 memory_order __m) noexcept 1082 { return __a->fetch_add(__d, __m); } 1083 1084 template<typename _ITp> 1085 inline _ITp* 1086 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d, 1087 memory_order __m) noexcept 1088 { return __a->fetch_add(__d, __m); } 1089 1090 template<typename _ITp> 1091 inline _ITp* 1092 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1093 { return __a->fetch_add(__d); } 1094 1095 template<typename _ITp> 1096 inline _ITp* 1097 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1098 { return __a->fetch_add(__d); } 1099 1100 template<typename _ITp> 1101 inline _ITp* 1102 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a, 1103 ptrdiff_t __d, memory_order __m) noexcept 1104 { return __a->fetch_sub(__d, __m); } 1105 1106 template<typename _ITp> 1107 inline _ITp* 1108 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d, 1109 memory_order __m) noexcept 1110 { return __a->fetch_sub(__d, __m); } 1111 1112 template<typename _ITp> 1113 inline _ITp* 1114 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1115 { return __a->fetch_sub(__d); } 1116 1117 template<typename _ITp> 1118 inline _ITp* 1119 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept 1120 { return __a->fetch_sub(__d); } 1121 // @} group atomics 1122 1123 _GLIBCXX_END_NAMESPACE_VERSION 1124 } // namespace 1125 1126 #endif 1127