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