Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:22

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_H
0010 #define _LIBCPP___CXX03___ATOMIC_ATOMIC_H
0011 
0012 #include <__cxx03/__atomic/atomic_base.h>
0013 #include <__cxx03/__atomic/check_memory_order.h>
0014 #include <__cxx03/__atomic/cxx_atomic_impl.h>
0015 #include <__cxx03/__atomic/memory_order.h>
0016 #include <__cxx03/__config>
0017 #include <__cxx03/__functional/operations.h>
0018 #include <__cxx03/__memory/addressof.h>
0019 #include <__cxx03/__type_traits/is_floating_point.h>
0020 #include <__cxx03/__type_traits/is_function.h>
0021 #include <__cxx03/__type_traits/is_same.h>
0022 #include <__cxx03/__type_traits/remove_const.h>
0023 #include <__cxx03/__type_traits/remove_pointer.h>
0024 #include <__cxx03/__type_traits/remove_volatile.h>
0025 #include <__cxx03/__utility/forward.h>
0026 #include <__cxx03/cstddef>
0027 #include <__cxx03/cstring>
0028 
0029 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0030 #  pragma GCC system_header
0031 #endif
0032 
0033 _LIBCPP_BEGIN_NAMESPACE_STD
0034 
0035 template <class _Tp>
0036 struct atomic : public __atomic_base<_Tp> {
0037   using __base          = __atomic_base<_Tp>;
0038   using value_type      = _Tp;
0039   using difference_type = value_type;
0040 
0041 #if _LIBCPP_STD_VER >= 20
0042   _LIBCPP_HIDE_FROM_ABI atomic() = default;
0043 #else
0044   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
0045 #endif
0046 
0047   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
0048 
0049   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile _NOEXCEPT {
0050     __base::store(__d);
0051     return __d;
0052   }
0053   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) _NOEXCEPT {
0054     __base::store(__d);
0055     return __d;
0056   }
0057 
0058   atomic& operator=(const atomic&)          = delete;
0059   atomic& operator=(const atomic&) volatile = delete;
0060 };
0061 
0062 // atomic<T*>
0063 
0064 template <class _Tp>
0065 struct atomic<_Tp*> : public __atomic_base<_Tp*> {
0066   using __base          = __atomic_base<_Tp*>;
0067   using value_type      = _Tp*;
0068   using difference_type = ptrdiff_t;
0069 
0070   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
0071 
0072   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
0073 
0074   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) volatile _NOEXCEPT {
0075     __base::store(__d);
0076     return __d;
0077   }
0078   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) _NOEXCEPT {
0079     __base::store(__d);
0080     return __d;
0081   }
0082 
0083   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
0084     // __atomic_fetch_add accepts function pointers, guard against them.
0085     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
0086     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
0087   }
0088 
0089   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
0090     // __atomic_fetch_add accepts function pointers, guard against them.
0091     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
0092     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
0093   }
0094 
0095   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
0096     // __atomic_fetch_add accepts function pointers, guard against them.
0097     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
0098     return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
0099   }
0100 
0101   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
0102     // __atomic_fetch_add accepts function pointers, guard against them.
0103     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
0104     return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
0105   }
0106 
0107   _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) volatile _NOEXCEPT { return fetch_add(1); }
0108   _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) _NOEXCEPT { return fetch_add(1); }
0109   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) volatile _NOEXCEPT { return fetch_sub(1); }
0110   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) _NOEXCEPT { return fetch_sub(1); }
0111   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() volatile _NOEXCEPT { return fetch_add(1) + 1; }
0112   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() _NOEXCEPT { return fetch_add(1) + 1; }
0113   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() volatile _NOEXCEPT { return fetch_sub(1) - 1; }
0114   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() _NOEXCEPT { return fetch_sub(1) - 1; }
0115   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }
0116   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT { return fetch_add(__op) + __op; }
0117   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }
0118   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT { return fetch_sub(__op) - __op; }
0119 
0120   atomic& operator=(const atomic&)          = delete;
0121   atomic& operator=(const atomic&) volatile = delete;
0122 };
0123 
0124 #if _LIBCPP_STD_VER >= 20
0125 template <class _Tp>
0126   requires is_floating_point_v<_Tp>
0127 struct atomic<_Tp> : __atomic_base<_Tp> {
0128 private:
0129   _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() {
0130     // Only x87-fp80 long double has 64-bit mantissa
0131     return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
0132   }
0133 
0134   _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() {
0135 #  ifndef _LIBCPP_COMPILER_CLANG_BASED
0136     return false;
0137 #  else
0138     // The builtin __cxx_atomic_fetch_add errors during compilation for
0139     // long double on platforms with fp80 format.
0140     // For more details, see
0141     // lib/Sema/SemaChecking.cpp function IsAllowedValueType
0142     // LLVM Parser does not allow atomicrmw with x86_fp80 type.
0143     // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
0144     //    &Context.getTargetInfo().getLongDoubleFormat() ==
0145     //        &llvm::APFloat::x87DoubleExtended())
0146     // For more info
0147     // https://github.com/llvm/llvm-project/issues/68602
0148     // https://reviews.llvm.org/D53965
0149     return !__is_fp80_long_double();
0150 #  endif
0151   }
0152 
0153   template <class _This, class _Operation, class _BuiltinOp>
0154   _LIBCPP_HIDE_FROM_ABI static _Tp
0155   __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
0156     if constexpr (__has_rmw_builtin()) {
0157       return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
0158     } else {
0159       _Tp __old = __self.load(memory_order_relaxed);
0160       _Tp __new = __operation(__old, __operand);
0161       while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
0162 #  ifdef _LIBCPP_COMPILER_CLANG_BASED
0163         if constexpr (__is_fp80_long_double()) {
0164           // https://github.com/llvm/llvm-project/issues/47978
0165           // clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
0166           // Note __old = __self.load(memory_order_relaxed) will not work
0167           std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, memory_order_relaxed);
0168         }
0169 #  endif
0170         __new = __operation(__old, __operand);
0171       }
0172       return __old;
0173     }
0174   }
0175 
0176   template <class _This>
0177   _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_add(_This&& __self, _Tp __operand, memory_order __m) {
0178     auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) {
0179       return std::__cxx_atomic_fetch_add(__a, __builtin_operand, __order);
0180     };
0181     return __rmw_op(std::forward<_This>(__self), __operand, __m, std::plus<>{}, __builtin_op);
0182   }
0183 
0184   template <class _This>
0185   _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_sub(_This&& __self, _Tp __operand, memory_order __m) {
0186     auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) {
0187       return std::__cxx_atomic_fetch_sub(__a, __builtin_operand, __order);
0188     };
0189     return __rmw_op(std::forward<_This>(__self), __operand, __m, std::minus<>{}, __builtin_op);
0190   }
0191 
0192 public:
0193   using __base          = __atomic_base<_Tp>;
0194   using value_type      = _Tp;
0195   using difference_type = value_type;
0196 
0197   _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default;
0198   _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {}
0199 
0200   atomic(const atomic&)                     = delete;
0201   atomic& operator=(const atomic&)          = delete;
0202   atomic& operator=(const atomic&) volatile = delete;
0203 
0204   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile noexcept
0205     requires __base::is_always_lock_free
0206   {
0207     __base::store(__d);
0208     return __d;
0209   }
0210   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) noexcept {
0211     __base::store(__d);
0212     return __d;
0213   }
0214 
0215   _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept
0216     requires __base::is_always_lock_free
0217   {
0218     return __fetch_add(*this, __op, __m);
0219   }
0220 
0221   _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept {
0222     return __fetch_add(*this, __op, __m);
0223   }
0224 
0225   _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept
0226     requires __base::is_always_lock_free
0227   {
0228     return __fetch_sub(*this, __op, __m);
0229   }
0230 
0231   _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept {
0232     return __fetch_sub(*this, __op, __m);
0233   }
0234 
0235   _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile noexcept
0236     requires __base::is_always_lock_free
0237   {
0238     return fetch_add(__op) + __op;
0239   }
0240 
0241   _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) noexcept { return fetch_add(__op) + __op; }
0242 
0243   _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile noexcept
0244     requires __base::is_always_lock_free
0245   {
0246     return fetch_sub(__op) - __op;
0247   }
0248 
0249   _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) noexcept { return fetch_sub(__op) - __op; }
0250 };
0251 
0252 #endif // _LIBCPP_STD_VER >= 20
0253 
0254 // atomic_is_lock_free
0255 
0256 template <class _Tp>
0257 _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
0258   return __o->is_lock_free();
0259 }
0260 
0261 template <class _Tp>
0262 _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
0263   return __o->is_lock_free();
0264 }
0265 
0266 // atomic_init
0267 
0268 template <class _Tp>
0269 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void
0270 atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0271   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
0272 }
0273 
0274 template <class _Tp>
0275 _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void
0276 atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0277   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
0278 }
0279 
0280 // atomic_store
0281 
0282 template <class _Tp>
0283 _LIBCPP_HIDE_FROM_ABI void atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0284   __o->store(__d);
0285 }
0286 
0287 template <class _Tp>
0288 _LIBCPP_HIDE_FROM_ABI void atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0289   __o->store(__d);
0290 }
0291 
0292 // atomic_store_explicit
0293 
0294 template <class _Tp>
0295 _LIBCPP_HIDE_FROM_ABI void
0296 atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
0297     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
0298   __o->store(__d, __m);
0299 }
0300 
0301 template <class _Tp>
0302 _LIBCPP_HIDE_FROM_ABI void
0303 atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
0304     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
0305   __o->store(__d, __m);
0306 }
0307 
0308 // atomic_load
0309 
0310 template <class _Tp>
0311 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
0312   return __o->load();
0313 }
0314 
0315 template <class _Tp>
0316 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
0317   return __o->load();
0318 }
0319 
0320 // atomic_load_explicit
0321 
0322 template <class _Tp>
0323 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
0324     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
0325   return __o->load(__m);
0326 }
0327 
0328 template <class _Tp>
0329 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
0330     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
0331   return __o->load(__m);
0332 }
0333 
0334 // atomic_exchange
0335 
0336 template <class _Tp>
0337 _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0338   return __o->exchange(__d);
0339 }
0340 
0341 template <class _Tp>
0342 _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0343   return __o->exchange(__d);
0344 }
0345 
0346 // atomic_exchange_explicit
0347 
0348 template <class _Tp>
0349 _LIBCPP_HIDE_FROM_ABI _Tp
0350 atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
0351   return __o->exchange(__d, __m);
0352 }
0353 
0354 template <class _Tp>
0355 _LIBCPP_HIDE_FROM_ABI _Tp
0356 atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
0357   return __o->exchange(__d, __m);
0358 }
0359 
0360 // atomic_compare_exchange_weak
0361 
0362 template <class _Tp>
0363 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
0364     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0365   return __o->compare_exchange_weak(*__e, __d);
0366 }
0367 
0368 template <class _Tp>
0369 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
0370     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0371   return __o->compare_exchange_weak(*__e, __d);
0372 }
0373 
0374 // atomic_compare_exchange_strong
0375 
0376 template <class _Tp>
0377 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
0378     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0379   return __o->compare_exchange_strong(*__e, __d);
0380 }
0381 
0382 template <class _Tp>
0383 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
0384     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
0385   return __o->compare_exchange_strong(*__e, __d);
0386 }
0387 
0388 // atomic_compare_exchange_weak_explicit
0389 
0390 template <class _Tp>
0391 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
0392     volatile atomic<_Tp>* __o,
0393     typename atomic<_Tp>::value_type* __e,
0394     typename atomic<_Tp>::value_type __d,
0395     memory_order __s,
0396     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
0397   return __o->compare_exchange_weak(*__e, __d, __s, __f);
0398 }
0399 
0400 template <class _Tp>
0401 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
0402     atomic<_Tp>* __o,
0403     typename atomic<_Tp>::value_type* __e,
0404     typename atomic<_Tp>::value_type __d,
0405     memory_order __s,
0406     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
0407   return __o->compare_exchange_weak(*__e, __d, __s, __f);
0408 }
0409 
0410 // atomic_compare_exchange_strong_explicit
0411 
0412 template <class _Tp>
0413 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
0414     volatile atomic<_Tp>* __o,
0415     typename atomic<_Tp>::value_type* __e,
0416     typename atomic<_Tp>::value_type __d,
0417     memory_order __s,
0418     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
0419   return __o->compare_exchange_strong(*__e, __d, __s, __f);
0420 }
0421 
0422 template <class _Tp>
0423 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
0424     atomic<_Tp>* __o,
0425     typename atomic<_Tp>::value_type* __e,
0426     typename atomic<_Tp>::value_type __d,
0427     memory_order __s,
0428     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
0429   return __o->compare_exchange_strong(*__e, __d, __s, __f);
0430 }
0431 
0432 // atomic_wait
0433 
0434 template <class _Tp>
0435 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0436 atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
0437   return __o->wait(__v);
0438 }
0439 
0440 template <class _Tp>
0441 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0442 atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
0443   return __o->wait(__v);
0444 }
0445 
0446 // atomic_wait_explicit
0447 
0448 template <class _Tp>
0449 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0450 atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
0451     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
0452   return __o->wait(__v, __m);
0453 }
0454 
0455 template <class _Tp>
0456 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0457 atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
0458     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
0459   return __o->wait(__v, __m);
0460 }
0461 
0462 // atomic_notify_one
0463 
0464 template <class _Tp>
0465 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0466 atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
0467   __o->notify_one();
0468 }
0469 template <class _Tp>
0470 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0471 atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
0472   __o->notify_one();
0473 }
0474 
0475 // atomic_notify_all
0476 
0477 template <class _Tp>
0478 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0479 atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
0480   __o->notify_all();
0481 }
0482 template <class _Tp>
0483 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
0484 atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
0485   __o->notify_all();
0486 }
0487 
0488 // atomic_fetch_add
0489 
0490 template <class _Tp>
0491 _LIBCPP_HIDE_FROM_ABI _Tp
0492 atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
0493   return __o->fetch_add(__op);
0494 }
0495 
0496 template <class _Tp>
0497 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
0498   return __o->fetch_add(__op);
0499 }
0500 
0501 // atomic_fetch_add_explicit
0502 
0503 template <class _Tp>
0504 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add_explicit(
0505     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
0506   return __o->fetch_add(__op, __m);
0507 }
0508 
0509 template <class _Tp>
0510 _LIBCPP_HIDE_FROM_ABI _Tp
0511 atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
0512   return __o->fetch_add(__op, __m);
0513 }
0514 
0515 // atomic_fetch_sub
0516 
0517 template <class _Tp>
0518 _LIBCPP_HIDE_FROM_ABI _Tp
0519 atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
0520   return __o->fetch_sub(__op);
0521 }
0522 
0523 template <class _Tp>
0524 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
0525   return __o->fetch_sub(__op);
0526 }
0527 
0528 // atomic_fetch_sub_explicit
0529 
0530 template <class _Tp>
0531 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub_explicit(
0532     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
0533   return __o->fetch_sub(__op, __m);
0534 }
0535 
0536 template <class _Tp>
0537 _LIBCPP_HIDE_FROM_ABI _Tp
0538 atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
0539   return __o->fetch_sub(__op, __m);
0540 }
0541 
0542 // atomic_fetch_and
0543 
0544 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0545 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0546   return __o->fetch_and(__op);
0547 }
0548 
0549 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0550 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0551   return __o->fetch_and(__op);
0552 }
0553 
0554 // atomic_fetch_and_explicit
0555 
0556 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0557 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and_explicit(
0558     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0559   return __o->fetch_and(__op, __m);
0560 }
0561 
0562 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0563 _LIBCPP_HIDE_FROM_ABI _Tp
0564 atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0565   return __o->fetch_and(__op, __m);
0566 }
0567 
0568 // atomic_fetch_or
0569 
0570 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0571 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0572   return __o->fetch_or(__op);
0573 }
0574 
0575 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0576 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0577   return __o->fetch_or(__op);
0578 }
0579 
0580 // atomic_fetch_or_explicit
0581 
0582 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0583 _LIBCPP_HIDE_FROM_ABI _Tp
0584 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0585   return __o->fetch_or(__op, __m);
0586 }
0587 
0588 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0589 _LIBCPP_HIDE_FROM_ABI _Tp
0590 atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0591   return __o->fetch_or(__op, __m);
0592 }
0593 
0594 // atomic_fetch_xor
0595 
0596 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0597 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0598   return __o->fetch_xor(__op);
0599 }
0600 
0601 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0602 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
0603   return __o->fetch_xor(__op);
0604 }
0605 
0606 // atomic_fetch_xor_explicit
0607 
0608 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0609 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor_explicit(
0610     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0611   return __o->fetch_xor(__op, __m);
0612 }
0613 
0614 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
0615 _LIBCPP_HIDE_FROM_ABI _Tp
0616 atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
0617   return __o->fetch_xor(__op, __m);
0618 }
0619 
0620 _LIBCPP_END_NAMESPACE_STD
0621 
0622 #endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_H