Back to home page

EIC code displayed by LXR

 
 

    


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

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_CXX_ATOMIC_IMPL_H
0010 #define _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H
0011 
0012 #include <__cxx03/__atomic/memory_order.h>
0013 #include <__cxx03/__atomic/to_gcc_order.h>
0014 #include <__cxx03/__config>
0015 #include <__cxx03/__memory/addressof.h>
0016 #include <__cxx03/__type_traits/is_assignable.h>
0017 #include <__cxx03/__type_traits/is_trivially_copyable.h>
0018 #include <__cxx03/__type_traits/remove_const.h>
0019 #include <__cxx03/cstddef>
0020 
0021 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0022 #  pragma GCC system_header
0023 #endif
0024 
0025 _LIBCPP_BEGIN_NAMESPACE_STD
0026 
0027 #if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
0028 
0029 // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
0030 // the default operator= in an object is not volatile, a byte-by-byte copy
0031 // is required.
0032 template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>
0033 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
0034   __a_value = __val;
0035 }
0036 template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>
0037 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
0038   volatile char* __to         = reinterpret_cast<volatile char*>(std::addressof(__a_value));
0039   volatile char* __end        = __to + sizeof(_Tp);
0040   volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));
0041   while (__to != __end)
0042     *__to++ = *__from++;
0043 }
0044 
0045 template <typename _Tp>
0046 struct __cxx_atomic_base_impl {
0047   _LIBCPP_HIDE_FROM_ABI
0048 #  ifndef _LIBCPP_CXX03_LANG
0049   __cxx_atomic_base_impl() _NOEXCEPT = default;
0050 #  else
0051   __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {
0052   }
0053 #  endif // _LIBCPP_CXX03_LANG
0054   _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {}
0055   _Tp __a_value;
0056 };
0057 
0058 template <typename _Tp>
0059 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
0060   __cxx_atomic_assign_volatile(__a->__a_value, __val);
0061 }
0062 
0063 template <typename _Tp>
0064 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
0065   __a->__a_value = __val;
0066 }
0067 
0068 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) {
0069   __atomic_thread_fence(__to_gcc_order(__order));
0070 }
0071 
0072 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) {
0073   __atomic_signal_fence(__to_gcc_order(__order));
0074 }
0075 
0076 template <typename _Tp>
0077 _LIBCPP_HIDE_FROM_ABI void
0078 __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {
0079   __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
0080 }
0081 
0082 template <typename _Tp>
0083 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {
0084   __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
0085 }
0086 
0087 template <typename _Tp>
0088 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
0089   _Tp __ret;
0090   __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
0091   return __ret;
0092 }
0093 
0094 template <typename _Tp>
0095 _LIBCPP_HIDE_FROM_ABI void
0096 __cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {
0097   __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));
0098 }
0099 
0100 template <typename _Tp>
0101 _LIBCPP_HIDE_FROM_ABI void
0102 __cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {
0103   __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));
0104 }
0105 
0106 template <typename _Tp>
0107 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
0108   _Tp __ret;
0109   __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
0110   return __ret;
0111 }
0112 
0113 template <typename _Tp>
0114 _LIBCPP_HIDE_FROM_ABI _Tp
0115 __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {
0116   _Tp __ret;
0117   __atomic_exchange(
0118       std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
0119   return __ret;
0120 }
0121 
0122 template <typename _Tp>
0123 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {
0124   _Tp __ret;
0125   __atomic_exchange(
0126       std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
0127   return __ret;
0128 }
0129 
0130 template <typename _Tp>
0131 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
0132     volatile __cxx_atomic_base_impl<_Tp>* __a,
0133     _Tp* __expected,
0134     _Tp __value,
0135     memory_order __success,
0136     memory_order __failure) {
0137   return __atomic_compare_exchange(
0138       std::addressof(__a->__a_value),
0139       __expected,
0140       std::addressof(__value),
0141       false,
0142       __to_gcc_order(__success),
0143       __to_gcc_failure_order(__failure));
0144 }
0145 
0146 template <typename _Tp>
0147 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
0148     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {
0149   return __atomic_compare_exchange(
0150       std::addressof(__a->__a_value),
0151       __expected,
0152       std::addressof(__value),
0153       false,
0154       __to_gcc_order(__success),
0155       __to_gcc_failure_order(__failure));
0156 }
0157 
0158 template <typename _Tp>
0159 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
0160     volatile __cxx_atomic_base_impl<_Tp>* __a,
0161     _Tp* __expected,
0162     _Tp __value,
0163     memory_order __success,
0164     memory_order __failure) {
0165   return __atomic_compare_exchange(
0166       std::addressof(__a->__a_value),
0167       __expected,
0168       std::addressof(__value),
0169       true,
0170       __to_gcc_order(__success),
0171       __to_gcc_failure_order(__failure));
0172 }
0173 
0174 template <typename _Tp>
0175 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
0176     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {
0177   return __atomic_compare_exchange(
0178       std::addressof(__a->__a_value),
0179       __expected,
0180       std::addressof(__value),
0181       true,
0182       __to_gcc_order(__success),
0183       __to_gcc_failure_order(__failure));
0184 }
0185 
0186 template <typename _Tp>
0187 struct __skip_amt {
0188   enum { value = 1 };
0189 };
0190 
0191 template <typename _Tp>
0192 struct __skip_amt<_Tp*> {
0193   enum { value = sizeof(_Tp) };
0194 };
0195 
0196 // FIXME: Haven't figured out what the spec says about using arrays with
0197 // atomic_fetch_add. Force a failure rather than creating bad behavior.
0198 template <typename _Tp>
0199 struct __skip_amt<_Tp[]> {};
0200 template <typename _Tp, int n>
0201 struct __skip_amt<_Tp[n]> {};
0202 
0203 template <typename _Tp, typename _Td>
0204 _LIBCPP_HIDE_FROM_ABI _Tp
0205 __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
0206   return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
0207 }
0208 
0209 template <typename _Tp, typename _Td>
0210 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
0211   return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
0212 }
0213 
0214 template <typename _Tp, typename _Td>
0215 _LIBCPP_HIDE_FROM_ABI _Tp
0216 __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
0217   return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
0218 }
0219 
0220 template <typename _Tp, typename _Td>
0221 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
0222   return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
0223 }
0224 
0225 template <typename _Tp>
0226 _LIBCPP_HIDE_FROM_ABI _Tp
0227 __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0228   return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0229 }
0230 
0231 template <typename _Tp>
0232 _LIBCPP_HIDE_FROM_ABI _Tp
0233 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0234   return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0235 }
0236 
0237 template <typename _Tp>
0238 _LIBCPP_HIDE_FROM_ABI _Tp
0239 __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0240   return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0241 }
0242 
0243 template <typename _Tp>
0244 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0245   return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0246 }
0247 
0248 template <typename _Tp>
0249 _LIBCPP_HIDE_FROM_ABI _Tp
0250 __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0251   return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0252 }
0253 
0254 template <typename _Tp>
0255 _LIBCPP_HIDE_FROM_ABI _Tp
0256 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
0257   return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
0258 }
0259 
0260 #  define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
0261 
0262 #elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
0263 
0264 template <typename _Tp>
0265 struct __cxx_atomic_base_impl {
0266   _LIBCPP_HIDE_FROM_ABI
0267 #  ifndef _LIBCPP_CXX03_LANG
0268   __cxx_atomic_base_impl() _NOEXCEPT = default;
0269 #  else
0270   __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {
0271   }
0272 #  endif // _LIBCPP_CXX03_LANG
0273   _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {}
0274   _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
0275 };
0276 
0277 #  define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
0278 
0279 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
0280   __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
0281 }
0282 
0283 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
0284   __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
0285 }
0286 
0287 template <class _Tp>
0288 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
0289   __c11_atomic_init(std::addressof(__a->__a_value), __val);
0290 }
0291 template <class _Tp>
0292 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT {
0293   __c11_atomic_init(std::addressof(__a->__a_value), __val);
0294 }
0295 
0296 template <class _Tp>
0297 _LIBCPP_HIDE_FROM_ABI void
0298 __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
0299   __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
0300 }
0301 template <class _Tp>
0302 _LIBCPP_HIDE_FROM_ABI void
0303 __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT {
0304   __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
0305 }
0306 
0307 template <class _Tp>
0308 _LIBCPP_HIDE_FROM_ABI _Tp
0309 __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
0310   using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
0311   return __c11_atomic_load(
0312       const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
0313 }
0314 template <class _Tp>
0315 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
0316   using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
0317   return __c11_atomic_load(
0318       const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
0319 }
0320 
0321 template <class _Tp>
0322 _LIBCPP_HIDE_FROM_ABI void
0323 __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
0324   using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
0325   *__dst           = __c11_atomic_load(
0326       const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
0327 }
0328 template <class _Tp>
0329 _LIBCPP_HIDE_FROM_ABI void
0330 __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
0331   using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
0332   *__dst           = __c11_atomic_load(
0333       const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
0334 }
0335 
0336 template <class _Tp>
0337 _LIBCPP_HIDE_FROM_ABI _Tp
0338 __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
0339   return __c11_atomic_exchange(
0340       std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
0341 }
0342 template <class _Tp>
0343 _LIBCPP_HIDE_FROM_ABI _Tp
0344 __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT {
0345   return __c11_atomic_exchange(
0346       std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
0347 }
0348 
0349 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
0350   // Avoid switch statement to make this a constexpr.
0351   return __order == memory_order_release
0352            ? memory_order_relaxed
0353            : (__order == memory_order_acq_rel ? memory_order_acquire : __order);
0354 }
0355 
0356 template <class _Tp>
0357 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
0358     __cxx_atomic_base_impl<_Tp> volatile* __a,
0359     _Tp* __expected,
0360     _Tp __value,
0361     memory_order __success,
0362     memory_order __failure) _NOEXCEPT {
0363   return __c11_atomic_compare_exchange_strong(
0364       std::addressof(__a->__a_value),
0365       __expected,
0366       __value,
0367       static_cast<__memory_order_underlying_t>(__success),
0368       static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
0369 }
0370 template <class _Tp>
0371 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
0372     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
0373     _NOEXCEPT {
0374   return __c11_atomic_compare_exchange_strong(
0375       std::addressof(__a->__a_value),
0376       __expected,
0377       __value,
0378       static_cast<__memory_order_underlying_t>(__success),
0379       static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
0380 }
0381 
0382 template <class _Tp>
0383 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
0384     __cxx_atomic_base_impl<_Tp> volatile* __a,
0385     _Tp* __expected,
0386     _Tp __value,
0387     memory_order __success,
0388     memory_order __failure) _NOEXCEPT {
0389   return __c11_atomic_compare_exchange_weak(
0390       std::addressof(__a->__a_value),
0391       __expected,
0392       __value,
0393       static_cast<__memory_order_underlying_t>(__success),
0394       static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
0395 }
0396 template <class _Tp>
0397 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
0398     __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
0399     _NOEXCEPT {
0400   return __c11_atomic_compare_exchange_weak(
0401       std::addressof(__a->__a_value),
0402       __expected,
0403       __value,
0404       static_cast<__memory_order_underlying_t>(__success),
0405       static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
0406 }
0407 
0408 template <class _Tp>
0409 _LIBCPP_HIDE_FROM_ABI _Tp
0410 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
0411   return __c11_atomic_fetch_add(
0412       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0413 }
0414 template <class _Tp>
0415 _LIBCPP_HIDE_FROM_ABI _Tp
0416 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
0417   return __c11_atomic_fetch_add(
0418       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0419 }
0420 
0421 template <class _Tp>
0422 _LIBCPP_HIDE_FROM_ABI _Tp*
0423 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
0424   return __c11_atomic_fetch_add(
0425       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0426 }
0427 template <class _Tp>
0428 _LIBCPP_HIDE_FROM_ABI _Tp*
0429 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
0430   return __c11_atomic_fetch_add(
0431       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0432 }
0433 
0434 template <class _Tp>
0435 _LIBCPP_HIDE_FROM_ABI _Tp
0436 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
0437   return __c11_atomic_fetch_sub(
0438       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0439 }
0440 template <class _Tp>
0441 _LIBCPP_HIDE_FROM_ABI _Tp
0442 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
0443   return __c11_atomic_fetch_sub(
0444       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0445 }
0446 template <class _Tp>
0447 _LIBCPP_HIDE_FROM_ABI _Tp*
0448 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
0449   return __c11_atomic_fetch_sub(
0450       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0451 }
0452 template <class _Tp>
0453 _LIBCPP_HIDE_FROM_ABI _Tp*
0454 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
0455   return __c11_atomic_fetch_sub(
0456       std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
0457 }
0458 
0459 template <class _Tp>
0460 _LIBCPP_HIDE_FROM_ABI _Tp
0461 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0462   return __c11_atomic_fetch_and(
0463       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0464 }
0465 template <class _Tp>
0466 _LIBCPP_HIDE_FROM_ABI _Tp
0467 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0468   return __c11_atomic_fetch_and(
0469       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0470 }
0471 
0472 template <class _Tp>
0473 _LIBCPP_HIDE_FROM_ABI _Tp
0474 __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0475   return __c11_atomic_fetch_or(
0476       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0477 }
0478 template <class _Tp>
0479 _LIBCPP_HIDE_FROM_ABI _Tp
0480 __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0481   return __c11_atomic_fetch_or(
0482       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0483 }
0484 
0485 template <class _Tp>
0486 _LIBCPP_HIDE_FROM_ABI _Tp
0487 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0488   return __c11_atomic_fetch_xor(
0489       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0490 }
0491 template <class _Tp>
0492 _LIBCPP_HIDE_FROM_ABI _Tp
0493 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
0494   return __c11_atomic_fetch_xor(
0495       std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
0496 }
0497 
0498 #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
0499 
0500 template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >
0501 struct __cxx_atomic_impl : public _Base {
0502   static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");
0503 
0504   _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
0505   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}
0506 };
0507 
0508 _LIBCPP_END_NAMESPACE_STD
0509 
0510 #endif // _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H