xref: /freebsd/contrib/llvm-project/libcxx/include/__cxx03/__atomic/atomic.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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___CXX03___ATOMIC_ATOMIC_H
10 #define _LIBCPP___CXX03___ATOMIC_ATOMIC_H
11 
12 #include <__cxx03/__atomic/atomic_base.h>
13 #include <__cxx03/__atomic/check_memory_order.h>
14 #include <__cxx03/__atomic/cxx_atomic_impl.h>
15 #include <__cxx03/__atomic/memory_order.h>
16 #include <__cxx03/__config>
17 #include <__cxx03/__functional/operations.h>
18 #include <__cxx03/__memory/addressof.h>
19 #include <__cxx03/__type_traits/is_floating_point.h>
20 #include <__cxx03/__type_traits/is_function.h>
21 #include <__cxx03/__type_traits/is_same.h>
22 #include <__cxx03/__type_traits/remove_const.h>
23 #include <__cxx03/__type_traits/remove_pointer.h>
24 #include <__cxx03/__type_traits/remove_volatile.h>
25 #include <__cxx03/__utility/forward.h>
26 #include <__cxx03/cstddef>
27 #include <__cxx03/cstring>
28 
29 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30 #  pragma GCC system_header
31 #endif
32 
33 _LIBCPP_BEGIN_NAMESPACE_STD
34 
35 template <class _Tp>
36 struct atomic : public __atomic_base<_Tp> {
37   using __base          = __atomic_base<_Tp>;
38   using value_type      = _Tp;
39   using difference_type = value_type;
40 
41   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
42 
atomicatomic43   _LIBCPP_HIDE_FROM_ABI atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
44 
45   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile _NOEXCEPT {
46     __base::store(__d);
47     return __d;
48   }
49   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) _NOEXCEPT {
50     __base::store(__d);
51     return __d;
52   }
53 
54   atomic& operator=(const atomic&)          = delete;
55   atomic& operator=(const atomic&) volatile = delete;
56 };
57 
58 // atomic<T*>
59 
60 template <class _Tp>
61 struct atomic<_Tp*> : public __atomic_base<_Tp*> {
62   using __base          = __atomic_base<_Tp*>;
63   using value_type      = _Tp*;
64   using difference_type = ptrdiff_t;
65 
66   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
67 
68   _LIBCPP_HIDE_FROM_ABI atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
69 
70   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) volatile _NOEXCEPT {
71     __base::store(__d);
72     return __d;
73   }
74   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) _NOEXCEPT {
75     __base::store(__d);
76     return __d;
77   }
78 
79   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
80     // __atomic_fetch_add accepts function pointers, guard against them.
81     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
82     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
83   }
84 
85   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
86     // __atomic_fetch_add accepts function pointers, guard against them.
87     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
88     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
89   }
90 
91   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
92     // __atomic_fetch_add accepts function pointers, guard against them.
93     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
94     return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
95   }
96 
97   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _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 _Tp* operator++(int) volatile _NOEXCEPT { return fetch_add(1); }
104   _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) _NOEXCEPT { return fetch_add(1); }
105   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) volatile _NOEXCEPT { return fetch_sub(1); }
106   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) _NOEXCEPT { return fetch_sub(1); }
107   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() volatile _NOEXCEPT { return fetch_add(1) + 1; }
108   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() _NOEXCEPT { return fetch_add(1) + 1; }
109   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() volatile _NOEXCEPT { return fetch_sub(1) - 1; }
110   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() _NOEXCEPT { return fetch_sub(1) - 1; }
111   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }
112   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT { return fetch_add(__op) + __op; }
113   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }
114   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT { return fetch_sub(__op) - __op; }
115 
116   atomic& operator=(const atomic&)          = delete;
117   atomic& operator=(const atomic&) volatile = delete;
118 };
119 
120 // atomic_is_lock_free
121 
122 template <class _Tp>
123 _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
124   return __o->is_lock_free();
125 }
126 
127 template <class _Tp>
128 _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
129   return __o->is_lock_free();
130 }
131 
132 // atomic_init
133 
134 template <class _Tp>
135 _LIBCPP_HIDE_FROM_ABI void atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
136   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
137 }
138 
139 template <class _Tp>
140 _LIBCPP_HIDE_FROM_ABI void atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
141   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
142 }
143 
144 // atomic_store
145 
146 template <class _Tp>
147 _LIBCPP_HIDE_FROM_ABI void atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
148   __o->store(__d);
149 }
150 
151 template <class _Tp>
152 _LIBCPP_HIDE_FROM_ABI void atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
153   __o->store(__d);
154 }
155 
156 // atomic_store_explicit
157 
158 template <class _Tp>
159 _LIBCPP_HIDE_FROM_ABI void
160 atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
161     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
162   __o->store(__d, __m);
163 }
164 
165 template <class _Tp>
166 _LIBCPP_HIDE_FROM_ABI void
167 atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
168     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
169   __o->store(__d, __m);
170 }
171 
172 // atomic_load
173 
174 template <class _Tp>
175 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
176   return __o->load();
177 }
178 
179 template <class _Tp>
180 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
181   return __o->load();
182 }
183 
184 // atomic_load_explicit
185 
186 template <class _Tp>
187 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
188     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
189   return __o->load(__m);
190 }
191 
192 template <class _Tp>
193 _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
194     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
195   return __o->load(__m);
196 }
197 
198 // atomic_exchange
199 
200 template <class _Tp>
201 _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
202   return __o->exchange(__d);
203 }
204 
205 template <class _Tp>
206 _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
207   return __o->exchange(__d);
208 }
209 
210 // atomic_exchange_explicit
211 
212 template <class _Tp>
213 _LIBCPP_HIDE_FROM_ABI _Tp
214 atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
215   return __o->exchange(__d, __m);
216 }
217 
218 template <class _Tp>
219 _LIBCPP_HIDE_FROM_ABI _Tp
220 atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
221   return __o->exchange(__d, __m);
222 }
223 
224 // atomic_compare_exchange_weak
225 
226 template <class _Tp>
227 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
228     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
229   return __o->compare_exchange_weak(*__e, __d);
230 }
231 
232 template <class _Tp>
233 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
234     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
235   return __o->compare_exchange_weak(*__e, __d);
236 }
237 
238 // atomic_compare_exchange_strong
239 
240 template <class _Tp>
241 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
242     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
243   return __o->compare_exchange_strong(*__e, __d);
244 }
245 
246 template <class _Tp>
247 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
248     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
249   return __o->compare_exchange_strong(*__e, __d);
250 }
251 
252 // atomic_compare_exchange_weak_explicit
253 
254 template <class _Tp>
255 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
256     volatile atomic<_Tp>* __o,
257     typename atomic<_Tp>::value_type* __e,
258     typename atomic<_Tp>::value_type __d,
259     memory_order __s,
260     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
261   return __o->compare_exchange_weak(*__e, __d, __s, __f);
262 }
263 
264 template <class _Tp>
265 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
266     atomic<_Tp>* __o,
267     typename atomic<_Tp>::value_type* __e,
268     typename atomic<_Tp>::value_type __d,
269     memory_order __s,
270     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
271   return __o->compare_exchange_weak(*__e, __d, __s, __f);
272 }
273 
274 // atomic_compare_exchange_strong_explicit
275 
276 template <class _Tp>
277 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
278     volatile atomic<_Tp>* __o,
279     typename atomic<_Tp>::value_type* __e,
280     typename atomic<_Tp>::value_type __d,
281     memory_order __s,
282     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
283   return __o->compare_exchange_strong(*__e, __d, __s, __f);
284 }
285 
286 template <class _Tp>
287 _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
288     atomic<_Tp>* __o,
289     typename atomic<_Tp>::value_type* __e,
290     typename atomic<_Tp>::value_type __d,
291     memory_order __s,
292     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
293   return __o->compare_exchange_strong(*__e, __d, __s, __f);
294 }
295 
296 // atomic_wait
297 
298 template <class _Tp>
299 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
300 atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
301   return __o->wait(__v);
302 }
303 
304 template <class _Tp>
305 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
306 atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
307   return __o->wait(__v);
308 }
309 
310 // atomic_wait_explicit
311 
312 template <class _Tp>
313 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
314 atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
315     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
316   return __o->wait(__v, __m);
317 }
318 
319 template <class _Tp>
320 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
321 atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
322     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
323   return __o->wait(__v, __m);
324 }
325 
326 // atomic_notify_one
327 
328 template <class _Tp>
329 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
330 atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
331   __o->notify_one();
332 }
333 template <class _Tp>
334 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
335 atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
336   __o->notify_one();
337 }
338 
339 // atomic_notify_all
340 
341 template <class _Tp>
342 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
343 atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
344   __o->notify_all();
345 }
346 template <class _Tp>
347 _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
348 atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
349   __o->notify_all();
350 }
351 
352 // atomic_fetch_add
353 
354 template <class _Tp>
355 _LIBCPP_HIDE_FROM_ABI _Tp
356 atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
357   return __o->fetch_add(__op);
358 }
359 
360 template <class _Tp>
361 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
362   return __o->fetch_add(__op);
363 }
364 
365 // atomic_fetch_add_explicit
366 
367 template <class _Tp>
368 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add_explicit(
369     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
370   return __o->fetch_add(__op, __m);
371 }
372 
373 template <class _Tp>
374 _LIBCPP_HIDE_FROM_ABI _Tp
375 atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
376   return __o->fetch_add(__op, __m);
377 }
378 
379 // atomic_fetch_sub
380 
381 template <class _Tp>
382 _LIBCPP_HIDE_FROM_ABI _Tp
383 atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
384   return __o->fetch_sub(__op);
385 }
386 
387 template <class _Tp>
388 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
389   return __o->fetch_sub(__op);
390 }
391 
392 // atomic_fetch_sub_explicit
393 
394 template <class _Tp>
395 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub_explicit(
396     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
397   return __o->fetch_sub(__op, __m);
398 }
399 
400 template <class _Tp>
401 _LIBCPP_HIDE_FROM_ABI _Tp
402 atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
403   return __o->fetch_sub(__op, __m);
404 }
405 
406 // atomic_fetch_and
407 
408 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
409 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
410   return __o->fetch_and(__op);
411 }
412 
413 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
414 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
415   return __o->fetch_and(__op);
416 }
417 
418 // atomic_fetch_and_explicit
419 
420 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
421 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and_explicit(
422     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
423   return __o->fetch_and(__op, __m);
424 }
425 
426 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
427 _LIBCPP_HIDE_FROM_ABI _Tp
428 atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
429   return __o->fetch_and(__op, __m);
430 }
431 
432 // atomic_fetch_or
433 
434 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
435 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
436   return __o->fetch_or(__op);
437 }
438 
439 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
440 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
441   return __o->fetch_or(__op);
442 }
443 
444 // atomic_fetch_or_explicit
445 
446 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
447 _LIBCPP_HIDE_FROM_ABI _Tp
448 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
449   return __o->fetch_or(__op, __m);
450 }
451 
452 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
453 _LIBCPP_HIDE_FROM_ABI _Tp
454 atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
455   return __o->fetch_or(__op, __m);
456 }
457 
458 // atomic_fetch_xor
459 
460 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
461 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
462   return __o->fetch_xor(__op);
463 }
464 
465 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
466 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
467   return __o->fetch_xor(__op);
468 }
469 
470 // atomic_fetch_xor_explicit
471 
472 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
473 _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor_explicit(
474     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
475   return __o->fetch_xor(__op, __m);
476 }
477 
478 template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
479 _LIBCPP_HIDE_FROM_ABI _Tp
480 atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
481   return __o->fetch_xor(__op, __m);
482 }
483 
484 _LIBCPP_END_NAMESPACE_STD
485 
486 #endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_H
487