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