1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___ATOMIC_ATOMIC_H 10 #define _LIBCPP___ATOMIC_ATOMIC_H 11 12 #include <__atomic/atomic_base.h> 13 #include <__atomic/check_memory_order.h> 14 #include <__atomic/cxx_atomic_impl.h> 15 #include <__atomic/memory_order.h> 16 #include <__config> 17 #include <__memory/addressof.h> 18 #include <__type_traits/is_function.h> 19 #include <__type_traits/is_same.h> 20 #include <__type_traits/remove_pointer.h> 21 #include <cstddef> 22 23 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 24 # pragma GCC system_header 25 #endif 26 27 _LIBCPP_BEGIN_NAMESPACE_STD 28 29 template <class _Tp> 30 struct atomic 31 : public __atomic_base<_Tp> 32 { 33 using __base = __atomic_base<_Tp>; 34 using value_type = _Tp; 35 using difference_type = value_type; 36 37 #if _LIBCPP_STD_VER >= 20 38 _LIBCPP_HIDE_FROM_ABI 39 atomic() = default; 40 #else 41 _LIBCPP_HIDE_FROM_ABI 42 atomic() _NOEXCEPT = default; 43 #endif 44 45 _LIBCPP_HIDE_FROM_ABI 46 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 47 48 _LIBCPP_HIDE_FROM_ABI 49 _Tp operator=(_Tp __d) volatile _NOEXCEPT 50 {__base::store(__d); return __d;} 51 _LIBCPP_HIDE_FROM_ABI 52 _Tp operator=(_Tp __d) _NOEXCEPT 53 {__base::store(__d); return __d;} 54 55 atomic& operator=(const atomic&) = delete; 56 atomic& operator=(const atomic&) volatile = delete; 57 }; 58 59 // atomic<T*> 60 61 template <class _Tp> 62 struct atomic<_Tp*> 63 : public __atomic_base<_Tp*> 64 { 65 using __base = __atomic_base<_Tp*>; 66 using value_type = _Tp*; 67 using difference_type = ptrdiff_t; 68 69 _LIBCPP_HIDE_FROM_ABI 70 atomic() _NOEXCEPT = default; 71 72 _LIBCPP_HIDE_FROM_ABI 73 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 74 75 _LIBCPP_HIDE_FROM_ABI 76 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 77 {__base::store(__d); return __d;} 78 _LIBCPP_HIDE_FROM_ABI 79 _Tp* operator=(_Tp* __d) _NOEXCEPT 80 {__base::store(__d); return __d;} 81 82 _LIBCPP_HIDE_FROM_ABI 83 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 84 // __atomic_fetch_add accepts function pointers, guard against them. 85 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 86 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); 87 } 88 89 _LIBCPP_HIDE_FROM_ABI 90 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { 91 // __atomic_fetch_add accepts function pointers, guard against them. 92 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 93 return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m); 94 } 95 96 _LIBCPP_HIDE_FROM_ABI 97 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 98 // __atomic_fetch_add accepts function pointers, guard against them. 99 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 100 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); 101 } 102 103 _LIBCPP_HIDE_FROM_ABI 104 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { 105 // __atomic_fetch_add accepts function pointers, guard against them. 106 static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 107 return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m); 108 } 109 110 _LIBCPP_HIDE_FROM_ABI 111 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 112 _LIBCPP_HIDE_FROM_ABI 113 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 114 _LIBCPP_HIDE_FROM_ABI 115 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 116 _LIBCPP_HIDE_FROM_ABI 117 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 118 _LIBCPP_HIDE_FROM_ABI 119 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 120 _LIBCPP_HIDE_FROM_ABI 121 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 122 _LIBCPP_HIDE_FROM_ABI 123 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 124 _LIBCPP_HIDE_FROM_ABI 125 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 126 _LIBCPP_HIDE_FROM_ABI 127 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 128 _LIBCPP_HIDE_FROM_ABI 129 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 130 _LIBCPP_HIDE_FROM_ABI 131 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 132 _LIBCPP_HIDE_FROM_ABI 133 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 134 135 atomic& operator=(const atomic&) = delete; 136 atomic& operator=(const atomic&) volatile = delete; 137 }; 138 139 // atomic_is_lock_free 140 141 template <class _Tp> 142 _LIBCPP_HIDE_FROM_ABI 143 bool 144 atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 145 { 146 return __o->is_lock_free(); 147 } 148 149 template <class _Tp> 150 _LIBCPP_HIDE_FROM_ABI 151 bool 152 atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 153 { 154 return __o->is_lock_free(); 155 } 156 157 // atomic_init 158 159 template <class _Tp> 160 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI 161 void 162 atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 163 { 164 std::__cxx_atomic_init(std::addressof(__o->__a_), __d); 165 } 166 167 template <class _Tp> 168 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI 169 void 170 atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 171 { 172 std::__cxx_atomic_init(std::addressof(__o->__a_), __d); 173 } 174 175 // atomic_store 176 177 template <class _Tp> 178 _LIBCPP_HIDE_FROM_ABI 179 void 180 atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 181 { 182 __o->store(__d); 183 } 184 185 template <class _Tp> 186 _LIBCPP_HIDE_FROM_ABI 187 void 188 atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 189 { 190 __o->store(__d); 191 } 192 193 // atomic_store_explicit 194 195 template <class _Tp> 196 _LIBCPP_HIDE_FROM_ABI 197 void 198 atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 199 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 200 { 201 __o->store(__d, __m); 202 } 203 204 template <class _Tp> 205 _LIBCPP_HIDE_FROM_ABI 206 void 207 atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 208 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 209 { 210 __o->store(__d, __m); 211 } 212 213 // atomic_load 214 215 template <class _Tp> 216 _LIBCPP_HIDE_FROM_ABI 217 _Tp 218 atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 219 { 220 return __o->load(); 221 } 222 223 template <class _Tp> 224 _LIBCPP_HIDE_FROM_ABI 225 _Tp 226 atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 227 { 228 return __o->load(); 229 } 230 231 // atomic_load_explicit 232 233 template <class _Tp> 234 _LIBCPP_HIDE_FROM_ABI 235 _Tp 236 atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 237 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 238 { 239 return __o->load(__m); 240 } 241 242 template <class _Tp> 243 _LIBCPP_HIDE_FROM_ABI 244 _Tp 245 atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 246 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 247 { 248 return __o->load(__m); 249 } 250 251 // atomic_exchange 252 253 template <class _Tp> 254 _LIBCPP_HIDE_FROM_ABI 255 _Tp 256 atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 257 { 258 return __o->exchange(__d); 259 } 260 261 template <class _Tp> 262 _LIBCPP_HIDE_FROM_ABI 263 _Tp 264 atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 265 { 266 return __o->exchange(__d); 267 } 268 269 // atomic_exchange_explicit 270 271 template <class _Tp> 272 _LIBCPP_HIDE_FROM_ABI 273 _Tp 274 atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 275 { 276 return __o->exchange(__d, __m); 277 } 278 279 template <class _Tp> 280 _LIBCPP_HIDE_FROM_ABI 281 _Tp 282 atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 283 { 284 return __o->exchange(__d, __m); 285 } 286 287 // atomic_compare_exchange_weak 288 289 template <class _Tp> 290 _LIBCPP_HIDE_FROM_ABI 291 bool 292 atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 293 { 294 return __o->compare_exchange_weak(*__e, __d); 295 } 296 297 template <class _Tp> 298 _LIBCPP_HIDE_FROM_ABI 299 bool 300 atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 301 { 302 return __o->compare_exchange_weak(*__e, __d); 303 } 304 305 // atomic_compare_exchange_strong 306 307 template <class _Tp> 308 _LIBCPP_HIDE_FROM_ABI 309 bool 310 atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 311 { 312 return __o->compare_exchange_strong(*__e, __d); 313 } 314 315 template <class _Tp> 316 _LIBCPP_HIDE_FROM_ABI 317 bool 318 atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 319 { 320 return __o->compare_exchange_strong(*__e, __d); 321 } 322 323 // atomic_compare_exchange_weak_explicit 324 325 template <class _Tp> 326 _LIBCPP_HIDE_FROM_ABI 327 bool 328 atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, 329 typename atomic<_Tp>::value_type __d, 330 memory_order __s, memory_order __f) _NOEXCEPT 331 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 332 { 333 return __o->compare_exchange_weak(*__e, __d, __s, __f); 334 } 335 336 template <class _Tp> 337 _LIBCPP_HIDE_FROM_ABI 338 bool 339 atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, 340 memory_order __s, memory_order __f) _NOEXCEPT 341 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 342 { 343 return __o->compare_exchange_weak(*__e, __d, __s, __f); 344 } 345 346 // atomic_compare_exchange_strong_explicit 347 348 template <class _Tp> 349 _LIBCPP_HIDE_FROM_ABI 350 bool 351 atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 352 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, 353 memory_order __s, memory_order __f) _NOEXCEPT 354 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 355 { 356 return __o->compare_exchange_strong(*__e, __d, __s, __f); 357 } 358 359 template <class _Tp> 360 _LIBCPP_HIDE_FROM_ABI 361 bool 362 atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, 363 typename atomic<_Tp>::value_type __d, 364 memory_order __s, memory_order __f) _NOEXCEPT 365 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 366 { 367 return __o->compare_exchange_strong(*__e, __d, __s, __f); 368 } 369 370 // atomic_wait 371 372 template <class _Tp> 373 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 374 void atomic_wait(const volatile atomic<_Tp>* __o, 375 typename atomic<_Tp>::value_type __v) _NOEXCEPT 376 { 377 return __o->wait(__v); 378 } 379 380 template <class _Tp> 381 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 382 void atomic_wait(const atomic<_Tp>* __o, 383 typename atomic<_Tp>::value_type __v) _NOEXCEPT 384 { 385 return __o->wait(__v); 386 } 387 388 // atomic_wait_explicit 389 390 template <class _Tp> 391 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 392 void atomic_wait_explicit(const volatile atomic<_Tp>* __o, 393 typename atomic<_Tp>::value_type __v, 394 memory_order __m) _NOEXCEPT 395 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 396 { 397 return __o->wait(__v, __m); 398 } 399 400 template <class _Tp> 401 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 402 void atomic_wait_explicit(const atomic<_Tp>* __o, 403 typename atomic<_Tp>::value_type __v, 404 memory_order __m) _NOEXCEPT 405 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 406 { 407 return __o->wait(__v, __m); 408 } 409 410 // atomic_notify_one 411 412 template <class _Tp> 413 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 414 void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT 415 { 416 __o->notify_one(); 417 } 418 template <class _Tp> 419 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 420 void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT 421 { 422 __o->notify_one(); 423 } 424 425 // atomic_notify_all 426 427 template <class _Tp> 428 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 429 void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT 430 { 431 __o->notify_all(); 432 } 433 template <class _Tp> 434 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI 435 void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT 436 { 437 __o->notify_all(); 438 } 439 440 // atomic_fetch_add 441 442 template <class _Tp> 443 _LIBCPP_HIDE_FROM_ABI 444 _Tp 445 atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 446 { 447 return __o->fetch_add(__op); 448 } 449 450 template <class _Tp> 451 _LIBCPP_HIDE_FROM_ABI 452 _Tp 453 atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 454 { 455 return __o->fetch_add(__op); 456 } 457 458 // atomic_fetch_add_explicit 459 460 template <class _Tp> 461 _LIBCPP_HIDE_FROM_ABI 462 _Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 463 { 464 return __o->fetch_add(__op, __m); 465 } 466 467 template <class _Tp> 468 _LIBCPP_HIDE_FROM_ABI 469 _Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 470 { 471 return __o->fetch_add(__op, __m); 472 } 473 474 // atomic_fetch_sub 475 476 template <class _Tp> 477 _LIBCPP_HIDE_FROM_ABI 478 _Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 479 { 480 return __o->fetch_sub(__op); 481 } 482 483 template <class _Tp> 484 _LIBCPP_HIDE_FROM_ABI 485 _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 486 { 487 return __o->fetch_sub(__op); 488 } 489 490 // atomic_fetch_sub_explicit 491 492 template <class _Tp> 493 _LIBCPP_HIDE_FROM_ABI 494 _Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 495 { 496 return __o->fetch_sub(__op, __m); 497 } 498 499 template <class _Tp> 500 _LIBCPP_HIDE_FROM_ABI 501 _Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 502 { 503 return __o->fetch_sub(__op, __m); 504 } 505 506 // atomic_fetch_and 507 508 template <class _Tp> 509 _LIBCPP_HIDE_FROM_ABI 510 typename enable_if 511 < 512 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 513 _Tp 514 >::type 515 atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 516 { 517 return __o->fetch_and(__op); 518 } 519 520 template <class _Tp> 521 _LIBCPP_HIDE_FROM_ABI 522 typename enable_if 523 < 524 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 525 _Tp 526 >::type 527 atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 528 { 529 return __o->fetch_and(__op); 530 } 531 532 // atomic_fetch_and_explicit 533 534 template <class _Tp> 535 _LIBCPP_HIDE_FROM_ABI 536 typename enable_if 537 < 538 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 539 _Tp 540 >::type 541 atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 542 { 543 return __o->fetch_and(__op, __m); 544 } 545 546 template <class _Tp> 547 _LIBCPP_HIDE_FROM_ABI 548 typename enable_if 549 < 550 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 551 _Tp 552 >::type 553 atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 554 { 555 return __o->fetch_and(__op, __m); 556 } 557 558 // atomic_fetch_or 559 560 template <class _Tp> 561 _LIBCPP_HIDE_FROM_ABI 562 typename enable_if 563 < 564 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 565 _Tp 566 >::type 567 atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 568 { 569 return __o->fetch_or(__op); 570 } 571 572 template <class _Tp> 573 _LIBCPP_HIDE_FROM_ABI 574 typename enable_if 575 < 576 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 577 _Tp 578 >::type 579 atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 580 { 581 return __o->fetch_or(__op); 582 } 583 584 // atomic_fetch_or_explicit 585 586 template <class _Tp> 587 _LIBCPP_HIDE_FROM_ABI 588 typename enable_if 589 < 590 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 591 _Tp 592 >::type 593 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 594 { 595 return __o->fetch_or(__op, __m); 596 } 597 598 template <class _Tp> 599 _LIBCPP_HIDE_FROM_ABI 600 typename enable_if 601 < 602 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 603 _Tp 604 >::type 605 atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 606 { 607 return __o->fetch_or(__op, __m); 608 } 609 610 // atomic_fetch_xor 611 612 template <class _Tp> 613 _LIBCPP_HIDE_FROM_ABI 614 typename enable_if 615 < 616 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 617 _Tp 618 >::type 619 atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 620 { 621 return __o->fetch_xor(__op); 622 } 623 624 template <class _Tp> 625 _LIBCPP_HIDE_FROM_ABI 626 typename enable_if 627 < 628 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 629 _Tp 630 >::type 631 atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 632 { 633 return __o->fetch_xor(__op); 634 } 635 636 // atomic_fetch_xor_explicit 637 638 template <class _Tp> 639 _LIBCPP_HIDE_FROM_ABI 640 typename enable_if 641 < 642 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 643 _Tp 644 >::type 645 atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 646 { 647 return __o->fetch_xor(__op, __m); 648 } 649 650 template <class _Tp> 651 _LIBCPP_HIDE_FROM_ABI 652 typename enable_if 653 < 654 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 655 _Tp 656 >::type 657 atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 658 { 659 return __o->fetch_xor(__op, __m); 660 } 661 662 _LIBCPP_END_NAMESPACE_STD 663 664 #endif // _LIBCPP___ATOMIC_ATOMIC_H 665