3// Copyright (C) 2008-2023 Free Software Foundation, Inc.
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
25/** @file include/atomic
26 * This is a Standard C++ Library header.
29// Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
30// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
32#ifndef _GLIBCXX_ATOMIC
33#define _GLIBCXX_ATOMIC 1
35#pragma GCC system_header
37#if __cplusplus < 201103L
38# include <bits/c++0x_warning.h>
41#include <bits/atomic_base.h>
43namespace std _GLIBCXX_VISIBILITY(default)
45_GLIBCXX_BEGIN_NAMESPACE_VERSION
52#if __cplusplus >= 201703L
53# define __cpp_lib_atomic_is_always_lock_free 201603L
56 template<typename _Tp>
60 // NB: No operators or fetch-operations for this type.
64 using value_type = bool;
67 __atomic_base<bool> _M_base;
70 atomic() noexcept = default;
71 ~atomic() noexcept = default;
72 atomic(const atomic&) = delete;
73 atomic& operator=(const atomic&) = delete;
74 atomic& operator=(const atomic&) volatile = delete;
76 constexpr atomic(bool __i) noexcept : _M_base(__i) { }
79 operator=(bool __i) noexcept
80 { return _M_base.operator=(__i); }
83 operator=(bool __i) volatile noexcept
84 { return _M_base.operator=(__i); }
86 operator bool() const noexcept
87 { return _M_base.load(); }
89 operator bool() const volatile noexcept
90 { return _M_base.load(); }
93 is_lock_free() const noexcept { return _M_base.is_lock_free(); }
96 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
98#if __cplusplus >= 201703L
99 static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
103 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
104 { _M_base.store(__i, __m); }
107 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
108 { _M_base.store(__i, __m); }
111 load(memory_order __m = memory_order_seq_cst) const noexcept
112 { return _M_base.load(__m); }
115 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
116 { return _M_base.load(__m); }
119 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
120 { return _M_base.exchange(__i, __m); }
124 memory_order __m = memory_order_seq_cst) volatile noexcept
125 { return _M_base.exchange(__i, __m); }
128 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
129 memory_order __m2) noexcept
130 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
133 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
134 memory_order __m2) volatile noexcept
135 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
138 compare_exchange_weak(bool& __i1, bool __i2,
139 memory_order __m = memory_order_seq_cst) noexcept
140 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
143 compare_exchange_weak(bool& __i1, bool __i2,
144 memory_order __m = memory_order_seq_cst) volatile noexcept
145 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
148 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
149 memory_order __m2) noexcept
150 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
153 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
154 memory_order __m2) volatile noexcept
155 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
158 compare_exchange_strong(bool& __i1, bool __i2,
159 memory_order __m = memory_order_seq_cst) noexcept
160 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
163 compare_exchange_strong(bool& __i1, bool __i2,
164 memory_order __m = memory_order_seq_cst) volatile noexcept
165 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
167#if __cpp_lib_atomic_wait
169 wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
170 { _M_base.wait(__old, __m); }
172 // TODO add const volatile overload
175 notify_one() noexcept
176 { _M_base.notify_one(); }
179 notify_all() noexcept
180 { _M_base.notify_all(); }
181#endif // __cpp_lib_atomic_wait
184/// @cond undocumented
185#if __cpp_lib_atomic_value_initialization
186# define _GLIBCXX20_INIT(I) = I
188# define _GLIBCXX20_INIT(I)
193 * @brief Generic atomic type, primary class template.
195 * @tparam _Tp Type to be made atomic, must be trivially copyable.
197 template<typename _Tp>
200 using value_type = _Tp;
203 // Align 1/2/4/8/16-byte types to at least their size.
204 static constexpr int _S_min_alignment
205 = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
208 static constexpr int _S_alignment
209 = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
211 alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
213 static_assert(__is_trivially_copyable(_Tp),
214 "std::atomic requires a trivially copyable type");
216 static_assert(sizeof(_Tp) > 0,
217 "Incomplete or zero-sized types are not supported");
219#if __cplusplus > 201703L
220 static_assert(is_copy_constructible_v<_Tp>);
221 static_assert(is_move_constructible_v<_Tp>);
222 static_assert(is_copy_assignable_v<_Tp>);
223 static_assert(is_move_assignable_v<_Tp>);
228 ~atomic() noexcept = default;
229 atomic(const atomic&) = delete;
230 atomic& operator=(const atomic&) = delete;
231 atomic& operator=(const atomic&) volatile = delete;
233#pragma GCC diagnostic push
234#pragma GCC diagnostic ignored "-Wc++14-extensions" // constexpr ctor body
235 constexpr atomic(_Tp __i) noexcept : _M_i(__i)
237#if __has_builtin(__builtin_clear_padding)
238 if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>())
239 if (!std::__is_constant_evaluated())
240 __builtin_clear_padding(std::__addressof(_M_i));
243#pragma GCC diagnostic pop
245 operator _Tp() const noexcept
248 operator _Tp() const volatile noexcept
252 operator=(_Tp __i) noexcept
253 { store(__i); return __i; }
256 operator=(_Tp __i) volatile noexcept
257 { store(__i); return __i; }
260 is_lock_free() const noexcept
262 // Produce a fake, minimally aligned pointer.
263 return __atomic_is_lock_free(sizeof(_M_i),
264 reinterpret_cast<void *>(-_S_alignment));
268 is_lock_free() const volatile noexcept
270 // Produce a fake, minimally aligned pointer.
271 return __atomic_is_lock_free(sizeof(_M_i),
272 reinterpret_cast<void *>(-_S_alignment));
275#if __cplusplus >= 201703L
276 static constexpr bool is_always_lock_free
277 = __atomic_always_lock_free(sizeof(_M_i), 0);
281 store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
283 __atomic_store(std::__addressof(_M_i),
284 __atomic_impl::__clear_padding(__i),
289 store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
291 __atomic_store(std::__addressof(_M_i),
292 __atomic_impl::__clear_padding(__i),
297 load(memory_order __m = memory_order_seq_cst) const noexcept
299 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
300 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
301 __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
306 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
308 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
309 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
310 __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
315 exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
317 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
318 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
319 __atomic_exchange(std::__addressof(_M_i),
320 __atomic_impl::__clear_padding(__i),
327 memory_order __m = memory_order_seq_cst) volatile noexcept
329 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
330 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
331 __atomic_exchange(std::__addressof(_M_i),
332 __atomic_impl::__clear_padding(__i),
338 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
339 memory_order __f) noexcept
341 return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
346 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
347 memory_order __f) volatile noexcept
349 return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
354 compare_exchange_weak(_Tp& __e, _Tp __i,
355 memory_order __m = memory_order_seq_cst) noexcept
356 { return compare_exchange_weak(__e, __i, __m,
357 __cmpexch_failure_order(__m)); }
360 compare_exchange_weak(_Tp& __e, _Tp __i,
361 memory_order __m = memory_order_seq_cst) volatile noexcept
362 { return compare_exchange_weak(__e, __i, __m,
363 __cmpexch_failure_order(__m)); }
366 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
367 memory_order __f) noexcept
369 return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
374 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
375 memory_order __f) volatile noexcept
377 return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
382 compare_exchange_strong(_Tp& __e, _Tp __i,
383 memory_order __m = memory_order_seq_cst) noexcept
384 { return compare_exchange_strong(__e, __i, __m,
385 __cmpexch_failure_order(__m)); }
388 compare_exchange_strong(_Tp& __e, _Tp __i,
389 memory_order __m = memory_order_seq_cst) volatile noexcept
390 { return compare_exchange_strong(__e, __i, __m,
391 __cmpexch_failure_order(__m)); }
393#if __cpp_lib_atomic_wait
395 wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
397 std::__atomic_wait_address_v(std::addressof(_M_i), __old,
398 [__m, this] { return this->load(__m); });
401 // TODO add const volatile overload
404 notify_one() noexcept
405 { std::__atomic_notify_address(std::addressof(_M_i), false); }
408 notify_all() noexcept
409 { std::__atomic_notify_address(std::addressof(_M_i), true); }
410#endif // __cpp_lib_atomic_wait
412#undef _GLIBCXX20_INIT
414 /// Partial specialization for pointer types.
415 template<typename _Tp>
418 using value_type = _Tp*;
419 using difference_type = ptrdiff_t;
421 typedef _Tp* __pointer_type;
422 typedef __atomic_base<_Tp*> __base_type;
425 atomic() noexcept = default;
426 ~atomic() noexcept = default;
427 atomic(const atomic&) = delete;
428 atomic& operator=(const atomic&) = delete;
429 atomic& operator=(const atomic&) volatile = delete;
431 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
433 operator __pointer_type() const noexcept
434 { return __pointer_type(_M_b); }
436 operator __pointer_type() const volatile noexcept
437 { return __pointer_type(_M_b); }
440 operator=(__pointer_type __p) noexcept
441 { return _M_b.operator=(__p); }
444 operator=(__pointer_type __p) volatile noexcept
445 { return _M_b.operator=(__p); }
448 operator++(int) noexcept
450#if __cplusplus >= 201703L
451 static_assert( is_object<_Tp>::value, "pointer to object type" );
457 operator++(int) volatile noexcept
459#if __cplusplus >= 201703L
460 static_assert( is_object<_Tp>::value, "pointer to object type" );
466 operator--(int) noexcept
468#if __cplusplus >= 201703L
469 static_assert( is_object<_Tp>::value, "pointer to object type" );
475 operator--(int) volatile noexcept
477#if __cplusplus >= 201703L
478 static_assert( is_object<_Tp>::value, "pointer to object type" );
484 operator++() noexcept
486#if __cplusplus >= 201703L
487 static_assert( is_object<_Tp>::value, "pointer to object type" );
493 operator++() volatile noexcept
495#if __cplusplus >= 201703L
496 static_assert( is_object<_Tp>::value, "pointer to object type" );
502 operator--() noexcept
504#if __cplusplus >= 201703L
505 static_assert( is_object<_Tp>::value, "pointer to object type" );
511 operator--() volatile noexcept
513#if __cplusplus >= 201703L
514 static_assert( is_object<_Tp>::value, "pointer to object type" );
520 operator+=(ptrdiff_t __d) noexcept
522#if __cplusplus >= 201703L
523 static_assert( is_object<_Tp>::value, "pointer to object type" );
525 return _M_b.operator+=(__d);
529 operator+=(ptrdiff_t __d) volatile noexcept
531#if __cplusplus >= 201703L
532 static_assert( is_object<_Tp>::value, "pointer to object type" );
534 return _M_b.operator+=(__d);
538 operator-=(ptrdiff_t __d) noexcept
540#if __cplusplus >= 201703L
541 static_assert( is_object<_Tp>::value, "pointer to object type" );
543 return _M_b.operator-=(__d);
547 operator-=(ptrdiff_t __d) volatile noexcept
549#if __cplusplus >= 201703L
550 static_assert( is_object<_Tp>::value, "pointer to object type" );
552 return _M_b.operator-=(__d);
556 is_lock_free() const noexcept
557 { return _M_b.is_lock_free(); }
560 is_lock_free() const volatile noexcept
561 { return _M_b.is_lock_free(); }
563#if __cplusplus >= 201703L
564 static constexpr bool is_always_lock_free
565 = ATOMIC_POINTER_LOCK_FREE == 2;
569 store(__pointer_type __p,
570 memory_order __m = memory_order_seq_cst) noexcept
571 { return _M_b.store(__p, __m); }
574 store(__pointer_type __p,
575 memory_order __m = memory_order_seq_cst) volatile noexcept
576 { return _M_b.store(__p, __m); }
579 load(memory_order __m = memory_order_seq_cst) const noexcept
580 { return _M_b.load(__m); }
583 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
584 { return _M_b.load(__m); }
587 exchange(__pointer_type __p,
588 memory_order __m = memory_order_seq_cst) noexcept
589 { return _M_b.exchange(__p, __m); }
592 exchange(__pointer_type __p,
593 memory_order __m = memory_order_seq_cst) volatile noexcept
594 { return _M_b.exchange(__p, __m); }
597 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
598 memory_order __m1, memory_order __m2) noexcept
599 { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
602 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
604 memory_order __m2) volatile noexcept
605 { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
608 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
609 memory_order __m = memory_order_seq_cst) noexcept
611 return compare_exchange_weak(__p1, __p2, __m,
612 __cmpexch_failure_order(__m));
616 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
617 memory_order __m = memory_order_seq_cst) volatile noexcept
619 return compare_exchange_weak(__p1, __p2, __m,
620 __cmpexch_failure_order(__m));
624 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
625 memory_order __m1, memory_order __m2) noexcept
626 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
629 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
631 memory_order __m2) volatile noexcept
632 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
635 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
636 memory_order __m = memory_order_seq_cst) noexcept
638 return _M_b.compare_exchange_strong(__p1, __p2, __m,
639 __cmpexch_failure_order(__m));
643 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
644 memory_order __m = memory_order_seq_cst) volatile noexcept
646 return _M_b.compare_exchange_strong(__p1, __p2, __m,
647 __cmpexch_failure_order(__m));
650#if __cpp_lib_atomic_wait
652 wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
653 { _M_b.wait(__old, __m); }
655 // TODO add const volatile overload
658 notify_one() noexcept
659 { _M_b.notify_one(); }
662 notify_all() noexcept
663 { _M_b.notify_all(); }
664#endif // __cpp_lib_atomic_wait
667 fetch_add(ptrdiff_t __d,
668 memory_order __m = memory_order_seq_cst) noexcept
670#if __cplusplus >= 201703L
671 static_assert( is_object<_Tp>::value, "pointer to object type" );
673 return _M_b.fetch_add(__d, __m);
677 fetch_add(ptrdiff_t __d,
678 memory_order __m = memory_order_seq_cst) volatile noexcept
680#if __cplusplus >= 201703L
681 static_assert( is_object<_Tp>::value, "pointer to object type" );
683 return _M_b.fetch_add(__d, __m);
687 fetch_sub(ptrdiff_t __d,
688 memory_order __m = memory_order_seq_cst) noexcept
690#if __cplusplus >= 201703L
691 static_assert( is_object<_Tp>::value, "pointer to object type" );
693 return _M_b.fetch_sub(__d, __m);
697 fetch_sub(ptrdiff_t __d,
698 memory_order __m = memory_order_seq_cst) volatile noexcept
700#if __cplusplus >= 201703L
701 static_assert( is_object<_Tp>::value, "pointer to object type" );
703 return _M_b.fetch_sub(__d, __m);
708 /// Explicit specialization for char.
710 struct atomic<char> : __atomic_base<char>
712 typedef char __integral_type;
713 typedef __atomic_base<char> __base_type;
715 atomic() noexcept = default;
716 ~atomic() noexcept = default;
717 atomic(const atomic&) = delete;
718 atomic& operator=(const atomic&) = delete;
719 atomic& operator=(const atomic&) volatile = delete;
721 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
723 using __base_type::operator __integral_type;
724 using __base_type::operator=;
726#if __cplusplus >= 201703L
727 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
731 /// Explicit specialization for signed char.
733 struct atomic<signed char> : __atomic_base<signed char>
735 typedef signed char __integral_type;
736 typedef __atomic_base<signed char> __base_type;
738 atomic() noexcept= default;
739 ~atomic() noexcept = default;
740 atomic(const atomic&) = delete;
741 atomic& operator=(const atomic&) = delete;
742 atomic& operator=(const atomic&) volatile = delete;
744 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
746 using __base_type::operator __integral_type;
747 using __base_type::operator=;
749#if __cplusplus >= 201703L
750 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
754 /// Explicit specialization for unsigned char.
756 struct atomic<unsigned char> : __atomic_base<unsigned char>
758 typedef unsigned char __integral_type;
759 typedef __atomic_base<unsigned char> __base_type;
761 atomic() noexcept= default;
762 ~atomic() noexcept = default;
763 atomic(const atomic&) = delete;
764 atomic& operator=(const atomic&) = delete;
765 atomic& operator=(const atomic&) volatile = delete;
767 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
769 using __base_type::operator __integral_type;
770 using __base_type::operator=;
772#if __cplusplus >= 201703L
773 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
777 /// Explicit specialization for short.
779 struct atomic<short> : __atomic_base<short>
781 typedef short __integral_type;
782 typedef __atomic_base<short> __base_type;
784 atomic() noexcept = default;
785 ~atomic() noexcept = default;
786 atomic(const atomic&) = delete;
787 atomic& operator=(const atomic&) = delete;
788 atomic& operator=(const atomic&) volatile = delete;
790 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
792 using __base_type::operator __integral_type;
793 using __base_type::operator=;
795#if __cplusplus >= 201703L
796 static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
800 /// Explicit specialization for unsigned short.
802 struct atomic<unsigned short> : __atomic_base<unsigned short>
804 typedef unsigned short __integral_type;
805 typedef __atomic_base<unsigned short> __base_type;
807 atomic() noexcept = default;
808 ~atomic() noexcept = default;
809 atomic(const atomic&) = delete;
810 atomic& operator=(const atomic&) = delete;
811 atomic& operator=(const atomic&) volatile = delete;
813 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
815 using __base_type::operator __integral_type;
816 using __base_type::operator=;
818#if __cplusplus >= 201703L
819 static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
823 /// Explicit specialization for int.
825 struct atomic<int> : __atomic_base<int>
827 typedef int __integral_type;
828 typedef __atomic_base<int> __base_type;
830 atomic() noexcept = default;
831 ~atomic() noexcept = default;
832 atomic(const atomic&) = delete;
833 atomic& operator=(const atomic&) = delete;
834 atomic& operator=(const atomic&) volatile = delete;
836 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
838 using __base_type::operator __integral_type;
839 using __base_type::operator=;
841#if __cplusplus >= 201703L
842 static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
846 /// Explicit specialization for unsigned int.
848 struct atomic<unsigned int> : __atomic_base<unsigned int>
850 typedef unsigned int __integral_type;
851 typedef __atomic_base<unsigned int> __base_type;
853 atomic() noexcept = default;
854 ~atomic() noexcept = default;
855 atomic(const atomic&) = delete;
856 atomic& operator=(const atomic&) = delete;
857 atomic& operator=(const atomic&) volatile = delete;
859 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
861 using __base_type::operator __integral_type;
862 using __base_type::operator=;
864#if __cplusplus >= 201703L
865 static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
869 /// Explicit specialization for long.
871 struct atomic<long> : __atomic_base<long>
873 typedef long __integral_type;
874 typedef __atomic_base<long> __base_type;
876 atomic() noexcept = default;
877 ~atomic() noexcept = default;
878 atomic(const atomic&) = delete;
879 atomic& operator=(const atomic&) = delete;
880 atomic& operator=(const atomic&) volatile = delete;
882 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
884 using __base_type::operator __integral_type;
885 using __base_type::operator=;
887#if __cplusplus >= 201703L
888 static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
892 /// Explicit specialization for unsigned long.
894 struct atomic<unsigned long> : __atomic_base<unsigned long>
896 typedef unsigned long __integral_type;
897 typedef __atomic_base<unsigned long> __base_type;
899 atomic() noexcept = default;
900 ~atomic() noexcept = default;
901 atomic(const atomic&) = delete;
902 atomic& operator=(const atomic&) = delete;
903 atomic& operator=(const atomic&) volatile = delete;
905 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
907 using __base_type::operator __integral_type;
908 using __base_type::operator=;
910#if __cplusplus >= 201703L
911 static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
915 /// Explicit specialization for long long.
917 struct atomic<long long> : __atomic_base<long long>
919 typedef long long __integral_type;
920 typedef __atomic_base<long long> __base_type;
922 atomic() noexcept = default;
923 ~atomic() noexcept = default;
924 atomic(const atomic&) = delete;
925 atomic& operator=(const atomic&) = delete;
926 atomic& operator=(const atomic&) volatile = delete;
928 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
930 using __base_type::operator __integral_type;
931 using __base_type::operator=;
933#if __cplusplus >= 201703L
934 static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
938 /// Explicit specialization for unsigned long long.
940 struct atomic<unsigned long long> : __atomic_base<unsigned long long>
942 typedef unsigned long long __integral_type;
943 typedef __atomic_base<unsigned long long> __base_type;
945 atomic() noexcept = default;
946 ~atomic() noexcept = default;
947 atomic(const atomic&) = delete;
948 atomic& operator=(const atomic&) = delete;
949 atomic& operator=(const atomic&) volatile = delete;
951 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
953 using __base_type::operator __integral_type;
954 using __base_type::operator=;
956#if __cplusplus >= 201703L
957 static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
961 /// Explicit specialization for wchar_t.
963 struct atomic<wchar_t> : __atomic_base<wchar_t>
965 typedef wchar_t __integral_type;
966 typedef __atomic_base<wchar_t> __base_type;
968 atomic() noexcept = default;
969 ~atomic() noexcept = default;
970 atomic(const atomic&) = delete;
971 atomic& operator=(const atomic&) = delete;
972 atomic& operator=(const atomic&) volatile = delete;
974 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
976 using __base_type::operator __integral_type;
977 using __base_type::operator=;
979#if __cplusplus >= 201703L
980 static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
984#ifdef _GLIBCXX_USE_CHAR8_T
985 /// Explicit specialization for char8_t.
987 struct atomic<char8_t> : __atomic_base<char8_t>
989 typedef char8_t __integral_type;
990 typedef __atomic_base<char8_t> __base_type;
992 atomic() noexcept = default;
993 ~atomic() noexcept = default;
994 atomic(const atomic&) = delete;
995 atomic& operator=(const atomic&) = delete;
996 atomic& operator=(const atomic&) volatile = delete;
998 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1000 using __base_type::operator __integral_type;
1001 using __base_type::operator=;
1003#if __cplusplus > 201402L
1004 static constexpr bool is_always_lock_free
1005 = ATOMIC_CHAR8_T_LOCK_FREE == 2;
1010 /// Explicit specialization for char16_t.
1012 struct atomic<char16_t> : __atomic_base<char16_t>
1014 typedef char16_t __integral_type;
1015 typedef __atomic_base<char16_t> __base_type;
1017 atomic() noexcept = default;
1018 ~atomic() noexcept = default;
1019 atomic(const atomic&) = delete;
1020 atomic& operator=(const atomic&) = delete;
1021 atomic& operator=(const atomic&) volatile = delete;
1023 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1025 using __base_type::operator __integral_type;
1026 using __base_type::operator=;
1028#if __cplusplus >= 201703L
1029 static constexpr bool is_always_lock_free
1030 = ATOMIC_CHAR16_T_LOCK_FREE == 2;
1034 /// Explicit specialization for char32_t.
1036 struct atomic<char32_t> : __atomic_base<char32_t>
1038 typedef char32_t __integral_type;
1039 typedef __atomic_base<char32_t> __base_type;
1041 atomic() noexcept = default;
1042 ~atomic() noexcept = default;
1043 atomic(const atomic&) = delete;
1044 atomic& operator=(const atomic&) = delete;
1045 atomic& operator=(const atomic&) volatile = delete;
1047 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1049 using __base_type::operator __integral_type;
1050 using __base_type::operator=;
1052#if __cplusplus >= 201703L
1053 static constexpr bool is_always_lock_free
1054 = ATOMIC_CHAR32_T_LOCK_FREE == 2;
1060 typedef atomic<bool> atomic_bool;
1063 typedef atomic<char> atomic_char;
1066 typedef atomic<signed char> atomic_schar;
1069 typedef atomic<unsigned char> atomic_uchar;
1072 typedef atomic<short> atomic_short;
1075 typedef atomic<unsigned short> atomic_ushort;
1078 typedef atomic<int> atomic_int;
1081 typedef atomic<unsigned int> atomic_uint;
1084 typedef atomic<long> atomic_long;
1087 typedef atomic<unsigned long> atomic_ulong;
1090 typedef atomic<long long> atomic_llong;
1093 typedef atomic<unsigned long long> atomic_ullong;
1096 typedef atomic<wchar_t> atomic_wchar_t;
1098#ifdef _GLIBCXX_USE_CHAR8_T
1100 typedef atomic<char8_t> atomic_char8_t;
1104 typedef atomic<char16_t> atomic_char16_t;
1107 typedef atomic<char32_t> atomic_char32_t;
1109#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1111 // 2441. Exact-width atomic typedefs should be provided
1114 typedef atomic<int8_t> atomic_int8_t;
1117 typedef atomic<uint8_t> atomic_uint8_t;
1120 typedef atomic<int16_t> atomic_int16_t;
1123 typedef atomic<uint16_t> atomic_uint16_t;
1126 typedef atomic<int32_t> atomic_int32_t;
1129 typedef atomic<uint32_t> atomic_uint32_t;
1132 typedef atomic<int64_t> atomic_int64_t;
1135 typedef atomic<uint64_t> atomic_uint64_t;
1138 /// atomic_int_least8_t
1139 typedef atomic<int_least8_t> atomic_int_least8_t;
1141 /// atomic_uint_least8_t
1142 typedef atomic<uint_least8_t> atomic_uint_least8_t;
1144 /// atomic_int_least16_t
1145 typedef atomic<int_least16_t> atomic_int_least16_t;
1147 /// atomic_uint_least16_t
1148 typedef atomic<uint_least16_t> atomic_uint_least16_t;
1150 /// atomic_int_least32_t
1151 typedef atomic<int_least32_t> atomic_int_least32_t;
1153 /// atomic_uint_least32_t
1154 typedef atomic<uint_least32_t> atomic_uint_least32_t;
1156 /// atomic_int_least64_t
1157 typedef atomic<int_least64_t> atomic_int_least64_t;
1159 /// atomic_uint_least64_t
1160 typedef atomic<uint_least64_t> atomic_uint_least64_t;
1163 /// atomic_int_fast8_t
1164 typedef atomic<int_fast8_t> atomic_int_fast8_t;
1166 /// atomic_uint_fast8_t
1167 typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1169 /// atomic_int_fast16_t
1170 typedef atomic<int_fast16_t> atomic_int_fast16_t;
1172 /// atomic_uint_fast16_t
1173 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1175 /// atomic_int_fast32_t
1176 typedef atomic<int_fast32_t> atomic_int_fast32_t;
1178 /// atomic_uint_fast32_t
1179 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1181 /// atomic_int_fast64_t
1182 typedef atomic<int_fast64_t> atomic_int_fast64_t;
1184 /// atomic_uint_fast64_t
1185 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1190 typedef atomic<intptr_t> atomic_intptr_t;
1192 /// atomic_uintptr_t
1193 typedef atomic<uintptr_t> atomic_uintptr_t;
1196 typedef atomic<size_t> atomic_size_t;
1198 /// atomic_ptrdiff_t
1199 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1201#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1203 typedef atomic<intmax_t> atomic_intmax_t;
1205 /// atomic_uintmax_t
1206 typedef atomic<uintmax_t> atomic_uintmax_t;
1209 // Function definitions, atomic_flag operations.
1211 atomic_flag_test_and_set_explicit(atomic_flag* __a,
1212 memory_order __m) noexcept
1213 { return __a->test_and_set(__m); }
1216 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
1217 memory_order __m) noexcept
1218 { return __a->test_and_set(__m); }
1220#if __cpp_lib_atomic_flag_test
1222 atomic_flag_test(const atomic_flag* __a) noexcept
1223 { return __a->test(); }
1226 atomic_flag_test(const volatile atomic_flag* __a) noexcept
1227 { return __a->test(); }
1230 atomic_flag_test_explicit(const atomic_flag* __a,
1231 memory_order __m) noexcept
1232 { return __a->test(__m); }
1235 atomic_flag_test_explicit(const volatile atomic_flag* __a,
1236 memory_order __m) noexcept
1237 { return __a->test(__m); }
1241 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
1242 { __a->clear(__m); }
1245 atomic_flag_clear_explicit(volatile atomic_flag* __a,
1246 memory_order __m) noexcept
1247 { __a->clear(__m); }
1250 atomic_flag_test_and_set(atomic_flag* __a) noexcept
1251 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1254 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
1255 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1258 atomic_flag_clear(atomic_flag* __a) noexcept
1259 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1262 atomic_flag_clear(volatile atomic_flag* __a) noexcept
1263 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1265#if __cpp_lib_atomic_wait
1267 atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
1268 { __a->wait(__old); }
1271 atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
1272 memory_order __m) noexcept
1273 { __a->wait(__old, __m); }
1276 atomic_flag_notify_one(atomic_flag* __a) noexcept
1277 { __a->notify_one(); }
1280 atomic_flag_notify_all(atomic_flag* __a) noexcept
1281 { __a->notify_all(); }
1282#endif // __cpp_lib_atomic_wait
1284 /// @cond undocumented
1285 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1286 // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
1287 template<typename _Tp>
1288 using __atomic_val_t = __type_identity_t<_Tp>;
1289 template<typename _Tp>
1290 using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1293 // [atomics.nonmembers] Non-member functions.
1294 // Function templates generally applicable to atomic types.
1295 template<typename _ITp>
1297 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
1298 { return __a->is_lock_free(); }
1300 template<typename _ITp>
1302 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
1303 { return __a->is_lock_free(); }
1305 template<typename _ITp>
1307 atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1308 { __a->store(__i, memory_order_relaxed); }
1310 template<typename _ITp>
1312 atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1313 { __a->store(__i, memory_order_relaxed); }
1315 template<typename _ITp>
1317 atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1318 memory_order __m) noexcept
1319 { __a->store(__i, __m); }
1321 template<typename _ITp>
1323 atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1324 memory_order __m) noexcept
1325 { __a->store(__i, __m); }
1327 template<typename _ITp>
1329 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
1330 { return __a->load(__m); }
1332 template<typename _ITp>
1334 atomic_load_explicit(const volatile atomic<_ITp>* __a,
1335 memory_order __m) noexcept
1336 { return __a->load(__m); }
1338 template<typename _ITp>
1340 atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1341 memory_order __m) noexcept
1342 { return __a->exchange(__i, __m); }
1344 template<typename _ITp>
1346 atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1347 __atomic_val_t<_ITp> __i,
1348 memory_order __m) noexcept
1349 { return __a->exchange(__i, __m); }
1351 template<typename _ITp>
1353 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1354 __atomic_val_t<_ITp>* __i1,
1355 __atomic_val_t<_ITp> __i2,
1357 memory_order __m2) noexcept
1358 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1360 template<typename _ITp>
1362 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1363 __atomic_val_t<_ITp>* __i1,
1364 __atomic_val_t<_ITp> __i2,
1366 memory_order __m2) noexcept
1367 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1369 template<typename _ITp>
1371 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1372 __atomic_val_t<_ITp>* __i1,
1373 __atomic_val_t<_ITp> __i2,
1375 memory_order __m2) noexcept
1376 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1378 template<typename _ITp>
1380 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1381 __atomic_val_t<_ITp>* __i1,
1382 __atomic_val_t<_ITp> __i2,
1384 memory_order __m2) noexcept
1385 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1388 template<typename _ITp>
1390 atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1391 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1393 template<typename _ITp>
1395 atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1396 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1398 template<typename _ITp>
1400 atomic_load(const atomic<_ITp>* __a) noexcept
1401 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1403 template<typename _ITp>
1405 atomic_load(const volatile atomic<_ITp>* __a) noexcept
1406 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1408 template<typename _ITp>
1410 atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1411 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1413 template<typename _ITp>
1415 atomic_exchange(volatile atomic<_ITp>* __a,
1416 __atomic_val_t<_ITp> __i) noexcept
1417 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1419 template<typename _ITp>
1421 atomic_compare_exchange_weak(atomic<_ITp>* __a,
1422 __atomic_val_t<_ITp>* __i1,
1423 __atomic_val_t<_ITp> __i2) noexcept
1425 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1426 memory_order_seq_cst,
1427 memory_order_seq_cst);
1430 template<typename _ITp>
1432 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1433 __atomic_val_t<_ITp>* __i1,
1434 __atomic_val_t<_ITp> __i2) noexcept
1436 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1437 memory_order_seq_cst,
1438 memory_order_seq_cst);
1441 template<typename _ITp>
1443 atomic_compare_exchange_strong(atomic<_ITp>* __a,
1444 __atomic_val_t<_ITp>* __i1,
1445 __atomic_val_t<_ITp> __i2) noexcept
1447 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1448 memory_order_seq_cst,
1449 memory_order_seq_cst);
1452 template<typename _ITp>
1454 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1455 __atomic_val_t<_ITp>* __i1,
1456 __atomic_val_t<_ITp> __i2) noexcept
1458 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1459 memory_order_seq_cst,
1460 memory_order_seq_cst);
1464#if __cpp_lib_atomic_wait
1465 template<typename _Tp>
1467 atomic_wait(const atomic<_Tp>* __a,
1468 typename std::atomic<_Tp>::value_type __old) noexcept
1469 { __a->wait(__old); }
1471 template<typename _Tp>
1473 atomic_wait_explicit(const atomic<_Tp>* __a,
1474 typename std::atomic<_Tp>::value_type __old,
1475 std::memory_order __m) noexcept
1476 { __a->wait(__old, __m); }
1478 template<typename _Tp>
1480 atomic_notify_one(atomic<_Tp>* __a) noexcept
1481 { __a->notify_one(); }
1483 template<typename _Tp>
1485 atomic_notify_all(atomic<_Tp>* __a) noexcept
1486 { __a->notify_all(); }
1487#endif // __cpp_lib_atomic_wait
1489 // Function templates for atomic_integral and atomic_pointer operations only.
1490 // Some operations (and, or, xor) are only available for atomic integrals,
1491 // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1493 template<typename _ITp>
1495 atomic_fetch_add_explicit(atomic<_ITp>* __a,
1496 __atomic_diff_t<_ITp> __i,
1497 memory_order __m) noexcept
1498 { return __a->fetch_add(__i, __m); }
1500 template<typename _ITp>
1502 atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1503 __atomic_diff_t<_ITp> __i,
1504 memory_order __m) noexcept
1505 { return __a->fetch_add(__i, __m); }
1507 template<typename _ITp>
1509 atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1510 __atomic_diff_t<_ITp> __i,
1511 memory_order __m) noexcept
1512 { return __a->fetch_sub(__i, __m); }
1514 template<typename _ITp>
1516 atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1517 __atomic_diff_t<_ITp> __i,
1518 memory_order __m) noexcept
1519 { return __a->fetch_sub(__i, __m); }
1521 template<typename _ITp>
1523 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1524 __atomic_val_t<_ITp> __i,
1525 memory_order __m) noexcept
1526 { return __a->fetch_and(__i, __m); }
1528 template<typename _ITp>
1530 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1531 __atomic_val_t<_ITp> __i,
1532 memory_order __m) noexcept
1533 { return __a->fetch_and(__i, __m); }
1535 template<typename _ITp>
1537 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1538 __atomic_val_t<_ITp> __i,
1539 memory_order __m) noexcept
1540 { return __a->fetch_or(__i, __m); }
1542 template<typename _ITp>
1544 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1545 __atomic_val_t<_ITp> __i,
1546 memory_order __m) noexcept
1547 { return __a->fetch_or(__i, __m); }
1549 template<typename _ITp>
1551 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1552 __atomic_val_t<_ITp> __i,
1553 memory_order __m) noexcept
1554 { return __a->fetch_xor(__i, __m); }
1556 template<typename _ITp>
1558 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1559 __atomic_val_t<_ITp> __i,
1560 memory_order __m) noexcept
1561 { return __a->fetch_xor(__i, __m); }
1563 template<typename _ITp>
1565 atomic_fetch_add(atomic<_ITp>* __a,
1566 __atomic_diff_t<_ITp> __i) noexcept
1567 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1569 template<typename _ITp>
1571 atomic_fetch_add(volatile atomic<_ITp>* __a,
1572 __atomic_diff_t<_ITp> __i) noexcept
1573 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1575 template<typename _ITp>
1577 atomic_fetch_sub(atomic<_ITp>* __a,
1578 __atomic_diff_t<_ITp> __i) noexcept
1579 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1581 template<typename _ITp>
1583 atomic_fetch_sub(volatile atomic<_ITp>* __a,
1584 __atomic_diff_t<_ITp> __i) noexcept
1585 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1587 template<typename _ITp>
1589 atomic_fetch_and(__atomic_base<_ITp>* __a,
1590 __atomic_val_t<_ITp> __i) noexcept
1591 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1593 template<typename _ITp>
1595 atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1596 __atomic_val_t<_ITp> __i) noexcept
1597 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1599 template<typename _ITp>
1601 atomic_fetch_or(__atomic_base<_ITp>* __a,
1602 __atomic_val_t<_ITp> __i) noexcept
1603 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1605 template<typename _ITp>
1607 atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1608 __atomic_val_t<_ITp> __i) noexcept
1609 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1611 template<typename _ITp>
1613 atomic_fetch_xor(__atomic_base<_ITp>* __a,
1614 __atomic_val_t<_ITp> __i) noexcept
1615 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1617 template<typename _ITp>
1619 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1620 __atomic_val_t<_ITp> __i) noexcept
1621 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1623#if __cplusplus > 201703L
1624#define __cpp_lib_atomic_float 201711L
1626 struct atomic<float> : __atomic_float<float>
1628 atomic() noexcept = default;
1631 atomic(float __fp) noexcept : __atomic_float<float>(__fp)
1634 atomic& operator=(const atomic&) volatile = delete;
1635 atomic& operator=(const atomic&) = delete;
1637 using __atomic_float<float>::operator=;
1641 struct atomic<double> : __atomic_float<double>
1643 atomic() noexcept = default;
1646 atomic(double __fp) noexcept : __atomic_float<double>(__fp)
1649 atomic& operator=(const atomic&) volatile = delete;
1650 atomic& operator=(const atomic&) = delete;
1652 using __atomic_float<double>::operator=;
1656 struct atomic<long double> : __atomic_float<long double>
1658 atomic() noexcept = default;
1661 atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
1664 atomic& operator=(const atomic&) volatile = delete;
1665 atomic& operator=(const atomic&) = delete;
1667 using __atomic_float<long double>::operator=;
1670#ifdef __STDCPP_FLOAT16_T__
1672 struct atomic<_Float16> : __atomic_float<_Float16>
1674 atomic() noexcept = default;
1677 atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp)
1680 atomic& operator=(const atomic&) volatile = delete;
1681 atomic& operator=(const atomic&) = delete;
1683 using __atomic_float<_Float16>::operator=;
1687#ifdef __STDCPP_FLOAT32_T__
1689 struct atomic<_Float32> : __atomic_float<_Float32>
1691 atomic() noexcept = default;
1694 atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp)
1697 atomic& operator=(const atomic&) volatile = delete;
1698 atomic& operator=(const atomic&) = delete;
1700 using __atomic_float<_Float32>::operator=;
1704#ifdef __STDCPP_FLOAT64_T__
1706 struct atomic<_Float64> : __atomic_float<_Float64>
1708 atomic() noexcept = default;
1711 atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp)
1714 atomic& operator=(const atomic&) volatile = delete;
1715 atomic& operator=(const atomic&) = delete;
1717 using __atomic_float<_Float64>::operator=;
1721#ifdef __STDCPP_FLOAT128_T__
1723 struct atomic<_Float128> : __atomic_float<_Float128>
1725 atomic() noexcept = default;
1728 atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp)
1731 atomic& operator=(const atomic&) volatile = delete;
1732 atomic& operator=(const atomic&) = delete;
1734 using __atomic_float<_Float128>::operator=;
1738#ifdef __STDCPP_BFLOAT16_T__
1740 struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
1742 atomic() noexcept = default;
1745 atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
1748 atomic& operator=(const atomic&) volatile = delete;
1749 atomic& operator=(const atomic&) = delete;
1751 using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
1755#define __cpp_lib_atomic_ref 201806L
1757 /// Class template to provide atomic operations on a non-atomic variable.
1758 template<typename _Tp>
1759 struct atomic_ref : __atomic_ref<_Tp>
1762 atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
1765 atomic_ref& operator=(const atomic_ref&) = delete;
1767 atomic_ref(const atomic_ref&) = default;
1769 using __atomic_ref<_Tp>::operator=;
1772#define __cpp_lib_atomic_lock_free_type_aliases 201907L
1773#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
1774 using atomic_signed_lock_free
1775 = atomic<make_signed_t<__detail::__platform_wait_t>>;
1776 using atomic_unsigned_lock_free
1777 = atomic<make_unsigned_t<__detail::__platform_wait_t>>;
1778#elif ATOMIC_INT_LOCK_FREE || !(ATOMIC_LONG_LOCK_FREE || ATOMIC_CHAR_LOCK_FREE)
1779 using atomic_signed_lock_free = atomic<signed int>;
1780 using atomic_unsigned_lock_free = atomic<unsigned int>;
1781#elif ATOMIC_LONG_LOCK_FREE
1782 using atomic_signed_lock_free = atomic<signed long>;
1783 using atomic_unsigned_lock_free = atomic<unsigned long>;
1784#elif ATOMIC_CHAR_LOCK_FREE
1785 using atomic_signed_lock_free = atomic<signed char>;
1786 using atomic_unsigned_lock_free = atomic<unsigned char>;
1791 /// @} group atomics
1793_GLIBCXX_END_NAMESPACE_VERSION
1798#endif // _GLIBCXX_ATOMIC