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>
42 #include <bits/atomic_0.h>
43 #include <bits/atomic_2.h>
45 namespace std _GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 // NB: No operators or fetch-operations for this type.
59 __atomic_base<bool> _M_base;
62 atomic_bool() = default;
63 ~atomic_bool() = default;
64 atomic_bool(const atomic_bool&) = delete;
65 atomic_bool& operator=(const atomic_bool&) = delete;
66 atomic_bool& operator=(const atomic_bool&) volatile = delete;
68 constexpr atomic_bool(bool __i) : _M_base(__i) { }
72 { return _M_base.operator=(__i); }
75 { return _M_base.load(); }
77 operator bool() const volatile
78 { return _M_base.load(); }
81 is_lock_free() const { return _M_base.is_lock_free(); }
84 is_lock_free() const volatile { return _M_base.is_lock_free(); }
87 store(bool __i, memory_order __m = memory_order_seq_cst)
88 { _M_base.store(__i, __m); }
91 store(bool __i, memory_order __m = memory_order_seq_cst) volatile
92 { _M_base.store(__i, __m); }
95 load(memory_order __m = memory_order_seq_cst) const
96 { return _M_base.load(__m); }
99 load(memory_order __m = memory_order_seq_cst) const volatile
100 { return _M_base.load(__m); }
103 exchange(bool __i, memory_order __m = memory_order_seq_cst)
104 { return _M_base.exchange(__i, __m); }
107 exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile
108 { return _M_base.exchange(__i, __m); }
111 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
113 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
116 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
117 memory_order __m2) volatile
118 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
121 compare_exchange_weak(bool& __i1, bool __i2,
122 memory_order __m = memory_order_seq_cst)
123 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
126 compare_exchange_weak(bool& __i1, bool __i2,
127 memory_order __m = memory_order_seq_cst) volatile
128 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
131 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
133 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
136 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
137 memory_order __m2) volatile
138 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
141 compare_exchange_strong(bool& __i1, bool __i2,
142 memory_order __m = memory_order_seq_cst)
143 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
146 compare_exchange_strong(bool& __i1, bool __i2,
147 memory_order __m = memory_order_seq_cst) volatile
148 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
153 /// 29.4.3, Generic atomic type, primary class template.
154 template<typename _Tp>
163 atomic(const atomic&) = delete;
164 atomic& operator=(const atomic&) = delete;
165 atomic& operator=(const atomic&) volatile = delete;
167 constexpr atomic(_Tp __i) : _M_i(__i) { }
169 operator _Tp() const;
171 operator _Tp() const volatile;
174 operator=(_Tp __i) { store(__i); return __i; }
177 operator=(_Tp __i) volatile { store(__i); return __i; }
180 is_lock_free() const;
183 is_lock_free() const volatile;
186 store(_Tp, memory_order = memory_order_seq_cst);
189 store(_Tp, memory_order = memory_order_seq_cst) volatile;
192 load(memory_order = memory_order_seq_cst) const;
195 load(memory_order = memory_order_seq_cst) const volatile;
198 exchange(_Tp __i, memory_order = memory_order_seq_cst);
201 exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
204 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order);
207 compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
210 compare_exchange_weak(_Tp&, _Tp, memory_order = memory_order_seq_cst);
213 compare_exchange_weak(_Tp&, _Tp,
214 memory_order = memory_order_seq_cst) volatile;
217 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order);
220 compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
223 compare_exchange_strong(_Tp&, _Tp, memory_order = memory_order_seq_cst);
226 compare_exchange_strong(_Tp&, _Tp,
227 memory_order = memory_order_seq_cst) volatile;
231 /// Partial specialization for pointer types.
232 template<typename _Tp>
235 typedef _Tp* __pointer_type;
236 typedef __atomic_base<_Tp*> __base_type;
241 atomic(const atomic&) = delete;
242 atomic& operator=(const atomic&) = delete;
243 atomic& operator=(const atomic&) volatile = delete;
245 constexpr atomic(__pointer_type __p) : _M_b(__p) { }
247 operator __pointer_type() const
248 { return __pointer_type(_M_b); }
250 operator __pointer_type() const volatile
251 { return __pointer_type(_M_b); }
254 operator=(__pointer_type __p)
255 { return _M_b.operator=(__p); }
258 operator=(__pointer_type __p) volatile
259 { return _M_b.operator=(__p); }
266 operator++(int) volatile
274 operator--(int) volatile
282 operator++() volatile
290 operator--() volatile
294 operator+=(ptrdiff_t __d)
295 { return _M_b.operator+=(__d); }
298 operator+=(ptrdiff_t __d) volatile
299 { return _M_b.operator+=(__d); }
302 operator-=(ptrdiff_t __d)
303 { return _M_b.operator-=(__d); }
306 operator-=(ptrdiff_t __d) volatile
307 { return _M_b.operator-=(__d); }
311 { return _M_b.is_lock_free(); }
314 is_lock_free() const volatile
315 { return _M_b.is_lock_free(); }
318 store(__pointer_type __p, memory_order __m = memory_order_seq_cst)
319 { return _M_b.store(__p, __m); }
322 store(__pointer_type __p,
323 memory_order __m = memory_order_seq_cst) volatile
324 { return _M_b.store(__p, __m); }
327 load(memory_order __m = memory_order_seq_cst) const
328 { return _M_b.load(__m); }
331 load(memory_order __m = memory_order_seq_cst) const volatile
332 { return _M_b.load(__m); }
335 exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst)
336 { return _M_b.exchange(__p, __m); }
339 exchange(__pointer_type __p,
340 memory_order __m = memory_order_seq_cst) volatile
341 { return _M_b.exchange(__p, __m); }
344 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
345 memory_order __m1, memory_order __m2)
346 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
349 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
350 memory_order __m1, memory_order __m2) volatile
351 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
354 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
355 memory_order __m = memory_order_seq_cst)
357 return compare_exchange_weak(__p1, __p2, __m,
358 __calculate_memory_order(__m));
362 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
363 memory_order __m = memory_order_seq_cst) volatile
365 return compare_exchange_weak(__p1, __p2, __m,
366 __calculate_memory_order(__m));
370 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
371 memory_order __m1, memory_order __m2)
372 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
375 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
376 memory_order __m1, memory_order __m2) volatile
377 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
380 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
381 memory_order __m = memory_order_seq_cst)
383 return _M_b.compare_exchange_strong(__p1, __p2, __m,
384 __calculate_memory_order(__m));
388 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
389 memory_order __m = memory_order_seq_cst) volatile
391 return _M_b.compare_exchange_strong(__p1, __p2, __m,
392 __calculate_memory_order(__m));
396 fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
397 { return _M_b.fetch_add(__d, __m); }
400 fetch_add(ptrdiff_t __d,
401 memory_order __m = memory_order_seq_cst) volatile
402 { return _M_b.fetch_add(__d, __m); }
405 fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
406 { return _M_b.fetch_sub(__d, __m); }
409 fetch_sub(ptrdiff_t __d,
410 memory_order __m = memory_order_seq_cst) volatile
411 { return _M_b.fetch_sub(__d, __m); }
415 /// Explicit specialization for bool.
417 struct atomic<bool> : public atomic_bool
419 typedef bool __integral_type;
420 typedef atomic_bool __base_type;
424 atomic(const atomic&) = delete;
425 atomic& operator=(const atomic&) = delete;
426 atomic& operator=(const atomic&) volatile = delete;
428 constexpr atomic(__integral_type __i) : __base_type(__i) { }
430 using __base_type::operator __integral_type;
431 using __base_type::operator=;
434 /// Explicit specialization for char.
436 struct atomic<char> : public atomic_char
438 typedef char __integral_type;
439 typedef atomic_char __base_type;
443 atomic(const atomic&) = delete;
444 atomic& operator=(const atomic&) = delete;
445 atomic& operator=(const atomic&) volatile = delete;
447 constexpr atomic(__integral_type __i) : __base_type(__i) { }
449 using __base_type::operator __integral_type;
450 using __base_type::operator=;
453 /// Explicit specialization for signed char.
455 struct atomic<signed char> : public atomic_schar
457 typedef signed char __integral_type;
458 typedef atomic_schar __base_type;
462 atomic(const atomic&) = delete;
463 atomic& operator=(const atomic&) = delete;
464 atomic& operator=(const atomic&) volatile = delete;
466 constexpr atomic(__integral_type __i) : __base_type(__i) { }
468 using __base_type::operator __integral_type;
469 using __base_type::operator=;
472 /// Explicit specialization for unsigned char.
474 struct atomic<unsigned char> : public atomic_uchar
476 typedef unsigned char __integral_type;
477 typedef atomic_uchar __base_type;
481 atomic(const atomic&) = delete;
482 atomic& operator=(const atomic&) = delete;
483 atomic& operator=(const atomic&) volatile = delete;
485 constexpr atomic(__integral_type __i) : __base_type(__i) { }
487 using __base_type::operator __integral_type;
488 using __base_type::operator=;
491 /// Explicit specialization for short.
493 struct atomic<short> : public atomic_short
495 typedef short __integral_type;
496 typedef atomic_short __base_type;
500 atomic(const atomic&) = delete;
501 atomic& operator=(const atomic&) = delete;
502 atomic& operator=(const atomic&) volatile = delete;
504 constexpr atomic(__integral_type __i) : __base_type(__i) { }
506 using __base_type::operator __integral_type;
507 using __base_type::operator=;
510 /// Explicit specialization for unsigned short.
512 struct atomic<unsigned short> : public atomic_ushort
514 typedef unsigned short __integral_type;
515 typedef atomic_ushort __base_type;
519 atomic(const atomic&) = delete;
520 atomic& operator=(const atomic&) = delete;
521 atomic& operator=(const atomic&) volatile = delete;
523 constexpr atomic(__integral_type __i) : __base_type(__i) { }
525 using __base_type::operator __integral_type;
526 using __base_type::operator=;
529 /// Explicit specialization for int.
531 struct atomic<int> : atomic_int
533 typedef int __integral_type;
534 typedef atomic_int __base_type;
538 atomic(const atomic&) = delete;
539 atomic& operator=(const atomic&) = delete;
540 atomic& operator=(const atomic&) volatile = delete;
542 constexpr atomic(__integral_type __i) : __base_type(__i) { }
544 using __base_type::operator __integral_type;
545 using __base_type::operator=;
548 /// Explicit specialization for unsigned int.
550 struct atomic<unsigned int> : public atomic_uint
552 typedef unsigned int __integral_type;
553 typedef atomic_uint __base_type;
557 atomic(const atomic&) = delete;
558 atomic& operator=(const atomic&) = delete;
559 atomic& operator=(const atomic&) volatile = delete;
561 constexpr atomic(__integral_type __i) : __base_type(__i) { }
563 using __base_type::operator __integral_type;
564 using __base_type::operator=;
567 /// Explicit specialization for long.
569 struct atomic<long> : public atomic_long
571 typedef long __integral_type;
572 typedef atomic_long __base_type;
576 atomic(const atomic&) = delete;
577 atomic& operator=(const atomic&) = delete;
578 atomic& operator=(const atomic&) volatile = delete;
580 constexpr atomic(__integral_type __i) : __base_type(__i) { }
582 using __base_type::operator __integral_type;
583 using __base_type::operator=;
586 /// Explicit specialization for unsigned long.
588 struct atomic<unsigned long> : public atomic_ulong
590 typedef unsigned long __integral_type;
591 typedef atomic_ulong __base_type;
595 atomic(const atomic&) = delete;
596 atomic& operator=(const atomic&) = delete;
597 atomic& operator=(const atomic&) volatile = delete;
599 constexpr atomic(__integral_type __i) : __base_type(__i) { }
601 using __base_type::operator __integral_type;
602 using __base_type::operator=;
605 /// Explicit specialization for long long.
607 struct atomic<long long> : public atomic_llong
609 typedef long long __integral_type;
610 typedef atomic_llong __base_type;
614 atomic(const atomic&) = delete;
615 atomic& operator=(const atomic&) = delete;
616 atomic& operator=(const atomic&) volatile = delete;
618 constexpr atomic(__integral_type __i) : __base_type(__i) { }
620 using __base_type::operator __integral_type;
621 using __base_type::operator=;
624 /// Explicit specialization for unsigned long long.
626 struct atomic<unsigned long long> : public atomic_ullong
628 typedef unsigned long long __integral_type;
629 typedef atomic_ullong __base_type;
633 atomic(const atomic&) = delete;
634 atomic& operator=(const atomic&) = delete;
635 atomic& operator=(const atomic&) volatile = delete;
637 constexpr atomic(__integral_type __i) : __base_type(__i) { }
639 using __base_type::operator __integral_type;
640 using __base_type::operator=;
643 /// Explicit specialization for wchar_t.
645 struct atomic<wchar_t> : public atomic_wchar_t
647 typedef wchar_t __integral_type;
648 typedef atomic_wchar_t __base_type;
652 atomic(const atomic&) = delete;
653 atomic& operator=(const atomic&) = delete;
654 atomic& operator=(const atomic&) volatile = delete;
656 constexpr atomic(__integral_type __i) : __base_type(__i) { }
658 using __base_type::operator __integral_type;
659 using __base_type::operator=;
662 /// Explicit specialization for char16_t.
664 struct atomic<char16_t> : public atomic_char16_t
666 typedef char16_t __integral_type;
667 typedef atomic_char16_t __base_type;
671 atomic(const atomic&) = delete;
672 atomic& operator=(const atomic&) = delete;
673 atomic& operator=(const atomic&) volatile = delete;
675 constexpr atomic(__integral_type __i) : __base_type(__i) { }
677 using __base_type::operator __integral_type;
678 using __base_type::operator=;
681 /// Explicit specialization for char32_t.
683 struct atomic<char32_t> : public atomic_char32_t
685 typedef char32_t __integral_type;
686 typedef atomic_char32_t __base_type;
690 atomic(const atomic&) = delete;
691 atomic& operator=(const atomic&) = delete;
692 atomic& operator=(const atomic&) volatile = delete;
694 constexpr atomic(__integral_type __i) : __base_type(__i) { }
696 using __base_type::operator __integral_type;
697 using __base_type::operator=;
701 // Function definitions, atomic_flag operations.
703 atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
704 { return __a->test_and_set(__m); }
707 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
709 { return __a->test_and_set(__m); }
712 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
716 atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m)
720 atomic_flag_test_and_set(atomic_flag* __a)
721 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
724 atomic_flag_test_and_set(volatile atomic_flag* __a)
725 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
728 atomic_flag_clear(atomic_flag* __a)
729 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
732 atomic_flag_clear(volatile atomic_flag* __a)
733 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
736 // Function templates generally applicable to atomic types.
737 template<typename _ITp>
739 atomic_is_lock_free(const atomic<_ITp>* __a)
740 { return __a->is_lock_free(); }
742 template<typename _ITp>
744 atomic_is_lock_free(const volatile atomic<_ITp>* __a)
745 { return __a->is_lock_free(); }
747 template<typename _ITp>
749 atomic_init(atomic<_ITp>* __a, _ITp __i);
751 template<typename _ITp>
753 atomic_init(volatile atomic<_ITp>* __a, _ITp __i);
755 template<typename _ITp>
757 atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m)
758 { __a->store(__i, __m); }
760 template<typename _ITp>
762 atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
764 { __a->store(__i, __m); }
766 template<typename _ITp>
768 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m)
769 { return __a->load(__m); }
771 template<typename _ITp>
773 atomic_load_explicit(const volatile atomic<_ITp>* __a,
775 { return __a->load(__m); }
777 template<typename _ITp>
779 atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
781 { return __a->exchange(__i, __m); }
783 template<typename _ITp>
785 atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
787 { return __a->exchange(__i, __m); }
789 template<typename _ITp>
791 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
792 _ITp* __i1, _ITp __i2,
793 memory_order __m1, memory_order __m2)
794 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
796 template<typename _ITp>
798 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
799 _ITp* __i1, _ITp __i2,
800 memory_order __m1, memory_order __m2)
801 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
803 template<typename _ITp>
805 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
806 _ITp* __i1, _ITp __i2,
809 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
811 template<typename _ITp>
813 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
814 _ITp* __i1, _ITp __i2,
817 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
820 template<typename _ITp>
822 atomic_store(atomic<_ITp>* __a, _ITp __i)
823 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
825 template<typename _ITp>
827 atomic_store(volatile atomic<_ITp>* __a, _ITp __i)
828 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
830 template<typename _ITp>
832 atomic_load(const atomic<_ITp>* __a)
833 { return atomic_load_explicit(__a, memory_order_seq_cst); }
835 template<typename _ITp>
837 atomic_load(const volatile atomic<_ITp>* __a)
838 { return atomic_load_explicit(__a, memory_order_seq_cst); }
840 template<typename _ITp>
842 atomic_exchange(atomic<_ITp>* __a, _ITp __i)
843 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
845 template<typename _ITp>
847 atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i)
848 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
850 template<typename _ITp>
852 atomic_compare_exchange_weak(atomic<_ITp>* __a,
853 _ITp* __i1, _ITp __i2)
855 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
856 memory_order_seq_cst,
857 memory_order_seq_cst);
860 template<typename _ITp>
862 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
863 _ITp* __i1, _ITp __i2)
865 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
866 memory_order_seq_cst,
867 memory_order_seq_cst);
870 template<typename _ITp>
872 atomic_compare_exchange_strong(atomic<_ITp>* __a,
873 _ITp* __i1, _ITp __i2)
875 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
876 memory_order_seq_cst,
877 memory_order_seq_cst);
880 template<typename _ITp>
882 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
883 _ITp* __i1, _ITp __i2)
885 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
886 memory_order_seq_cst,
887 memory_order_seq_cst);
890 // Function templates for atomic_integral operations only, using
891 // __atomic_base. Template argument should be constricted to
892 // intergral types as specified in the standard, excluding address
894 template<typename _ITp>
896 atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
898 { return __a->fetch_add(__i, __m); }
900 template<typename _ITp>
902 atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
904 { return __a->fetch_add(__i, __m); }
906 template<typename _ITp>
908 atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
910 { return __a->fetch_sub(__i, __m); }
912 template<typename _ITp>
914 atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
916 { return __a->fetch_sub(__i, __m); }
918 template<typename _ITp>
920 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
922 { return __a->fetch_and(__i, __m); }
924 template<typename _ITp>
926 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
928 { return __a->fetch_and(__i, __m); }
930 template<typename _ITp>
932 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
934 { return __a->fetch_or(__i, __m); }
936 template<typename _ITp>
938 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
940 { return __a->fetch_or(__i, __m); }
942 template<typename _ITp>
944 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
946 { return __a->fetch_xor(__i, __m); }
948 template<typename _ITp>
950 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
952 { return __a->fetch_xor(__i, __m); }
954 template<typename _ITp>
956 atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
957 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
959 template<typename _ITp>
961 atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i)
962 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
964 template<typename _ITp>
966 atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
967 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
969 template<typename _ITp>
971 atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i)
972 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
974 template<typename _ITp>
976 atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
977 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
979 template<typename _ITp>
981 atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i)
982 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
984 template<typename _ITp>
986 atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
987 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
989 template<typename _ITp>
991 atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i)
992 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
994 template<typename _ITp>
996 atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
997 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
999 template<typename _ITp>
1001 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i)
1002 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1005 // Partial specializations for pointers.
1006 template<typename _ITp>
1008 atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1010 { return __a->fetch_add(__d, __m); }
1012 template<typename _ITp>
1014 atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1016 { return __a->fetch_add(__d, __m); }
1018 template<typename _ITp>
1020 atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
1021 { return __a->fetch_add(__d); }
1023 template<typename _ITp>
1025 atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d)
1026 { return __a->fetch_add(__d); }
1028 template<typename _ITp>
1030 atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1031 ptrdiff_t __d, memory_order __m)
1032 { return __a->fetch_sub(__d, __m); }
1034 template<typename _ITp>
1036 atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1038 { return __a->fetch_sub(__d, __m); }
1040 template<typename _ITp>
1042 atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
1043 { return __a->fetch_sub(__d); }
1045 template<typename _ITp>
1047 atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d)
1048 { return __a->fetch_sub(__d); }
1051 _GLIBCXX_END_NAMESPACE_VERSION