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