499 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H10#define _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H11 12#include <__cxx03/__atomic/memory_order.h>13#include <__cxx03/__atomic/to_gcc_order.h>14#include <__cxx03/__config>15#include <__cxx03/__memory/addressof.h>16#include <__cxx03/__type_traits/is_assignable.h>17#include <__cxx03/__type_traits/is_trivially_copyable.h>18#include <__cxx03/__type_traits/remove_const.h>19#include <__cxx03/cstddef>20 21#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)22# pragma GCC system_header23#endif24 25_LIBCPP_BEGIN_NAMESPACE_STD26 27#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)28 29// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because30// the default operator= in an object is not volatile, a byte-by-byte copy31// is required.32template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>33_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {34 __a_value = __val;35}36template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>37_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {38 volatile char* __to = reinterpret_cast<volatile char*>(std::addressof(__a_value));39 volatile char* __end = __to + sizeof(_Tp);40 volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));41 while (__to != __end)42 *__to++ = *__from++;43}44 45template <typename _Tp>46struct __cxx_atomic_base_impl {47 _LIBCPP_HIDE_FROM_ABI __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}48 explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {}49 _Tp __a_value;50};51 52template <typename _Tp>53_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {54 __cxx_atomic_assign_volatile(__a->__a_value, __val);55}56 57template <typename _Tp>58_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {59 __a->__a_value = __val;60}61 62_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) {63 __atomic_thread_fence(__to_gcc_order(__order));64}65 66_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) {67 __atomic_signal_fence(__to_gcc_order(__order));68}69 70template <typename _Tp>71_LIBCPP_HIDE_FROM_ABI void72__cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {73 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));74}75 76template <typename _Tp>77_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {78 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));79}80 81template <typename _Tp>82_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {83 _Tp __ret;84 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));85 return __ret;86}87 88template <typename _Tp>89_LIBCPP_HIDE_FROM_ABI void90__cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {91 __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));92}93 94template <typename _Tp>95_LIBCPP_HIDE_FROM_ABI void96__cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {97 __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));98}99 100template <typename _Tp>101_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {102 _Tp __ret;103 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));104 return __ret;105}106 107template <typename _Tp>108_LIBCPP_HIDE_FROM_ABI _Tp109__cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {110 _Tp __ret;111 __atomic_exchange(112 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));113 return __ret;114}115 116template <typename _Tp>117_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {118 _Tp __ret;119 __atomic_exchange(120 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));121 return __ret;122}123 124template <typename _Tp>125_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(126 volatile __cxx_atomic_base_impl<_Tp>* __a,127 _Tp* __expected,128 _Tp __value,129 memory_order __success,130 memory_order __failure) {131 return __atomic_compare_exchange(132 std::addressof(__a->__a_value),133 __expected,134 std::addressof(__value),135 false,136 __to_gcc_order(__success),137 __to_gcc_failure_order(__failure));138}139 140template <typename _Tp>141_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(142 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {143 return __atomic_compare_exchange(144 std::addressof(__a->__a_value),145 __expected,146 std::addressof(__value),147 false,148 __to_gcc_order(__success),149 __to_gcc_failure_order(__failure));150}151 152template <typename _Tp>153_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(154 volatile __cxx_atomic_base_impl<_Tp>* __a,155 _Tp* __expected,156 _Tp __value,157 memory_order __success,158 memory_order __failure) {159 return __atomic_compare_exchange(160 std::addressof(__a->__a_value),161 __expected,162 std::addressof(__value),163 true,164 __to_gcc_order(__success),165 __to_gcc_failure_order(__failure));166}167 168template <typename _Tp>169_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(170 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {171 return __atomic_compare_exchange(172 std::addressof(__a->__a_value),173 __expected,174 std::addressof(__value),175 true,176 __to_gcc_order(__success),177 __to_gcc_failure_order(__failure));178}179 180template <typename _Tp>181struct __skip_amt {182 enum { value = 1 };183};184 185template <typename _Tp>186struct __skip_amt<_Tp*> {187 enum { value = sizeof(_Tp) };188};189 190// FIXME: Haven't figured out what the spec says about using arrays with191// atomic_fetch_add. Force a failure rather than creating bad behavior.192template <typename _Tp>193struct __skip_amt<_Tp[]> {};194template <typename _Tp, int n>195struct __skip_amt<_Tp[n]> {};196 197template <typename _Tp, typename _Td>198_LIBCPP_HIDE_FROM_ABI _Tp199__cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {200 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));201}202 203template <typename _Tp, typename _Td>204_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {205 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));206}207 208template <typename _Tp, typename _Td>209_LIBCPP_HIDE_FROM_ABI _Tp210__cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {211 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));212}213 214template <typename _Tp, typename _Td>215_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {216 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));217}218 219template <typename _Tp>220_LIBCPP_HIDE_FROM_ABI _Tp221__cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {222 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));223}224 225template <typename _Tp>226_LIBCPP_HIDE_FROM_ABI _Tp227__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {228 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));229}230 231template <typename _Tp>232_LIBCPP_HIDE_FROM_ABI _Tp233__cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {234 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));235}236 237template <typename _Tp>238_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {239 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));240}241 242template <typename _Tp>243_LIBCPP_HIDE_FROM_ABI _Tp244__cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {245 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));246}247 248template <typename _Tp>249_LIBCPP_HIDE_FROM_ABI _Tp250__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {251 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));252}253 254# define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)255 256#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)257 258template <typename _Tp>259struct __cxx_atomic_base_impl {260 _LIBCPP_HIDE_FROM_ABI __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}261 explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {}262 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;263};264 265# define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)266 267_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {268 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));269}270 271_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {272 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));273}274 275template <class _Tp>276_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {277 __c11_atomic_init(std::addressof(__a->__a_value), __val);278}279template <class _Tp>280_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT {281 __c11_atomic_init(std::addressof(__a->__a_value), __val);282}283 284template <class _Tp>285_LIBCPP_HIDE_FROM_ABI void286__cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {287 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));288}289template <class _Tp>290_LIBCPP_HIDE_FROM_ABI void291__cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT {292 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));293}294 295template <class _Tp>296_LIBCPP_HIDE_FROM_ABI _Tp297__cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {298 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;299 return __c11_atomic_load(300 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));301}302template <class _Tp>303_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {304 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;305 return __c11_atomic_load(306 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));307}308 309template <class _Tp>310_LIBCPP_HIDE_FROM_ABI void311__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {312 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;313 *__dst = __c11_atomic_load(314 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));315}316template <class _Tp>317_LIBCPP_HIDE_FROM_ABI void318__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {319 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;320 *__dst = __c11_atomic_load(321 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));322}323 324template <class _Tp>325_LIBCPP_HIDE_FROM_ABI _Tp326__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {327 return __c11_atomic_exchange(328 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));329}330template <class _Tp>331_LIBCPP_HIDE_FROM_ABI _Tp332__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT {333 return __c11_atomic_exchange(334 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));335}336 337_LIBCPP_HIDE_FROM_ABI inline memory_order __to_failure_order(memory_order __order) {338 // Avoid switch statement to make this a constexpr.339 return __order == memory_order_release340 ? memory_order_relaxed341 : (__order == memory_order_acq_rel ? memory_order_acquire : __order);342}343 344template <class _Tp>345_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(346 __cxx_atomic_base_impl<_Tp> volatile* __a,347 _Tp* __expected,348 _Tp __value,349 memory_order __success,350 memory_order __failure) _NOEXCEPT {351 return __c11_atomic_compare_exchange_strong(352 std::addressof(__a->__a_value),353 __expected,354 __value,355 static_cast<__memory_order_underlying_t>(__success),356 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));357}358template <class _Tp>359_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(360 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)361 _NOEXCEPT {362 return __c11_atomic_compare_exchange_strong(363 std::addressof(__a->__a_value),364 __expected,365 __value,366 static_cast<__memory_order_underlying_t>(__success),367 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));368}369 370template <class _Tp>371_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(372 __cxx_atomic_base_impl<_Tp> volatile* __a,373 _Tp* __expected,374 _Tp __value,375 memory_order __success,376 memory_order __failure) _NOEXCEPT {377 return __c11_atomic_compare_exchange_weak(378 std::addressof(__a->__a_value),379 __expected,380 __value,381 static_cast<__memory_order_underlying_t>(__success),382 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));383}384template <class _Tp>385_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(386 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)387 _NOEXCEPT {388 return __c11_atomic_compare_exchange_weak(389 std::addressof(__a->__a_value),390 __expected,391 __value,392 static_cast<__memory_order_underlying_t>(__success),393 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));394}395 396template <class _Tp>397_LIBCPP_HIDE_FROM_ABI _Tp398__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {399 return __c11_atomic_fetch_add(400 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));401}402template <class _Tp>403_LIBCPP_HIDE_FROM_ABI _Tp404__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {405 return __c11_atomic_fetch_add(406 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));407}408 409template <class _Tp>410_LIBCPP_HIDE_FROM_ABI _Tp*411__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {412 return __c11_atomic_fetch_add(413 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));414}415template <class _Tp>416_LIBCPP_HIDE_FROM_ABI _Tp*417__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {418 return __c11_atomic_fetch_add(419 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));420}421 422template <class _Tp>423_LIBCPP_HIDE_FROM_ABI _Tp424__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {425 return __c11_atomic_fetch_sub(426 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));427}428template <class _Tp>429_LIBCPP_HIDE_FROM_ABI _Tp430__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {431 return __c11_atomic_fetch_sub(432 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));433}434template <class _Tp>435_LIBCPP_HIDE_FROM_ABI _Tp*436__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {437 return __c11_atomic_fetch_sub(438 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));439}440template <class _Tp>441_LIBCPP_HIDE_FROM_ABI _Tp*442__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {443 return __c11_atomic_fetch_sub(444 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));445}446 447template <class _Tp>448_LIBCPP_HIDE_FROM_ABI _Tp449__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {450 return __c11_atomic_fetch_and(451 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));452}453template <class _Tp>454_LIBCPP_HIDE_FROM_ABI _Tp455__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {456 return __c11_atomic_fetch_and(457 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));458}459 460template <class _Tp>461_LIBCPP_HIDE_FROM_ABI _Tp462__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {463 return __c11_atomic_fetch_or(464 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));465}466template <class _Tp>467_LIBCPP_HIDE_FROM_ABI _Tp468__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {469 return __c11_atomic_fetch_or(470 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));471}472 473template <class _Tp>474_LIBCPP_HIDE_FROM_ABI _Tp475__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {476 return __c11_atomic_fetch_xor(477 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));478}479template <class _Tp>480_LIBCPP_HIDE_FROM_ABI _Tp481__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {482 return __c11_atomic_fetch_xor(483 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));484}485 486#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP487 488template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >489struct __cxx_atomic_impl : public _Base {490 static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");491 492 _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;493 _LIBCPP_HIDE_FROM_ABI explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}494};495 496_LIBCPP_END_NAMESPACE_STD497 498#endif // _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H499