xref: /dflybsd-src/contrib/gcc-4.7/libstdc++-v3/include/bits/atomic_base.h (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino // -*- C++ -*- header.
2e4b17023SJohn Marino 
3e4b17023SJohn Marino // Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4e4b17023SJohn Marino //
5e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
6e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the
7e4b17023SJohn Marino // terms of the GNU General Public License as published by the
8e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option)
9e4b17023SJohn Marino // any later version.
10e4b17023SJohn Marino 
11e4b17023SJohn Marino // This library is distributed in the hope that it will be useful,
12e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of
13e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e4b17023SJohn Marino // GNU General Public License for more details.
15e4b17023SJohn Marino 
16e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19e4b17023SJohn Marino 
20e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24e4b17023SJohn Marino 
25e4b17023SJohn Marino /** @file bits/atomic_base.h
26e4b17023SJohn Marino  *  This is an internal header file, included by other library headers.
27e4b17023SJohn Marino  *  Do not attempt to use it directly. @headername{atomic}
28e4b17023SJohn Marino  */
29e4b17023SJohn Marino 
30e4b17023SJohn Marino #ifndef _GLIBCXX_ATOMIC_BASE_H
31e4b17023SJohn Marino #define _GLIBCXX_ATOMIC_BASE_H 1
32e4b17023SJohn Marino 
33e4b17023SJohn Marino #pragma GCC system_header
34e4b17023SJohn Marino 
35e4b17023SJohn Marino #include <bits/c++config.h>
36e4b17023SJohn Marino #include <stdbool.h>
37e4b17023SJohn Marino #include <stdint.h>
38e4b17023SJohn Marino #include <bits/atomic_lockfree_defines.h>
39e4b17023SJohn Marino 
_GLIBCXX_VISIBILITY(default)40e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
41e4b17023SJohn Marino {
42e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION
43e4b17023SJohn Marino 
44e4b17023SJohn Marino   /**
45e4b17023SJohn Marino    * @defgroup atomics Atomics
46e4b17023SJohn Marino    *
47e4b17023SJohn Marino    * Components for performing atomic operations.
48e4b17023SJohn Marino    * @{
49e4b17023SJohn Marino    */
50e4b17023SJohn Marino 
51e4b17023SJohn Marino   /// Enumeration for memory_order
52e4b17023SJohn Marino   typedef enum memory_order
53e4b17023SJohn Marino     {
54e4b17023SJohn Marino       memory_order_relaxed,
55e4b17023SJohn Marino       memory_order_consume,
56e4b17023SJohn Marino       memory_order_acquire,
57e4b17023SJohn Marino       memory_order_release,
58e4b17023SJohn Marino       memory_order_acq_rel,
59e4b17023SJohn Marino       memory_order_seq_cst
60e4b17023SJohn Marino     } memory_order;
61e4b17023SJohn Marino 
62e4b17023SJohn Marino   // Drop release ordering as per [atomics.types.operations.req]/21
63e4b17023SJohn Marino   constexpr memory_order
64e4b17023SJohn Marino   __cmpexch_failure_order(memory_order __m) noexcept
65e4b17023SJohn Marino   {
66e4b17023SJohn Marino     return __m == memory_order_acq_rel ? memory_order_acquire
67e4b17023SJohn Marino       : __m == memory_order_release ? memory_order_relaxed : __m;
68e4b17023SJohn Marino   }
69e4b17023SJohn Marino 
70e4b17023SJohn Marino   inline void
71e4b17023SJohn Marino   atomic_thread_fence(memory_order __m) noexcept
72e4b17023SJohn Marino   { __atomic_thread_fence(__m); }
73e4b17023SJohn Marino 
74e4b17023SJohn Marino   inline void
75e4b17023SJohn Marino   atomic_signal_fence(memory_order __m) noexcept
765ce9237cSJohn Marino   { __atomic_signal_fence(__m); }
77e4b17023SJohn Marino 
78e4b17023SJohn Marino   /// kill_dependency
79e4b17023SJohn Marino   template<typename _Tp>
80e4b17023SJohn Marino     inline _Tp
81e4b17023SJohn Marino     kill_dependency(_Tp __y) noexcept
82e4b17023SJohn Marino     {
83e4b17023SJohn Marino       _Tp __ret(__y);
84e4b17023SJohn Marino       return __ret;
85e4b17023SJohn Marino     }
86e4b17023SJohn Marino 
87e4b17023SJohn Marino 
88e4b17023SJohn Marino   // Base types for atomics.
89e4b17023SJohn Marino   template<typename _IntTp>
90e4b17023SJohn Marino     struct __atomic_base;
91e4b17023SJohn Marino 
92e4b17023SJohn Marino   /// atomic_char
93e4b17023SJohn Marino   typedef __atomic_base<char>  	       		atomic_char;
94e4b17023SJohn Marino 
95e4b17023SJohn Marino   /// atomic_schar
96e4b17023SJohn Marino   typedef __atomic_base<signed char>	     	atomic_schar;
97e4b17023SJohn Marino 
98e4b17023SJohn Marino   /// atomic_uchar
99e4b17023SJohn Marino   typedef __atomic_base<unsigned char>		atomic_uchar;
100e4b17023SJohn Marino 
101e4b17023SJohn Marino   /// atomic_short
102e4b17023SJohn Marino   typedef __atomic_base<short>			atomic_short;
103e4b17023SJohn Marino 
104e4b17023SJohn Marino   /// atomic_ushort
105e4b17023SJohn Marino   typedef __atomic_base<unsigned short>	 	atomic_ushort;
106e4b17023SJohn Marino 
107e4b17023SJohn Marino   /// atomic_int
108e4b17023SJohn Marino   typedef __atomic_base<int>  	       		atomic_int;
109e4b17023SJohn Marino 
110e4b17023SJohn Marino   /// atomic_uint
111e4b17023SJohn Marino   typedef __atomic_base<unsigned int>	     	atomic_uint;
112e4b17023SJohn Marino 
113e4b17023SJohn Marino   /// atomic_long
114e4b17023SJohn Marino   typedef __atomic_base<long>  	       		atomic_long;
115e4b17023SJohn Marino 
116e4b17023SJohn Marino   /// atomic_ulong
117e4b17023SJohn Marino   typedef __atomic_base<unsigned long>		atomic_ulong;
118e4b17023SJohn Marino 
119e4b17023SJohn Marino   /// atomic_llong
120e4b17023SJohn Marino   typedef __atomic_base<long long>  		atomic_llong;
121e4b17023SJohn Marino 
122e4b17023SJohn Marino   /// atomic_ullong
123e4b17023SJohn Marino   typedef __atomic_base<unsigned long long> 	atomic_ullong;
124e4b17023SJohn Marino 
125e4b17023SJohn Marino   /// atomic_wchar_t
126e4b17023SJohn Marino   typedef __atomic_base<wchar_t>  		atomic_wchar_t;
127e4b17023SJohn Marino 
128e4b17023SJohn Marino   /// atomic_char16_t
129e4b17023SJohn Marino   typedef __atomic_base<char16_t>  		atomic_char16_t;
130e4b17023SJohn Marino 
131e4b17023SJohn Marino   /// atomic_char32_t
132e4b17023SJohn Marino   typedef __atomic_base<char32_t>  		atomic_char32_t;
133e4b17023SJohn Marino 
134e4b17023SJohn Marino   /// atomic_char32_t
135e4b17023SJohn Marino   typedef __atomic_base<char32_t>  		atomic_char32_t;
136e4b17023SJohn Marino 
137e4b17023SJohn Marino 
138e4b17023SJohn Marino   /// atomic_int_least8_t
139e4b17023SJohn Marino   typedef __atomic_base<int_least8_t>  		atomic_int_least8_t;
140e4b17023SJohn Marino 
141e4b17023SJohn Marino   /// atomic_uint_least8_t
142e4b17023SJohn Marino   typedef __atomic_base<uint_least8_t>	       	atomic_uint_least8_t;
143e4b17023SJohn Marino 
144e4b17023SJohn Marino   /// atomic_int_least16_t
145e4b17023SJohn Marino   typedef __atomic_base<int_least16_t>	       	atomic_int_least16_t;
146e4b17023SJohn Marino 
147e4b17023SJohn Marino   /// atomic_uint_least16_t
148e4b17023SJohn Marino   typedef __atomic_base<uint_least16_t>	       	atomic_uint_least16_t;
149e4b17023SJohn Marino 
150e4b17023SJohn Marino   /// atomic_int_least32_t
151e4b17023SJohn Marino   typedef __atomic_base<int_least32_t>	       	atomic_int_least32_t;
152e4b17023SJohn Marino 
153e4b17023SJohn Marino   /// atomic_uint_least32_t
154e4b17023SJohn Marino   typedef __atomic_base<uint_least32_t>	       	atomic_uint_least32_t;
155e4b17023SJohn Marino 
156e4b17023SJohn Marino   /// atomic_int_least64_t
157e4b17023SJohn Marino   typedef __atomic_base<int_least64_t>	       	atomic_int_least64_t;
158e4b17023SJohn Marino 
159e4b17023SJohn Marino   /// atomic_uint_least64_t
160e4b17023SJohn Marino   typedef __atomic_base<uint_least64_t>	       	atomic_uint_least64_t;
161e4b17023SJohn Marino 
162e4b17023SJohn Marino 
163e4b17023SJohn Marino   /// atomic_int_fast8_t
164e4b17023SJohn Marino   typedef __atomic_base<int_fast8_t>  		atomic_int_fast8_t;
165e4b17023SJohn Marino 
166e4b17023SJohn Marino   /// atomic_uint_fast8_t
167e4b17023SJohn Marino   typedef __atomic_base<uint_fast8_t>	      	atomic_uint_fast8_t;
168e4b17023SJohn Marino 
169e4b17023SJohn Marino   /// atomic_int_fast16_t
170e4b17023SJohn Marino   typedef __atomic_base<int_fast16_t>	      	atomic_int_fast16_t;
171e4b17023SJohn Marino 
172e4b17023SJohn Marino   /// atomic_uint_fast16_t
173e4b17023SJohn Marino   typedef __atomic_base<uint_fast16_t>	      	atomic_uint_fast16_t;
174e4b17023SJohn Marino 
175e4b17023SJohn Marino   /// atomic_int_fast32_t
176e4b17023SJohn Marino   typedef __atomic_base<int_fast32_t>	      	atomic_int_fast32_t;
177e4b17023SJohn Marino 
178e4b17023SJohn Marino   /// atomic_uint_fast32_t
179e4b17023SJohn Marino   typedef __atomic_base<uint_fast32_t>	      	atomic_uint_fast32_t;
180e4b17023SJohn Marino 
181e4b17023SJohn Marino   /// atomic_int_fast64_t
182e4b17023SJohn Marino   typedef __atomic_base<int_fast64_t>	      	atomic_int_fast64_t;
183e4b17023SJohn Marino 
184e4b17023SJohn Marino   /// atomic_uint_fast64_t
185e4b17023SJohn Marino   typedef __atomic_base<uint_fast64_t>	      	atomic_uint_fast64_t;
186e4b17023SJohn Marino 
187e4b17023SJohn Marino 
188e4b17023SJohn Marino   /// atomic_intptr_t
189e4b17023SJohn Marino   typedef __atomic_base<intptr_t>  	       	atomic_intptr_t;
190e4b17023SJohn Marino 
191e4b17023SJohn Marino   /// atomic_uintptr_t
192e4b17023SJohn Marino   typedef __atomic_base<uintptr_t>  	       	atomic_uintptr_t;
193e4b17023SJohn Marino 
194e4b17023SJohn Marino   /// atomic_size_t
195e4b17023SJohn Marino   typedef __atomic_base<size_t>	 	       	atomic_size_t;
196e4b17023SJohn Marino 
197e4b17023SJohn Marino   /// atomic_intmax_t
198e4b17023SJohn Marino   typedef __atomic_base<intmax_t>  	       	atomic_intmax_t;
199e4b17023SJohn Marino 
200e4b17023SJohn Marino   /// atomic_uintmax_t
201e4b17023SJohn Marino   typedef __atomic_base<uintmax_t>  	       	atomic_uintmax_t;
202e4b17023SJohn Marino 
203e4b17023SJohn Marino   /// atomic_ptrdiff_t
204e4b17023SJohn Marino   typedef __atomic_base<ptrdiff_t>  	       	atomic_ptrdiff_t;
205e4b17023SJohn Marino 
206e4b17023SJohn Marino 
207e4b17023SJohn Marino #define ATOMIC_VAR_INIT(_VI) { _VI }
208e4b17023SJohn Marino 
209e4b17023SJohn Marino   template<typename _Tp>
210e4b17023SJohn Marino     struct atomic;
211e4b17023SJohn Marino 
212e4b17023SJohn Marino   template<typename _Tp>
213e4b17023SJohn Marino     struct atomic<_Tp*>;
214e4b17023SJohn Marino 
2155ce9237cSJohn Marino     /* The target's "set" value for test-and-set may not be exactly 1.  */
2165ce9237cSJohn Marino #if __GCC_ATOMIC_TEST_AND_SET_TRUEVAL == 1
2175ce9237cSJohn Marino     typedef bool __atomic_flag_data_type;
2185ce9237cSJohn Marino #else
2195ce9237cSJohn Marino     typedef unsigned char __atomic_flag_data_type;
2205ce9237cSJohn Marino #endif
221e4b17023SJohn Marino 
222e4b17023SJohn Marino   /**
223e4b17023SJohn Marino    *  @brief Base type for atomic_flag.
224e4b17023SJohn Marino    *
225e4b17023SJohn Marino    *  Base type is POD with data, allowing atomic_flag to derive from
226e4b17023SJohn Marino    *  it and meet the standard layout type requirement. In addition to
227e4b17023SJohn Marino    *  compatibilty with a C interface, this allows different
228e4b17023SJohn Marino    *  implementations of atomic_flag to use the same atomic operation
229e4b17023SJohn Marino    *  functions, via a standard conversion to the __atomic_flag_base
230e4b17023SJohn Marino    *  argument.
231e4b17023SJohn Marino   */
232e4b17023SJohn Marino   _GLIBCXX_BEGIN_EXTERN_C
233e4b17023SJohn Marino 
234e4b17023SJohn Marino   struct __atomic_flag_base
235e4b17023SJohn Marino   {
2365ce9237cSJohn Marino     __atomic_flag_data_type _M_i;
237e4b17023SJohn Marino   };
238e4b17023SJohn Marino 
239e4b17023SJohn Marino   _GLIBCXX_END_EXTERN_C
240e4b17023SJohn Marino 
241e4b17023SJohn Marino #define ATOMIC_FLAG_INIT { 0 }
242e4b17023SJohn Marino 
243e4b17023SJohn Marino   /// atomic_flag
244e4b17023SJohn Marino   struct atomic_flag : public __atomic_flag_base
245e4b17023SJohn Marino   {
246e4b17023SJohn Marino     atomic_flag() noexcept = default;
247e4b17023SJohn Marino     ~atomic_flag() noexcept = default;
248e4b17023SJohn Marino     atomic_flag(const atomic_flag&) = delete;
249e4b17023SJohn Marino     atomic_flag& operator=(const atomic_flag&) = delete;
250e4b17023SJohn Marino     atomic_flag& operator=(const atomic_flag&) volatile = delete;
251e4b17023SJohn Marino 
252e4b17023SJohn Marino     // Conversion to ATOMIC_FLAG_INIT.
253e4b17023SJohn Marino     constexpr atomic_flag(bool __i) noexcept
2545ce9237cSJohn Marino       : __atomic_flag_base{ _S_init(__i) }
255e4b17023SJohn Marino     { }
256e4b17023SJohn Marino 
257e4b17023SJohn Marino     bool
258e4b17023SJohn Marino     test_and_set(memory_order __m = memory_order_seq_cst) noexcept
259e4b17023SJohn Marino     {
260e4b17023SJohn Marino       return __atomic_test_and_set (&_M_i, __m);
261e4b17023SJohn Marino     }
262e4b17023SJohn Marino 
263e4b17023SJohn Marino     bool
264e4b17023SJohn Marino     test_and_set(memory_order __m = memory_order_seq_cst) volatile noexcept
265e4b17023SJohn Marino     {
266e4b17023SJohn Marino       return __atomic_test_and_set (&_M_i, __m);
267e4b17023SJohn Marino     }
268e4b17023SJohn Marino 
269e4b17023SJohn Marino     void
270e4b17023SJohn Marino     clear(memory_order __m = memory_order_seq_cst) noexcept
271e4b17023SJohn Marino     {
272e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_consume);
273e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_acquire);
274e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_acq_rel);
275e4b17023SJohn Marino 
276e4b17023SJohn Marino       __atomic_clear (&_M_i, __m);
277e4b17023SJohn Marino     }
278e4b17023SJohn Marino 
279e4b17023SJohn Marino     void
280e4b17023SJohn Marino     clear(memory_order __m = memory_order_seq_cst) volatile noexcept
281e4b17023SJohn Marino     {
282e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_consume);
283e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_acquire);
284e4b17023SJohn Marino       __glibcxx_assert(__m != memory_order_acq_rel);
285e4b17023SJohn Marino 
286e4b17023SJohn Marino       __atomic_clear (&_M_i, __m);
287e4b17023SJohn Marino     }
2885ce9237cSJohn Marino 
2895ce9237cSJohn Marino   private:
2905ce9237cSJohn Marino     static constexpr __atomic_flag_data_type
2915ce9237cSJohn Marino     _S_init(bool __i)
2925ce9237cSJohn Marino     { return __i ? __GCC_ATOMIC_TEST_AND_SET_TRUEVAL : 0; }
293e4b17023SJohn Marino   };
294e4b17023SJohn Marino 
295e4b17023SJohn Marino 
296e4b17023SJohn Marino   /// Base class for atomic integrals.
297e4b17023SJohn Marino   //
298e4b17023SJohn Marino   // For each of the integral types, define atomic_[integral type] struct
299e4b17023SJohn Marino   //
300e4b17023SJohn Marino   // atomic_bool     bool
301e4b17023SJohn Marino   // atomic_char     char
302e4b17023SJohn Marino   // atomic_schar    signed char
303e4b17023SJohn Marino   // atomic_uchar    unsigned char
304e4b17023SJohn Marino   // atomic_short    short
305e4b17023SJohn Marino   // atomic_ushort   unsigned short
306e4b17023SJohn Marino   // atomic_int      int
307e4b17023SJohn Marino   // atomic_uint     unsigned int
308e4b17023SJohn Marino   // atomic_long     long
309e4b17023SJohn Marino   // atomic_ulong    unsigned long
310e4b17023SJohn Marino   // atomic_llong    long long
311e4b17023SJohn Marino   // atomic_ullong   unsigned long long
312e4b17023SJohn Marino   // atomic_char16_t char16_t
313e4b17023SJohn Marino   // atomic_char32_t char32_t
314e4b17023SJohn Marino   // atomic_wchar_t  wchar_t
315e4b17023SJohn Marino   //
316e4b17023SJohn Marino   // NB: Assuming _ITp is an integral scalar type that is 1, 2, 4, or
317e4b17023SJohn Marino   // 8 bytes, since that is what GCC built-in functions for atomic
318e4b17023SJohn Marino   // memory access expect.
319e4b17023SJohn Marino   template<typename _ITp>
320e4b17023SJohn Marino     struct __atomic_base
321e4b17023SJohn Marino     {
322e4b17023SJohn Marino     private:
323e4b17023SJohn Marino       typedef _ITp 	__int_type;
324e4b17023SJohn Marino 
325e4b17023SJohn Marino       __int_type 	_M_i;
326e4b17023SJohn Marino 
327e4b17023SJohn Marino     public:
328e4b17023SJohn Marino       __atomic_base() noexcept = default;
329e4b17023SJohn Marino       ~__atomic_base() noexcept = default;
330e4b17023SJohn Marino       __atomic_base(const __atomic_base&) = delete;
331e4b17023SJohn Marino       __atomic_base& operator=(const __atomic_base&) = delete;
332e4b17023SJohn Marino       __atomic_base& operator=(const __atomic_base&) volatile = delete;
333e4b17023SJohn Marino 
334e4b17023SJohn Marino       // Requires __int_type convertible to _M_i.
335e4b17023SJohn Marino       constexpr __atomic_base(__int_type __i) noexcept : _M_i (__i) { }
336e4b17023SJohn Marino 
337e4b17023SJohn Marino       operator __int_type() const noexcept
338e4b17023SJohn Marino       { return load(); }
339e4b17023SJohn Marino 
340e4b17023SJohn Marino       operator __int_type() const volatile noexcept
341e4b17023SJohn Marino       { return load(); }
342e4b17023SJohn Marino 
343e4b17023SJohn Marino       __int_type
344e4b17023SJohn Marino       operator=(__int_type __i) noexcept
345e4b17023SJohn Marino       {
346e4b17023SJohn Marino 	store(__i);
347e4b17023SJohn Marino 	return __i;
348e4b17023SJohn Marino       }
349e4b17023SJohn Marino 
350e4b17023SJohn Marino       __int_type
351e4b17023SJohn Marino       operator=(__int_type __i) volatile noexcept
352e4b17023SJohn Marino       {
353e4b17023SJohn Marino 	store(__i);
354e4b17023SJohn Marino 	return __i;
355e4b17023SJohn Marino       }
356e4b17023SJohn Marino 
357e4b17023SJohn Marino       __int_type
358e4b17023SJohn Marino       operator++(int) noexcept
359e4b17023SJohn Marino       { return fetch_add(1); }
360e4b17023SJohn Marino 
361e4b17023SJohn Marino       __int_type
362e4b17023SJohn Marino       operator++(int) volatile noexcept
363e4b17023SJohn Marino       { return fetch_add(1); }
364e4b17023SJohn Marino 
365e4b17023SJohn Marino       __int_type
366e4b17023SJohn Marino       operator--(int) noexcept
367e4b17023SJohn Marino       { return fetch_sub(1); }
368e4b17023SJohn Marino 
369e4b17023SJohn Marino       __int_type
370e4b17023SJohn Marino       operator--(int) volatile noexcept
371e4b17023SJohn Marino       { return fetch_sub(1); }
372e4b17023SJohn Marino 
373e4b17023SJohn Marino       __int_type
374e4b17023SJohn Marino       operator++() noexcept
375e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
376e4b17023SJohn Marino 
377e4b17023SJohn Marino       __int_type
378e4b17023SJohn Marino       operator++() volatile noexcept
379e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_i, 1, memory_order_seq_cst); }
380e4b17023SJohn Marino 
381e4b17023SJohn Marino       __int_type
382e4b17023SJohn Marino       operator--() noexcept
383e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
384e4b17023SJohn Marino 
385e4b17023SJohn Marino       __int_type
386e4b17023SJohn Marino       operator--() volatile noexcept
387e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_i, 1, memory_order_seq_cst); }
388e4b17023SJohn Marino 
389e4b17023SJohn Marino       __int_type
390e4b17023SJohn Marino       operator+=(__int_type __i) noexcept
391e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
392e4b17023SJohn Marino 
393e4b17023SJohn Marino       __int_type
394e4b17023SJohn Marino       operator+=(__int_type __i) volatile noexcept
395e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_i, __i, memory_order_seq_cst); }
396e4b17023SJohn Marino 
397e4b17023SJohn Marino       __int_type
398e4b17023SJohn Marino       operator-=(__int_type __i) noexcept
399e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
400e4b17023SJohn Marino 
401e4b17023SJohn Marino       __int_type
402e4b17023SJohn Marino       operator-=(__int_type __i) volatile noexcept
403e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_i, __i, memory_order_seq_cst); }
404e4b17023SJohn Marino 
405e4b17023SJohn Marino       __int_type
406e4b17023SJohn Marino       operator&=(__int_type __i) noexcept
407e4b17023SJohn Marino       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
408e4b17023SJohn Marino 
409e4b17023SJohn Marino       __int_type
410e4b17023SJohn Marino       operator&=(__int_type __i) volatile noexcept
411e4b17023SJohn Marino       { return __atomic_and_fetch(&_M_i, __i, memory_order_seq_cst); }
412e4b17023SJohn Marino 
413e4b17023SJohn Marino       __int_type
414e4b17023SJohn Marino       operator|=(__int_type __i) noexcept
415e4b17023SJohn Marino       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
416e4b17023SJohn Marino 
417e4b17023SJohn Marino       __int_type
418e4b17023SJohn Marino       operator|=(__int_type __i) volatile noexcept
419e4b17023SJohn Marino       { return __atomic_or_fetch(&_M_i, __i, memory_order_seq_cst); }
420e4b17023SJohn Marino 
421e4b17023SJohn Marino       __int_type
422e4b17023SJohn Marino       operator^=(__int_type __i) noexcept
423e4b17023SJohn Marino       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
424e4b17023SJohn Marino 
425e4b17023SJohn Marino       __int_type
426e4b17023SJohn Marino       operator^=(__int_type __i) volatile noexcept
427e4b17023SJohn Marino       { return __atomic_xor_fetch(&_M_i, __i, memory_order_seq_cst); }
428e4b17023SJohn Marino 
429e4b17023SJohn Marino       bool
430e4b17023SJohn Marino       is_lock_free() const noexcept
431e4b17023SJohn Marino       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
432e4b17023SJohn Marino 
433e4b17023SJohn Marino       bool
434e4b17023SJohn Marino       is_lock_free() const volatile noexcept
435e4b17023SJohn Marino       { return __atomic_is_lock_free (sizeof (_M_i), &_M_i); }
436e4b17023SJohn Marino 
437e4b17023SJohn Marino       void
438e4b17023SJohn Marino       store(__int_type __i, memory_order __m = memory_order_seq_cst) noexcept
439e4b17023SJohn Marino       {
440e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acquire);
441e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
442e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_consume);
443e4b17023SJohn Marino 
444e4b17023SJohn Marino 	__atomic_store_n(&_M_i, __i, __m);
445e4b17023SJohn Marino       }
446e4b17023SJohn Marino 
447e4b17023SJohn Marino       void
448e4b17023SJohn Marino       store(__int_type __i,
449e4b17023SJohn Marino 	    memory_order __m = memory_order_seq_cst) volatile noexcept
450e4b17023SJohn Marino       {
451e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acquire);
452e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
453e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_consume);
454e4b17023SJohn Marino 
455e4b17023SJohn Marino 	__atomic_store_n(&_M_i, __i, __m);
456e4b17023SJohn Marino       }
457e4b17023SJohn Marino 
458e4b17023SJohn Marino       __int_type
459e4b17023SJohn Marino       load(memory_order __m = memory_order_seq_cst) const noexcept
460e4b17023SJohn Marino       {
461e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_release);
462e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
463e4b17023SJohn Marino 
464e4b17023SJohn Marino 	return __atomic_load_n(&_M_i, __m);
465e4b17023SJohn Marino       }
466e4b17023SJohn Marino 
467e4b17023SJohn Marino       __int_type
468e4b17023SJohn Marino       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
469e4b17023SJohn Marino       {
470e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_release);
471e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
472e4b17023SJohn Marino 
473e4b17023SJohn Marino 	return __atomic_load_n(&_M_i, __m);
474e4b17023SJohn Marino       }
475e4b17023SJohn Marino 
476e4b17023SJohn Marino       __int_type
477e4b17023SJohn Marino       exchange(__int_type __i,
478e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) noexcept
479e4b17023SJohn Marino       {
480e4b17023SJohn Marino 	return __atomic_exchange_n(&_M_i, __i, __m);
481e4b17023SJohn Marino       }
482e4b17023SJohn Marino 
483e4b17023SJohn Marino 
484e4b17023SJohn Marino       __int_type
485e4b17023SJohn Marino       exchange(__int_type __i,
486e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) volatile noexcept
487e4b17023SJohn Marino       {
488e4b17023SJohn Marino 	return __atomic_exchange_n(&_M_i, __i, __m);
489e4b17023SJohn Marino       }
490e4b17023SJohn Marino 
491e4b17023SJohn Marino       bool
492e4b17023SJohn Marino       compare_exchange_weak(__int_type& __i1, __int_type __i2,
493e4b17023SJohn Marino 			    memory_order __m1, memory_order __m2) noexcept
494e4b17023SJohn Marino       {
495e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
496e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
497e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
498e4b17023SJohn Marino 
499e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
500e4b17023SJohn Marino       }
501e4b17023SJohn Marino 
502e4b17023SJohn Marino       bool
503e4b17023SJohn Marino       compare_exchange_weak(__int_type& __i1, __int_type __i2,
504e4b17023SJohn Marino 			    memory_order __m1,
505e4b17023SJohn Marino 			    memory_order __m2) volatile noexcept
506e4b17023SJohn Marino       {
507e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
508e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
509e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
510e4b17023SJohn Marino 
511e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 1, __m1, __m2);
512e4b17023SJohn Marino       }
513e4b17023SJohn Marino 
514e4b17023SJohn Marino       bool
515e4b17023SJohn Marino       compare_exchange_weak(__int_type& __i1, __int_type __i2,
516e4b17023SJohn Marino 			    memory_order __m = memory_order_seq_cst) noexcept
517e4b17023SJohn Marino       {
518e4b17023SJohn Marino 	return compare_exchange_weak(__i1, __i2, __m,
519e4b17023SJohn Marino 				     __cmpexch_failure_order(__m));
520e4b17023SJohn Marino       }
521e4b17023SJohn Marino 
522e4b17023SJohn Marino       bool
523e4b17023SJohn Marino       compare_exchange_weak(__int_type& __i1, __int_type __i2,
524e4b17023SJohn Marino 		   memory_order __m = memory_order_seq_cst) volatile noexcept
525e4b17023SJohn Marino       {
526e4b17023SJohn Marino 	return compare_exchange_weak(__i1, __i2, __m,
527e4b17023SJohn Marino 				     __cmpexch_failure_order(__m));
528e4b17023SJohn Marino       }
529e4b17023SJohn Marino 
530e4b17023SJohn Marino       bool
531e4b17023SJohn Marino       compare_exchange_strong(__int_type& __i1, __int_type __i2,
532e4b17023SJohn Marino 			      memory_order __m1, memory_order __m2) noexcept
533e4b17023SJohn Marino       {
534e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
535e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
536e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
537e4b17023SJohn Marino 
538e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
539e4b17023SJohn Marino       }
540e4b17023SJohn Marino 
541e4b17023SJohn Marino       bool
542e4b17023SJohn Marino       compare_exchange_strong(__int_type& __i1, __int_type __i2,
543e4b17023SJohn Marino 			      memory_order __m1,
544e4b17023SJohn Marino 			      memory_order __m2) volatile noexcept
545e4b17023SJohn Marino       {
546e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
547e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
548e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
549e4b17023SJohn Marino 
550e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2);
551e4b17023SJohn Marino       }
552e4b17023SJohn Marino 
553e4b17023SJohn Marino       bool
554e4b17023SJohn Marino       compare_exchange_strong(__int_type& __i1, __int_type __i2,
555e4b17023SJohn Marino 			      memory_order __m = memory_order_seq_cst) noexcept
556e4b17023SJohn Marino       {
557e4b17023SJohn Marino 	return compare_exchange_strong(__i1, __i2, __m,
558e4b17023SJohn Marino 				       __cmpexch_failure_order(__m));
559e4b17023SJohn Marino       }
560e4b17023SJohn Marino 
561e4b17023SJohn Marino       bool
562e4b17023SJohn Marino       compare_exchange_strong(__int_type& __i1, __int_type __i2,
563e4b17023SJohn Marino 		 memory_order __m = memory_order_seq_cst) volatile noexcept
564e4b17023SJohn Marino       {
565e4b17023SJohn Marino 	return compare_exchange_strong(__i1, __i2, __m,
566e4b17023SJohn Marino 				       __cmpexch_failure_order(__m));
567e4b17023SJohn Marino       }
568e4b17023SJohn Marino 
569e4b17023SJohn Marino       __int_type
570e4b17023SJohn Marino       fetch_add(__int_type __i,
571e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
572e4b17023SJohn Marino       { return __atomic_fetch_add(&_M_i, __i, __m); }
573e4b17023SJohn Marino 
574e4b17023SJohn Marino       __int_type
575e4b17023SJohn Marino       fetch_add(__int_type __i,
576e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
577e4b17023SJohn Marino       { return __atomic_fetch_add(&_M_i, __i, __m); }
578e4b17023SJohn Marino 
579e4b17023SJohn Marino       __int_type
580e4b17023SJohn Marino       fetch_sub(__int_type __i,
581e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
582e4b17023SJohn Marino       { return __atomic_fetch_sub(&_M_i, __i, __m); }
583e4b17023SJohn Marino 
584e4b17023SJohn Marino       __int_type
585e4b17023SJohn Marino       fetch_sub(__int_type __i,
586e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
587e4b17023SJohn Marino       { return __atomic_fetch_sub(&_M_i, __i, __m); }
588e4b17023SJohn Marino 
589e4b17023SJohn Marino       __int_type
590e4b17023SJohn Marino       fetch_and(__int_type __i,
591e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
592e4b17023SJohn Marino       { return __atomic_fetch_and(&_M_i, __i, __m); }
593e4b17023SJohn Marino 
594e4b17023SJohn Marino       __int_type
595e4b17023SJohn Marino       fetch_and(__int_type __i,
596e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
597e4b17023SJohn Marino       { return __atomic_fetch_and(&_M_i, __i, __m); }
598e4b17023SJohn Marino 
599e4b17023SJohn Marino       __int_type
600e4b17023SJohn Marino       fetch_or(__int_type __i,
601e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) noexcept
602e4b17023SJohn Marino       { return __atomic_fetch_or(&_M_i, __i, __m); }
603e4b17023SJohn Marino 
604e4b17023SJohn Marino       __int_type
605e4b17023SJohn Marino       fetch_or(__int_type __i,
606e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) volatile noexcept
607e4b17023SJohn Marino       { return __atomic_fetch_or(&_M_i, __i, __m); }
608e4b17023SJohn Marino 
609e4b17023SJohn Marino       __int_type
610e4b17023SJohn Marino       fetch_xor(__int_type __i,
611e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
612e4b17023SJohn Marino       { return __atomic_fetch_xor(&_M_i, __i, __m); }
613e4b17023SJohn Marino 
614e4b17023SJohn Marino       __int_type
615e4b17023SJohn Marino       fetch_xor(__int_type __i,
616e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
617e4b17023SJohn Marino       { return __atomic_fetch_xor(&_M_i, __i, __m); }
618e4b17023SJohn Marino     };
619e4b17023SJohn Marino 
620e4b17023SJohn Marino 
621e4b17023SJohn Marino   /// Partial specialization for pointer types.
622e4b17023SJohn Marino   template<typename _PTp>
623e4b17023SJohn Marino     struct __atomic_base<_PTp*>
624e4b17023SJohn Marino     {
625e4b17023SJohn Marino     private:
626e4b17023SJohn Marino       typedef _PTp* 	__pointer_type;
627e4b17023SJohn Marino 
628e4b17023SJohn Marino       __pointer_type 	_M_p;
629e4b17023SJohn Marino 
630e4b17023SJohn Marino       // Factored out to facilitate explicit specialization.
631e4b17023SJohn Marino       constexpr ptrdiff_t
632e4b17023SJohn Marino       _M_type_size(ptrdiff_t __d) { return __d * sizeof(_PTp); }
633e4b17023SJohn Marino 
634e4b17023SJohn Marino       constexpr ptrdiff_t
635e4b17023SJohn Marino       _M_type_size(ptrdiff_t __d) volatile { return __d * sizeof(_PTp); }
636e4b17023SJohn Marino 
637e4b17023SJohn Marino     public:
638e4b17023SJohn Marino       __atomic_base() noexcept = default;
639e4b17023SJohn Marino       ~__atomic_base() noexcept = default;
640e4b17023SJohn Marino       __atomic_base(const __atomic_base&) = delete;
641e4b17023SJohn Marino       __atomic_base& operator=(const __atomic_base&) = delete;
642e4b17023SJohn Marino       __atomic_base& operator=(const __atomic_base&) volatile = delete;
643e4b17023SJohn Marino 
644e4b17023SJohn Marino       // Requires __pointer_type convertible to _M_p.
645e4b17023SJohn Marino       constexpr __atomic_base(__pointer_type __p) noexcept : _M_p (__p) { }
646e4b17023SJohn Marino 
647e4b17023SJohn Marino       operator __pointer_type() const noexcept
648e4b17023SJohn Marino       { return load(); }
649e4b17023SJohn Marino 
650e4b17023SJohn Marino       operator __pointer_type() const volatile noexcept
651e4b17023SJohn Marino       { return load(); }
652e4b17023SJohn Marino 
653e4b17023SJohn Marino       __pointer_type
654e4b17023SJohn Marino       operator=(__pointer_type __p) noexcept
655e4b17023SJohn Marino       {
656e4b17023SJohn Marino 	store(__p);
657e4b17023SJohn Marino 	return __p;
658e4b17023SJohn Marino       }
659e4b17023SJohn Marino 
660e4b17023SJohn Marino       __pointer_type
661e4b17023SJohn Marino       operator=(__pointer_type __p) volatile noexcept
662e4b17023SJohn Marino       {
663e4b17023SJohn Marino 	store(__p);
664e4b17023SJohn Marino 	return __p;
665e4b17023SJohn Marino       }
666e4b17023SJohn Marino 
667e4b17023SJohn Marino       __pointer_type
668e4b17023SJohn Marino       operator++(int) noexcept
669e4b17023SJohn Marino       { return fetch_add(1); }
670e4b17023SJohn Marino 
671e4b17023SJohn Marino       __pointer_type
672e4b17023SJohn Marino       operator++(int) volatile noexcept
673e4b17023SJohn Marino       { return fetch_add(1); }
674e4b17023SJohn Marino 
675e4b17023SJohn Marino       __pointer_type
676e4b17023SJohn Marino       operator--(int) noexcept
677e4b17023SJohn Marino       { return fetch_sub(1); }
678e4b17023SJohn Marino 
679e4b17023SJohn Marino       __pointer_type
680e4b17023SJohn Marino       operator--(int) volatile noexcept
681e4b17023SJohn Marino       { return fetch_sub(1); }
682e4b17023SJohn Marino 
683e4b17023SJohn Marino       __pointer_type
684e4b17023SJohn Marino       operator++() noexcept
685e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
686e4b17023SJohn Marino 				  memory_order_seq_cst); }
687e4b17023SJohn Marino 
688e4b17023SJohn Marino       __pointer_type
689e4b17023SJohn Marino       operator++() volatile noexcept
690e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_p, _M_type_size(1),
691e4b17023SJohn Marino 				  memory_order_seq_cst); }
692e4b17023SJohn Marino 
693e4b17023SJohn Marino       __pointer_type
694e4b17023SJohn Marino       operator--() noexcept
695e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
696e4b17023SJohn Marino 				  memory_order_seq_cst); }
697e4b17023SJohn Marino 
698e4b17023SJohn Marino       __pointer_type
699e4b17023SJohn Marino       operator--() volatile noexcept
700e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_p, _M_type_size(1),
701e4b17023SJohn Marino 				  memory_order_seq_cst); }
702e4b17023SJohn Marino 
703e4b17023SJohn Marino       __pointer_type
704e4b17023SJohn Marino       operator+=(ptrdiff_t __d) noexcept
705e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
706e4b17023SJohn Marino 				  memory_order_seq_cst); }
707e4b17023SJohn Marino 
708e4b17023SJohn Marino       __pointer_type
709e4b17023SJohn Marino       operator+=(ptrdiff_t __d) volatile noexcept
710e4b17023SJohn Marino       { return __atomic_add_fetch(&_M_p, _M_type_size(__d),
711e4b17023SJohn Marino 				  memory_order_seq_cst); }
712e4b17023SJohn Marino 
713e4b17023SJohn Marino       __pointer_type
714e4b17023SJohn Marino       operator-=(ptrdiff_t __d) noexcept
715e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
716e4b17023SJohn Marino 				  memory_order_seq_cst); }
717e4b17023SJohn Marino 
718e4b17023SJohn Marino       __pointer_type
719e4b17023SJohn Marino       operator-=(ptrdiff_t __d) volatile noexcept
720e4b17023SJohn Marino       { return __atomic_sub_fetch(&_M_p, _M_type_size(__d),
721e4b17023SJohn Marino 				  memory_order_seq_cst); }
722e4b17023SJohn Marino 
723e4b17023SJohn Marino       bool
724e4b17023SJohn Marino       is_lock_free() const noexcept
725*95d28233SJohn Marino       { return __atomic_is_lock_free(sizeof(__pointer_type), &_M_p); }
726e4b17023SJohn Marino 
727e4b17023SJohn Marino       bool
728e4b17023SJohn Marino       is_lock_free() const volatile noexcept
729*95d28233SJohn Marino       { return __atomic_is_lock_free(sizeof(__pointer_type), &_M_p); }
730e4b17023SJohn Marino 
731e4b17023SJohn Marino       void
732e4b17023SJohn Marino       store(__pointer_type __p,
733e4b17023SJohn Marino 	    memory_order __m = memory_order_seq_cst) noexcept
734e4b17023SJohn Marino       {
735e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acquire);
736e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
737e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_consume);
738e4b17023SJohn Marino 
739e4b17023SJohn Marino 	__atomic_store_n(&_M_p, __p, __m);
740e4b17023SJohn Marino       }
741e4b17023SJohn Marino 
742e4b17023SJohn Marino       void
743e4b17023SJohn Marino       store(__pointer_type __p,
744e4b17023SJohn Marino 	    memory_order __m = memory_order_seq_cst) volatile noexcept
745e4b17023SJohn Marino       {
746e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acquire);
747e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
748e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_consume);
749e4b17023SJohn Marino 
750e4b17023SJohn Marino 	__atomic_store_n(&_M_p, __p, __m);
751e4b17023SJohn Marino       }
752e4b17023SJohn Marino 
753e4b17023SJohn Marino       __pointer_type
754e4b17023SJohn Marino       load(memory_order __m = memory_order_seq_cst) const noexcept
755e4b17023SJohn Marino       {
756e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_release);
757e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
758e4b17023SJohn Marino 
759e4b17023SJohn Marino 	return __atomic_load_n(&_M_p, __m);
760e4b17023SJohn Marino       }
761e4b17023SJohn Marino 
762e4b17023SJohn Marino       __pointer_type
763e4b17023SJohn Marino       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
764e4b17023SJohn Marino       {
765e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_release);
766e4b17023SJohn Marino 	__glibcxx_assert(__m != memory_order_acq_rel);
767e4b17023SJohn Marino 
768e4b17023SJohn Marino 	return __atomic_load_n(&_M_p, __m);
769e4b17023SJohn Marino       }
770e4b17023SJohn Marino 
771e4b17023SJohn Marino       __pointer_type
772e4b17023SJohn Marino       exchange(__pointer_type __p,
773e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) noexcept
774e4b17023SJohn Marino       {
775e4b17023SJohn Marino 	return __atomic_exchange_n(&_M_p, __p, __m);
776e4b17023SJohn Marino       }
777e4b17023SJohn Marino 
778e4b17023SJohn Marino 
779e4b17023SJohn Marino       __pointer_type
780e4b17023SJohn Marino       exchange(__pointer_type __p,
781e4b17023SJohn Marino 	       memory_order __m = memory_order_seq_cst) volatile noexcept
782e4b17023SJohn Marino       {
783e4b17023SJohn Marino 	return __atomic_exchange_n(&_M_p, __p, __m);
784e4b17023SJohn Marino       }
785e4b17023SJohn Marino 
786e4b17023SJohn Marino       bool
787e4b17023SJohn Marino       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
788e4b17023SJohn Marino 			      memory_order __m1,
789e4b17023SJohn Marino 			      memory_order __m2) noexcept
790e4b17023SJohn Marino       {
791e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
792e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
793e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
794e4b17023SJohn Marino 
795e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
796e4b17023SJohn Marino       }
797e4b17023SJohn Marino 
798e4b17023SJohn Marino       bool
799e4b17023SJohn Marino       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
800e4b17023SJohn Marino 			      memory_order __m1,
801e4b17023SJohn Marino 			      memory_order __m2) volatile noexcept
802e4b17023SJohn Marino       {
803e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_release);
804e4b17023SJohn Marino 	__glibcxx_assert(__m2 != memory_order_acq_rel);
805e4b17023SJohn Marino 	__glibcxx_assert(__m2 <= __m1);
806e4b17023SJohn Marino 
807e4b17023SJohn Marino 	return __atomic_compare_exchange_n(&_M_p, &__p1, __p2, 0, __m1, __m2);
808e4b17023SJohn Marino       }
809e4b17023SJohn Marino 
810e4b17023SJohn Marino       __pointer_type
811e4b17023SJohn Marino       fetch_add(ptrdiff_t __d,
812e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
813e4b17023SJohn Marino       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
814e4b17023SJohn Marino 
815e4b17023SJohn Marino       __pointer_type
816e4b17023SJohn Marino       fetch_add(ptrdiff_t __d,
817e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
818e4b17023SJohn Marino       { return __atomic_fetch_add(&_M_p, _M_type_size(__d), __m); }
819e4b17023SJohn Marino 
820e4b17023SJohn Marino       __pointer_type
821e4b17023SJohn Marino       fetch_sub(ptrdiff_t __d,
822e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) noexcept
823e4b17023SJohn Marino       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
824e4b17023SJohn Marino 
825e4b17023SJohn Marino       __pointer_type
826e4b17023SJohn Marino       fetch_sub(ptrdiff_t __d,
827e4b17023SJohn Marino 		memory_order __m = memory_order_seq_cst) volatile noexcept
828e4b17023SJohn Marino       { return __atomic_fetch_sub(&_M_p, _M_type_size(__d), __m); }
829e4b17023SJohn Marino     };
830e4b17023SJohn Marino 
831e4b17023SJohn Marino   // @} group atomics
832e4b17023SJohn Marino 
833e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION
834e4b17023SJohn Marino } // namespace std
835e4b17023SJohn Marino 
836e4b17023SJohn Marino #endif
837