Revert "[libc] Use best-fit binary trie to make malloc logarithmic" (#117065)
[llvm-project.git] / libcxx / include / __atomic / cxx_atomic_impl.h
blobacffb0fa8f5d9fb7a1711a9601a474b2d2358490
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 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
10 #define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H
12 #include <__atomic/memory_order.h>
13 #include <__atomic/to_gcc_order.h>
14 #include <__config>
15 #include <__cstddef/ptrdiff_t.h>
16 #include <__memory/addressof.h>
17 #include <__type_traits/enable_if.h>
18 #include <__type_traits/is_assignable.h>
19 #include <__type_traits/is_trivially_copyable.h>
20 #include <__type_traits/remove_const.h>
22 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
23 # pragma GCC system_header
24 #endif
26 _LIBCPP_BEGIN_NAMESPACE_STD
28 #if _LIBCPP_HAS_GCC_ATOMIC_IMP
30 // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
31 // the default operator= in an object is not volatile, a byte-by-byte copy
32 // is required.
33 template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>
34 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
35 __a_value = __val;
37 template <typename _Tp, typename _Tv, __enable_if_t<is_assignable<_Tp&, _Tv>::value, int> = 0>
38 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
39 volatile char* __to = reinterpret_cast<volatile char*>(std::addressof(__a_value));
40 volatile char* __end = __to + sizeof(_Tp);
41 volatile const char* __from = reinterpret_cast<volatile const char*>(std::addressof(__val));
42 while (__to != __end)
43 *__to++ = *__from++;
46 template <typename _Tp>
47 struct __cxx_atomic_base_impl {
48 _LIBCPP_HIDE_FROM_ABI
49 # ifndef _LIBCPP_CXX03_LANG
50 __cxx_atomic_base_impl() _NOEXCEPT = default;
51 # else
52 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {
54 # endif // _LIBCPP_CXX03_LANG
55 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {}
56 _Tp __a_value;
59 template <typename _Tp>
60 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
61 __cxx_atomic_assign_volatile(__a->__a_value, __val);
64 template <typename _Tp>
65 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
66 __a->__a_value = __val;
69 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) {
70 __atomic_thread_fence(__to_gcc_order(__order));
73 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) {
74 __atomic_signal_fence(__to_gcc_order(__order));
77 template <typename _Tp>
78 _LIBCPP_HIDE_FROM_ABI void
79 __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {
80 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
83 template <typename _Tp>
84 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) {
85 __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order));
88 template <typename _Tp>
89 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
90 _Tp __ret;
91 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
92 return __ret;
95 template <typename _Tp>
96 _LIBCPP_HIDE_FROM_ABI void
97 __cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {
98 __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));
101 template <typename _Tp>
102 _LIBCPP_HIDE_FROM_ABI void
103 __cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) {
104 __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order));
107 template <typename _Tp>
108 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
109 _Tp __ret;
110 __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order));
111 return __ret;
114 template <typename _Tp>
115 _LIBCPP_HIDE_FROM_ABI _Tp
116 __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {
117 _Tp __ret;
118 __atomic_exchange(
119 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
120 return __ret;
123 template <typename _Tp>
124 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) {
125 _Tp __ret;
126 __atomic_exchange(
127 std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order));
128 return __ret;
131 template <typename _Tp>
132 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
133 volatile __cxx_atomic_base_impl<_Tp>* __a,
134 _Tp* __expected,
135 _Tp __value,
136 memory_order __success,
137 memory_order __failure) {
138 return __atomic_compare_exchange(
139 std::addressof(__a->__a_value),
140 __expected,
141 std::addressof(__value),
142 false,
143 __to_gcc_order(__success),
144 __to_gcc_failure_order(__failure));
147 template <typename _Tp>
148 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
149 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {
150 return __atomic_compare_exchange(
151 std::addressof(__a->__a_value),
152 __expected,
153 std::addressof(__value),
154 false,
155 __to_gcc_order(__success),
156 __to_gcc_failure_order(__failure));
159 template <typename _Tp>
160 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
161 volatile __cxx_atomic_base_impl<_Tp>* __a,
162 _Tp* __expected,
163 _Tp __value,
164 memory_order __success,
165 memory_order __failure) {
166 return __atomic_compare_exchange(
167 std::addressof(__a->__a_value),
168 __expected,
169 std::addressof(__value),
170 true,
171 __to_gcc_order(__success),
172 __to_gcc_failure_order(__failure));
175 template <typename _Tp>
176 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
177 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) {
178 return __atomic_compare_exchange(
179 std::addressof(__a->__a_value),
180 __expected,
181 std::addressof(__value),
182 true,
183 __to_gcc_order(__success),
184 __to_gcc_failure_order(__failure));
187 template <typename _Tp>
188 struct __skip_amt {
189 enum { value = 1 };
192 template <typename _Tp>
193 struct __skip_amt<_Tp*> {
194 enum { value = sizeof(_Tp) };
197 // FIXME: Haven't figured out what the spec says about using arrays with
198 // atomic_fetch_add. Force a failure rather than creating bad behavior.
199 template <typename _Tp>
200 struct __skip_amt<_Tp[]> {};
201 template <typename _Tp, int n>
202 struct __skip_amt<_Tp[n]> {};
204 template <typename _Tp, typename _Td>
205 _LIBCPP_HIDE_FROM_ABI _Tp
206 __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
207 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
210 template <typename _Tp, typename _Td>
211 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
212 return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
215 template <typename _Tp, typename _Td>
216 _LIBCPP_HIDE_FROM_ABI _Tp
217 __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
218 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
221 template <typename _Tp, typename _Td>
222 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) {
223 return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order));
226 template <typename _Tp>
227 _LIBCPP_HIDE_FROM_ABI _Tp
228 __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
229 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
232 template <typename _Tp>
233 _LIBCPP_HIDE_FROM_ABI _Tp
234 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
235 return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
238 template <typename _Tp>
239 _LIBCPP_HIDE_FROM_ABI _Tp
240 __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
241 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
244 template <typename _Tp>
245 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
246 return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
249 template <typename _Tp>
250 _LIBCPP_HIDE_FROM_ABI _Tp
251 __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
252 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
255 template <typename _Tp>
256 _LIBCPP_HIDE_FROM_ABI _Tp
257 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) {
258 return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order));
261 # define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
263 #elif _LIBCPP_HAS_C_ATOMIC_IMP
265 template <typename _Tp>
266 struct __cxx_atomic_base_impl {
267 _LIBCPP_HIDE_FROM_ABI
268 # ifndef _LIBCPP_CXX03_LANG
269 __cxx_atomic_base_impl() _NOEXCEPT = default;
270 # else
271 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {
273 # endif // _LIBCPP_CXX03_LANG
274 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {}
275 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
278 # define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
280 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
281 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
284 _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
285 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
288 template <class _Tp>
289 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
290 __c11_atomic_init(std::addressof(__a->__a_value), __val);
292 template <class _Tp>
293 _LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT {
294 __c11_atomic_init(std::addressof(__a->__a_value), __val);
297 template <class _Tp>
298 _LIBCPP_HIDE_FROM_ABI void
299 __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
300 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
302 template <class _Tp>
303 _LIBCPP_HIDE_FROM_ABI void
304 __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT {
305 __c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
308 template <class _Tp>
309 _LIBCPP_HIDE_FROM_ABI _Tp
310 __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
311 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
312 return __c11_atomic_load(
313 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
315 template <class _Tp>
316 _LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
317 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
318 return __c11_atomic_load(
319 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
322 template <class _Tp>
323 _LIBCPP_HIDE_FROM_ABI void
324 __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
325 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
326 *__dst = __c11_atomic_load(
327 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
329 template <class _Tp>
330 _LIBCPP_HIDE_FROM_ABI void
331 __cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
332 using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
333 *__dst = __c11_atomic_load(
334 const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
337 template <class _Tp>
338 _LIBCPP_HIDE_FROM_ABI _Tp
339 __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
340 return __c11_atomic_exchange(
341 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
343 template <class _Tp>
344 _LIBCPP_HIDE_FROM_ABI _Tp
345 __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT {
346 return __c11_atomic_exchange(
347 std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
350 _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
351 // Avoid switch statement to make this a constexpr.
352 return __order == memory_order_release
353 ? memory_order_relaxed
354 : (__order == memory_order_acq_rel ? memory_order_acquire : __order);
357 template <class _Tp>
358 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
359 __cxx_atomic_base_impl<_Tp> volatile* __a,
360 _Tp* __expected,
361 _Tp __value,
362 memory_order __success,
363 memory_order __failure) _NOEXCEPT {
364 return __c11_atomic_compare_exchange_strong(
365 std::addressof(__a->__a_value),
366 __expected,
367 __value,
368 static_cast<__memory_order_underlying_t>(__success),
369 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
371 template <class _Tp>
372 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
373 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
374 _NOEXCEPT {
375 return __c11_atomic_compare_exchange_strong(
376 std::addressof(__a->__a_value),
377 __expected,
378 __value,
379 static_cast<__memory_order_underlying_t>(__success),
380 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
383 template <class _Tp>
384 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
385 __cxx_atomic_base_impl<_Tp> volatile* __a,
386 _Tp* __expected,
387 _Tp __value,
388 memory_order __success,
389 memory_order __failure) _NOEXCEPT {
390 return __c11_atomic_compare_exchange_weak(
391 std::addressof(__a->__a_value),
392 __expected,
393 __value,
394 static_cast<__memory_order_underlying_t>(__success),
395 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
397 template <class _Tp>
398 _LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
399 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
400 _NOEXCEPT {
401 return __c11_atomic_compare_exchange_weak(
402 std::addressof(__a->__a_value),
403 __expected,
404 __value,
405 static_cast<__memory_order_underlying_t>(__success),
406 static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
409 template <class _Tp>
410 _LIBCPP_HIDE_FROM_ABI _Tp
411 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __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));
415 template <class _Tp>
416 _LIBCPP_HIDE_FROM_ABI _Tp
417 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __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));
422 template <class _Tp>
423 _LIBCPP_HIDE_FROM_ABI _Tp*
424 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
425 return __c11_atomic_fetch_add(
426 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
428 template <class _Tp>
429 _LIBCPP_HIDE_FROM_ABI _Tp*
430 __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
431 return __c11_atomic_fetch_add(
432 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
435 template <class _Tp>
436 _LIBCPP_HIDE_FROM_ABI _Tp
437 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
438 return __c11_atomic_fetch_sub(
439 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
441 template <class _Tp>
442 _LIBCPP_HIDE_FROM_ABI _Tp
443 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
444 return __c11_atomic_fetch_sub(
445 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
447 template <class _Tp>
448 _LIBCPP_HIDE_FROM_ABI _Tp*
449 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
450 return __c11_atomic_fetch_sub(
451 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
453 template <class _Tp>
454 _LIBCPP_HIDE_FROM_ABI _Tp*
455 __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
456 return __c11_atomic_fetch_sub(
457 std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
460 template <class _Tp>
461 _LIBCPP_HIDE_FROM_ABI _Tp
462 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
463 return __c11_atomic_fetch_and(
464 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
466 template <class _Tp>
467 _LIBCPP_HIDE_FROM_ABI _Tp
468 __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
469 return __c11_atomic_fetch_and(
470 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
473 template <class _Tp>
474 _LIBCPP_HIDE_FROM_ABI _Tp
475 __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
476 return __c11_atomic_fetch_or(
477 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
479 template <class _Tp>
480 _LIBCPP_HIDE_FROM_ABI _Tp
481 __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
482 return __c11_atomic_fetch_or(
483 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
486 template <class _Tp>
487 _LIBCPP_HIDE_FROM_ABI _Tp
488 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
489 return __c11_atomic_fetch_xor(
490 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
492 template <class _Tp>
493 _LIBCPP_HIDE_FROM_ABI _Tp
494 __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
495 return __c11_atomic_fetch_xor(
496 std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
499 #endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
501 template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >
502 struct __cxx_atomic_impl : public _Base {
503 static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");
505 _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
506 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}
509 _LIBCPP_END_NAMESPACE_STD
511 #endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H