3 // Copyright (C) 2008, 2009, 2010, 2011 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__
38 # include <bits/c++0x_warning.h>
41 #include <bits/atomic_base.h>
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
53 // NB: No operators or fetch-operations for this type.
57 __atomic_base<bool> _M_base;
60 atomic_bool() noexcept = default;
61 ~atomic_bool() noexcept = default;
62 atomic_bool(const atomic_bool&) = delete;
63 atomic_bool& operator=(const atomic_bool&) = delete;
64 atomic_bool& operator=(const atomic_bool&) volatile = delete;
66 constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
69 operator=(bool __i) noexcept
70 { return _M_base.operator=(__i); }
72 operator bool() const noexcept
73 { return _M_base.load(); }
75 operator bool() const volatile noexcept
76 { return _M_base.load(); }
79 is_lock_free() const noexcept { return _M_base.is_lock_free(); }
82 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
85 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
86 { _M_base.store(__i, __m); }
89 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
90 { _M_base.store(__i, __m); }
93 load(memory_order __m = memory_order_seq_cst) const noexcept
94 { return _M_base.load(__m); }
97 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
98 { return _M_base.load(__m); }
101 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
102 { return _M_base.exchange(__i, __m); }
106 memory_order __m = memory_order_seq_cst) volatile noexcept
107 { return _M_base.exchange(__i, __m); }
110 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
111 memory_order __m2) noexcept
112 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
115 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
116 memory_order __m2) volatile noexcept
117 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
120 compare_exchange_weak(bool& __i1, bool __i2,
121 memory_order __m = memory_order_seq_cst) noexcept
122 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
125 compare_exchange_weak(bool& __i1, bool __i2,
126 memory_order __m = memory_order_seq_cst) volatile noexcept
127 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
130 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
131 memory_order __m2) noexcept
132 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
135 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
136 memory_order __m2) volatile noexcept
137 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
140 compare_exchange_strong(bool& __i1, bool __i2,
141 memory_order __m = memory_order_seq_cst) noexcept
142 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
145 compare_exchange_strong(bool& __i1, bool __i2,
146 memory_order __m = memory_order_seq_cst) volatile noexcept
147 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
152 /// 29.4.3, Generic atomic type, primary class template.
153 template<typename _Tp>
160 atomic() noexcept = default;
161 ~atomic() noexcept = default;
162 atomic(const atomic&) = delete;
163 atomic& operator=(const atomic&) = delete;
164 atomic& operator=(const atomic&) volatile = delete;
166 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
168 operator _Tp() const noexcept
171 operator _Tp() const volatile noexcept
175 operator=(_Tp __i) noexcept
176 { store(__i); return __i; }
179 operator=(_Tp __i) volatile noexcept
180 { store(__i); return __i; }
183 is_lock_free() const noexcept
184 { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
187 is_lock_free() const volatile noexcept
188 { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
191 store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
192 { __atomic_store(&_M_i, &__i, _m); }
195 store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
196 { __atomic_store(&_M_i, &__i, _m); }
199 load(memory_order _m = memory_order_seq_cst) const noexcept
202 __atomic_load(&_M_i, &tmp, _m);
207 load(memory_order _m = memory_order_seq_cst) const volatile noexcept
210 __atomic_load(&_M_i, &tmp, _m);
215 exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
218 __atomic_exchange(&_M_i, &__i, &tmp, _m);
224 memory_order _m = memory_order_seq_cst) volatile noexcept
227 __atomic_exchange(&_M_i, &__i, &tmp, _m);
232 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
233 memory_order __f) noexcept
235 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
239 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
240 memory_order __f) volatile noexcept
242 return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
246 compare_exchange_weak(_Tp& __e, _Tp __i,
247 memory_order __m = memory_order_seq_cst) noexcept
248 { return compare_exchange_weak(__e, __i, __m, __m); }
251 compare_exchange_weak(_Tp& __e, _Tp __i,
252 memory_order __m = memory_order_seq_cst) volatile noexcept
253 { return compare_exchange_weak(__e, __i, __m, __m); }
256 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
257 memory_order __f) noexcept
259 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
263 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
264 memory_order __f) volatile noexcept
266 return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
270 compare_exchange_strong(_Tp& __e, _Tp __i,
271 memory_order __m = memory_order_seq_cst) noexcept
272 { return compare_exchange_strong(__e, __i, __m, __m); }
275 compare_exchange_strong(_Tp& __e, _Tp __i,
276 memory_order __m = memory_order_seq_cst) volatile noexcept
277 { return compare_exchange_strong(__e, __i, __m, __m); }
281 /// Partial specialization for pointer types.
282 template<typename _Tp>
285 typedef _Tp* __pointer_type;
286 typedef __atomic_base<_Tp*> __base_type;
289 atomic() noexcept = default;
290 ~atomic() noexcept = default;
291 atomic(const atomic&) = delete;
292 atomic& operator=(const atomic&) = delete;
293 atomic& operator=(const atomic&) volatile = delete;
295 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
297 operator __pointer_type() const noexcept
298 { return __pointer_type(_M_b); }
300 operator __pointer_type() const volatile noexcept
301 { return __pointer_type(_M_b); }
304 operator=(__pointer_type __p) noexcept
305 { return _M_b.operator=(__p); }
308 operator=(__pointer_type __p) volatile noexcept
309 { return _M_b.operator=(__p); }
312 operator++(int) noexcept
316 operator++(int) volatile noexcept
320 operator--(int) noexcept
324 operator--(int) volatile noexcept
328 operator++() noexcept
332 operator++() volatile noexcept
336 operator--() noexcept
340 operator--() volatile noexcept
344 operator+=(ptrdiff_t __d) noexcept
345 { return _M_b.operator+=(__d); }
348 operator+=(ptrdiff_t __d) volatile noexcept
349 { return _M_b.operator+=(__d); }
352 operator-=(ptrdiff_t __d) noexcept
353 { return _M_b.operator-=(__d); }
356 operator-=(ptrdiff_t __d) volatile noexcept
357 { return _M_b.operator-=(__d); }
360 is_lock_free() const noexcept
361 { return _M_b.is_lock_free(); }
364 is_lock_free() const volatile noexcept
365 { return _M_b.is_lock_free(); }
368 store(__pointer_type __p,
369 memory_order __m = memory_order_seq_cst) noexcept
370 { return _M_b.store(__p, __m); }
373 store(__pointer_type __p,
374 memory_order __m = memory_order_seq_cst) volatile noexcept
375 { return _M_b.store(__p, __m); }
378 load(memory_order __m = memory_order_seq_cst) const noexcept
379 { return _M_b.load(__m); }
382 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
383 { return _M_b.load(__m); }
386 exchange(__pointer_type __p,
387 memory_order __m = memory_order_seq_cst) noexcept
388 { return _M_b.exchange(__p, __m); }
391 exchange(__pointer_type __p,
392 memory_order __m = memory_order_seq_cst) volatile noexcept
393 { return _M_b.exchange(__p, __m); }
396 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
397 memory_order __m1, memory_order __m2) noexcept
398 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
401 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
403 memory_order __m2) volatile noexcept
404 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
407 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
408 memory_order __m = memory_order_seq_cst) noexcept
410 return compare_exchange_weak(__p1, __p2, __m,
411 __cmpexch_failure_order(__m));
415 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
416 memory_order __m = memory_order_seq_cst) volatile noexcept
418 return compare_exchange_weak(__p1, __p2, __m,
419 __cmpexch_failure_order(__m));
423 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
424 memory_order __m1, memory_order __m2) noexcept
425 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
428 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
430 memory_order __m2) volatile noexcept
431 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
434 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
435 memory_order __m = memory_order_seq_cst) noexcept
437 return _M_b.compare_exchange_strong(__p1, __p2, __m,
438 __cmpexch_failure_order(__m));
442 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
443 memory_order __m = memory_order_seq_cst) volatile noexcept
445 return _M_b.compare_exchange_strong(__p1, __p2, __m,
446 __cmpexch_failure_order(__m));
450 fetch_add(ptrdiff_t __d,
451 memory_order __m = memory_order_seq_cst) noexcept
452 { return _M_b.fetch_add(__d, __m); }
455 fetch_add(ptrdiff_t __d,
456 memory_order __m = memory_order_seq_cst) volatile noexcept
457 { return _M_b.fetch_add(__d, __m); }
460 fetch_sub(ptrdiff_t __d,
461 memory_order __m = memory_order_seq_cst) noexcept
462 { return _M_b.fetch_sub(__d, __m); }
465 fetch_sub(ptrdiff_t __d,
466 memory_order __m = memory_order_seq_cst) volatile noexcept
467 { return _M_b.fetch_sub(__d, __m); }
471 /// Explicit specialization for bool.
473 struct atomic<bool> : public atomic_bool
475 typedef bool __integral_type;
476 typedef atomic_bool __base_type;
478 atomic() noexcept = default;
479 ~atomic() noexcept = default;
480 atomic(const atomic&) = delete;
481 atomic& operator=(const atomic&) = delete;
482 atomic& operator=(const atomic&) volatile = delete;
484 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
486 using __base_type::operator __integral_type;
487 using __base_type::operator=;
490 /// Explicit specialization for char.
492 struct atomic<char> : public atomic_char
494 typedef char __integral_type;
495 typedef atomic_char __base_type;
497 atomic() noexcept = default;
498 ~atomic() noexcept = default;
499 atomic(const atomic&) = delete;
500 atomic& operator=(const atomic&) = delete;
501 atomic& operator=(const atomic&) volatile = delete;
503 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
505 using __base_type::operator __integral_type;
506 using __base_type::operator=;
509 /// Explicit specialization for signed char.
511 struct atomic<signed char> : public atomic_schar
513 typedef signed char __integral_type;
514 typedef atomic_schar __base_type;
516 atomic() noexcept= default;
517 ~atomic() noexcept = default;
518 atomic(const atomic&) = delete;
519 atomic& operator=(const atomic&) = delete;
520 atomic& operator=(const atomic&) volatile = delete;
522 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
524 using __base_type::operator __integral_type;
525 using __base_type::operator=;
528 /// Explicit specialization for unsigned char.
530 struct atomic<unsigned char> : public atomic_uchar
532 typedef unsigned char __integral_type;
533 typedef atomic_uchar __base_type;
535 atomic() noexcept= default;
536 ~atomic() noexcept = default;
537 atomic(const atomic&) = delete;
538 atomic& operator=(const atomic&) = delete;
539 atomic& operator=(const atomic&) volatile = delete;
541 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
543 using __base_type::operator __integral_type;
544 using __base_type::operator=;
547 /// Explicit specialization for short.
549 struct atomic<short> : public atomic_short
551 typedef short __integral_type;
552 typedef atomic_short __base_type;
554 atomic() noexcept = default;
555 ~atomic() noexcept = default;
556 atomic(const atomic&) = delete;
557 atomic& operator=(const atomic&) = delete;
558 atomic& operator=(const atomic&) volatile = delete;
560 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
562 using __base_type::operator __integral_type;
563 using __base_type::operator=;
566 /// Explicit specialization for unsigned short.
568 struct atomic<unsigned short> : public atomic_ushort
570 typedef unsigned short __integral_type;
571 typedef atomic_ushort __base_type;
573 atomic() noexcept = default;
574 ~atomic() noexcept = default;
575 atomic(const atomic&) = delete;
576 atomic& operator=(const atomic&) = delete;
577 atomic& operator=(const atomic&) volatile = delete;
579 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
581 using __base_type::operator __integral_type;
582 using __base_type::operator=;
585 /// Explicit specialization for int.
587 struct atomic<int> : atomic_int
589 typedef int __integral_type;
590 typedef atomic_int __base_type;
592 atomic() noexcept = default;
593 ~atomic() noexcept = default;
594 atomic(const atomic&) = delete;
595 atomic& operator=(const atomic&) = delete;
596 atomic& operator=(const atomic&) volatile = delete;
598 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
600 using __base_type::operator __integral_type;
601 using __base_type::operator=;
604 /// Explicit specialization for unsigned int.
606 struct atomic<unsigned int> : public atomic_uint
608 typedef unsigned int __integral_type;
609 typedef atomic_uint __base_type;
611 atomic() noexcept = default;
612 ~atomic() noexcept = default;
613 atomic(const atomic&) = delete;
614 atomic& operator=(const atomic&) = delete;
615 atomic& operator=(const atomic&) volatile = delete;
617 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
619 using __base_type::operator __integral_type;
620 using __base_type::operator=;
623 /// Explicit specialization for long.
625 struct atomic<long> : public atomic_long
627 typedef long __integral_type;
628 typedef atomic_long __base_type;
630 atomic() noexcept = default;
631 ~atomic() noexcept = default;
632 atomic(const atomic&) = delete;
633 atomic& operator=(const atomic&) = delete;
634 atomic& operator=(const atomic&) volatile = delete;
636 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
638 using __base_type::operator __integral_type;
639 using __base_type::operator=;
642 /// Explicit specialization for unsigned long.
644 struct atomic<unsigned long> : public atomic_ulong
646 typedef unsigned long __integral_type;
647 typedef atomic_ulong __base_type;
649 atomic() noexcept = default;
650 ~atomic() noexcept = default;
651 atomic(const atomic&) = delete;
652 atomic& operator=(const atomic&) = delete;
653 atomic& operator=(const atomic&) volatile = delete;
655 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
657 using __base_type::operator __integral_type;
658 using __base_type::operator=;
661 /// Explicit specialization for long long.
663 struct atomic<long long> : public atomic_llong
665 typedef long long __integral_type;
666 typedef atomic_llong __base_type;
668 atomic() noexcept = default;
669 ~atomic() noexcept = default;
670 atomic(const atomic&) = delete;
671 atomic& operator=(const atomic&) = delete;
672 atomic& operator=(const atomic&) volatile = delete;
674 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
676 using __base_type::operator __integral_type;
677 using __base_type::operator=;
680 /// Explicit specialization for unsigned long long.
682 struct atomic<unsigned long long> : public atomic_ullong
684 typedef unsigned long long __integral_type;
685 typedef atomic_ullong __base_type;
687 atomic() noexcept = default;
688 ~atomic() noexcept = default;
689 atomic(const atomic&) = delete;
690 atomic& operator=(const atomic&) = delete;
691 atomic& operator=(const atomic&) volatile = delete;
693 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
695 using __base_type::operator __integral_type;
696 using __base_type::operator=;
699 /// Explicit specialization for wchar_t.
701 struct atomic<wchar_t> : public atomic_wchar_t
703 typedef wchar_t __integral_type;
704 typedef atomic_wchar_t __base_type;
706 atomic() noexcept = default;
707 ~atomic() noexcept = default;
708 atomic(const atomic&) = delete;
709 atomic& operator=(const atomic&) = delete;
710 atomic& operator=(const atomic&) volatile = delete;
712 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
714 using __base_type::operator __integral_type;
715 using __base_type::operator=;
718 /// Explicit specialization for char16_t.
720 struct atomic<char16_t> : public atomic_char16_t
722 typedef char16_t __integral_type;
723 typedef atomic_char16_t __base_type;
725 atomic() noexcept = default;
726 ~atomic() noexcept = default;
727 atomic(const atomic&) = delete;
728 atomic& operator=(const atomic&) = delete;
729 atomic& operator=(const atomic&) volatile = delete;
731 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
733 using __base_type::operator __integral_type;
734 using __base_type::operator=;
737 /// Explicit specialization for char32_t.
739 struct atomic<char32_t> : public atomic_char32_t
741 typedef char32_t __integral_type;
742 typedef atomic_char32_t __base_type;
744 atomic() noexcept = default;
745 ~atomic() noexcept = default;
746 atomic(const atomic&) = delete;
747 atomic& operator=(const atomic&) = delete;
748 atomic& operator=(const atomic&) volatile = delete;
750 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
752 using __base_type::operator __integral_type;
753 using __base_type::operator=;
757 // Function definitions, atomic_flag operations.
759 atomic_flag_test_and_set_explicit(atomic_flag* __a,
760 memory_order __m) noexcept
761 { return __a->test_and_set(__m); }
764 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
765 memory_order __m) noexcept
766 { return __a->test_and_set(__m); }
769 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
773 atomic_flag_clear_explicit(volatile atomic_flag* __a,
774 memory_order __m) noexcept
778 atomic_flag_test_and_set(atomic_flag* __a) noexcept
779 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
782 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
783 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
786 atomic_flag_clear(atomic_flag* __a) noexcept
787 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
790 atomic_flag_clear(volatile atomic_flag* __a) noexcept
791 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
794 // Function templates generally applicable to atomic types.
795 template<typename _ITp>
797 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
798 { return __a->is_lock_free(); }
800 template<typename _ITp>
802 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
803 { return __a->is_lock_free(); }
805 template<typename _ITp>
807 atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
809 template<typename _ITp>
811 atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
813 template<typename _ITp>
815 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
816 memory_order __m) noexcept
817 { __a->store(__i, __m); }
819 template<typename _ITp>
821 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
822 memory_order __m) noexcept
823 { __a->store(__i, __m); }
825 template<typename _ITp>
827 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
828 { return __a->load(__m); }
830 template<typename _ITp>
832 atomic_load_explicit(const volatile atomic<_ITp>* __a,
833 memory_order __m) noexcept
834 { return __a->load(__m); }
836 template<typename _ITp>
838 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
839 memory_order __m) noexcept
840 { return __a->exchange(__i, __m); }
842 template<typename _ITp>
844 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
845 memory_order __m) noexcept
846 { return __a->exchange(__i, __m); }
848 template<typename _ITp>
850 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
851 _ITp* __i1, _ITp __i2,
853 memory_order __m2) noexcept
854 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
856 template<typename _ITp>
858 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
859 _ITp* __i1, _ITp __i2,
861 memory_order __m2) noexcept
862 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
864 template<typename _ITp>
866 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
867 _ITp* __i1, _ITp __i2,
869 memory_order __m2) noexcept
870 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
872 template<typename _ITp>
874 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
875 _ITp* __i1, _ITp __i2,
877 memory_order __m2) noexcept
878 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
881 template<typename _ITp>
883 atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
884 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
886 template<typename _ITp>
888 atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
889 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
891 template<typename _ITp>
893 atomic_load(const atomic<_ITp>* __a) noexcept
894 { return atomic_load_explicit(__a, memory_order_seq_cst); }
896 template<typename _ITp>
898 atomic_load(const volatile atomic<_ITp>* __a) noexcept
899 { return atomic_load_explicit(__a, memory_order_seq_cst); }
901 template<typename _ITp>
903 atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
904 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
906 template<typename _ITp>
908 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
909 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
911 template<typename _ITp>
913 atomic_compare_exchange_weak(atomic<_ITp>* __a,
914 _ITp* __i1, _ITp __i2) noexcept
916 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
917 memory_order_seq_cst,
918 memory_order_seq_cst);
921 template<typename _ITp>
923 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
924 _ITp* __i1, _ITp __i2) noexcept
926 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
927 memory_order_seq_cst,
928 memory_order_seq_cst);
931 template<typename _ITp>
933 atomic_compare_exchange_strong(atomic<_ITp>* __a,
934 _ITp* __i1, _ITp __i2) noexcept
936 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
937 memory_order_seq_cst,
938 memory_order_seq_cst);
941 template<typename _ITp>
943 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
944 _ITp* __i1, _ITp __i2) noexcept
946 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
947 memory_order_seq_cst,
948 memory_order_seq_cst);
951 // Function templates for atomic_integral operations only, using
952 // __atomic_base. Template argument should be constricted to
953 // intergral types as specified in the standard, excluding address
955 template<typename _ITp>
957 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
958 memory_order __m) noexcept
959 { return __a->fetch_add(__i, __m); }
961 template<typename _ITp>
963 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
964 memory_order __m) noexcept
965 { return __a->fetch_add(__i, __m); }
967 template<typename _ITp>
969 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
970 memory_order __m) noexcept
971 { return __a->fetch_sub(__i, __m); }
973 template<typename _ITp>
975 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
976 memory_order __m) noexcept
977 { return __a->fetch_sub(__i, __m); }
979 template<typename _ITp>
981 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
982 memory_order __m) noexcept
983 { return __a->fetch_and(__i, __m); }
985 template<typename _ITp>
987 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
988 memory_order __m) noexcept
989 { return __a->fetch_and(__i, __m); }
991 template<typename _ITp>
993 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
994 memory_order __m) noexcept
995 { return __a->fetch_or(__i, __m); }
997 template<typename _ITp>
999 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1000 memory_order __m) noexcept
1001 { return __a->fetch_or(__i, __m); }
1003 template<typename _ITp>
1005 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1006 memory_order __m) noexcept
1007 { return __a->fetch_xor(__i, __m); }
1009 template<typename _ITp>
1011 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1012 memory_order __m) noexcept
1013 { return __a->fetch_xor(__i, __m); }
1015 template<typename _ITp>
1017 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1018 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1020 template<typename _ITp>
1022 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1023 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1025 template<typename _ITp>
1027 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1028 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1030 template<typename _ITp>
1032 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1033 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1035 template<typename _ITp>
1037 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1038 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1040 template<typename _ITp>
1042 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1043 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1045 template<typename _ITp>
1047 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1048 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1050 template<typename _ITp>
1052 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1053 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1055 template<typename _ITp>
1057 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1058 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1060 template<typename _ITp>
1062 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1063 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1066 // Partial specializations for pointers.
1067 template<typename _ITp>
1069 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1070 memory_order __m) noexcept
1071 { return __a->fetch_add(__d, __m); }
1073 template<typename _ITp>
1075 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1076 memory_order __m) noexcept
1077 { return __a->fetch_add(__d, __m); }
1079 template<typename _ITp>
1081 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1082 { return __a->fetch_add(__d); }
1084 template<typename _ITp>
1086 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1087 { return __a->fetch_add(__d); }
1089 template<typename _ITp>
1091 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1092 ptrdiff_t __d, memory_order __m) noexcept
1093 { return __a->fetch_sub(__d, __m); }
1095 template<typename _ITp>
1097 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1098 memory_order __m) noexcept
1099 { return __a->fetch_sub(__d, __m); }
1101 template<typename _ITp>
1103 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1104 { return __a->fetch_sub(__d); }
1106 template<typename _ITp>
1108 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1109 { return __a->fetch_sub(__d); }
1112 _GLIBCXX_END_NAMESPACE_VERSION