]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/atomic
PR c++/89336 - multiple stores in constexpr stmt.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / atomic
CommitLineData
d466a7e2
BK
1// -*- C++ -*- header.
2
a5544970 3// Copyright (C) 2008-2019 Free Software Foundation, Inc.
d466a7e2
BK
4//
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
748086b7 8// Free Software Foundation; either version 3, or (at your option)
d466a7e2
BK
9// any later version.
10
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.
15
748086b7
JJ
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.
19
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/>.
d466a7e2 24
f910786b 25/** @file include/atomic
afd88205 26 * This is a Standard C++ Library header.
d466a7e2
BK
27 */
28
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
31
afd88205
BK
32#ifndef _GLIBCXX_ATOMIC
33#define _GLIBCXX_ATOMIC 1
d466a7e2
BK
34
35#pragma GCC system_header
36
734f5023 37#if __cplusplus < 201103L
ab65a4c7 38# include <bits/c++0x_warning.h>
709def90 39#else
d466a7e2 40
afd88205 41#include <bits/atomic_base.h>
9f9eb84e 42#include <bits/move.h>
d466a7e2 43
12ffa228
BK
44namespace std _GLIBCXX_VISIBILITY(default)
45{
46_GLIBCXX_BEGIN_NAMESPACE_VERSION
d466a7e2 47
5b9daa7e
BK
48 /**
49 * @addtogroup atomics
50 * @{
51 */
52
25999a11 53#if __cplusplus >= 201703L
387edf83
JW
54# define __cpp_lib_atomic_is_always_lock_free 201603
55#endif
56
d31b8797
JW
57 template<typename _Tp>
58 struct atomic;
59
60 /// atomic<bool>
94a86be0 61 // NB: No operators or fetch-operations for this type.
d31b8797
JW
62 template<>
63 struct atomic<bool>
d466a7e2 64 {
25999a11
JW
65 using value_type = bool;
66
94a86be0
BK
67 private:
68 __atomic_base<bool> _M_base;
69
70 public:
d31b8797
JW
71 atomic() noexcept = default;
72 ~atomic() noexcept = default;
73 atomic(const atomic&) = delete;
74 atomic& operator=(const atomic&) = delete;
75 atomic& operator=(const atomic&) volatile = delete;
94a86be0 76
d31b8797 77 constexpr atomic(bool __i) noexcept : _M_base(__i) { }
94a86be0
BK
78
79 bool
bdc05efb 80 operator=(bool __i) noexcept
94a86be0
BK
81 { return _M_base.operator=(__i); }
82
a26f0501
JW
83 bool
84 operator=(bool __i) volatile noexcept
85 { return _M_base.operator=(__i); }
86
bdc05efb 87 operator bool() const noexcept
94a86be0
BK
88 { return _M_base.load(); }
89
bdc05efb 90 operator bool() const volatile noexcept
94a86be0
BK
91 { return _M_base.load(); }
92
93 bool
bdc05efb 94 is_lock_free() const noexcept { return _M_base.is_lock_free(); }
94a86be0
BK
95
96 bool
bdc05efb 97 is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
94a86be0 98
25999a11 99#if __cplusplus >= 201703L
387edf83
JW
100 static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
101#endif
102
94a86be0 103 void
bdc05efb 104 store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
94a86be0
BK
105 { _M_base.store(__i, __m); }
106
107 void
bdc05efb 108 store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
94a86be0
BK
109 { _M_base.store(__i, __m); }
110
111 bool
bdc05efb 112 load(memory_order __m = memory_order_seq_cst) const noexcept
94a86be0
BK
113 { return _M_base.load(__m); }
114
115 bool
bdc05efb 116 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
94a86be0
BK
117 { return _M_base.load(__m); }
118
119 bool
bdc05efb 120 exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
94a86be0
BK
121 { return _M_base.exchange(__i, __m); }
122
123 bool
bdc05efb
PC
124 exchange(bool __i,
125 memory_order __m = memory_order_seq_cst) volatile noexcept
94a86be0
BK
126 { return _M_base.exchange(__i, __m); }
127
128 bool
129 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
bdc05efb 130 memory_order __m2) noexcept
94a86be0
BK
131 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
132
133 bool
134 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
bdc05efb 135 memory_order __m2) volatile noexcept
94a86be0
BK
136 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
137
138 bool
139 compare_exchange_weak(bool& __i1, bool __i2,
bdc05efb 140 memory_order __m = memory_order_seq_cst) noexcept
94a86be0
BK
141 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
142
143 bool
144 compare_exchange_weak(bool& __i1, bool __i2,
bdc05efb 145 memory_order __m = memory_order_seq_cst) volatile noexcept
94a86be0
BK
146 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
147
148 bool
149 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
bdc05efb 150 memory_order __m2) noexcept
94a86be0
BK
151 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
152
153 bool
154 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
bdc05efb 155 memory_order __m2) volatile noexcept
94a86be0
BK
156 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
157
158 bool
159 compare_exchange_strong(bool& __i1, bool __i2,
bdc05efb 160 memory_order __m = memory_order_seq_cst) noexcept
94a86be0
BK
161 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
162
163 bool
164 compare_exchange_strong(bool& __i1, bool __i2,
bdc05efb 165 memory_order __m = memory_order_seq_cst) volatile noexcept
94a86be0
BK
166 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
167 };
d466a7e2 168
d466a7e2 169
d632488a
BK
170 /**
171 * @brief Generic atomic type, primary class template.
172 *
173 * @tparam _Tp Type to be made atomic, must be trivally copyable.
174 */
50ce8d3d
BK
175 template<typename _Tp>
176 struct atomic
177 {
25999a11
JW
178 using value_type = _Tp;
179
50ce8d3d 180 private:
4cbaaa45 181 // Align 1/2/4/8/16-byte types to at least their size.
4280698d 182 static constexpr int _S_min_alignment
4cbaaa45
JW
183 = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
184 ? 0 : sizeof(_Tp);
4280698d
JW
185
186 static constexpr int _S_alignment
187 = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
188
189 alignas(_S_alignment) _Tp _M_i;
d466a7e2 190
bc2da0fc
JW
191 static_assert(__is_trivially_copyable(_Tp),
192 "std::atomic requires a trivially copyable type");
9ffc6d0b
JW
193
194 static_assert(sizeof(_Tp) > 0,
195 "Incomplete or zero-sized types are not supported");
196
50ce8d3d 197 public:
bdc05efb
PC
198 atomic() noexcept = default;
199 ~atomic() noexcept = default;
50ce8d3d 200 atomic(const atomic&) = delete;
94a86be0 201 atomic& operator=(const atomic&) = delete;
afd88205 202 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 203
bdc05efb 204 constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
d466a7e2 205
86951993
AM
206 operator _Tp() const noexcept
207 { return load(); }
d466a7e2 208
86951993
AM
209 operator _Tp() const volatile noexcept
210 { return load(); }
94a86be0 211
afd88205 212 _Tp
33ac58d5 213 operator=(_Tp __i) noexcept
86951993 214 { store(__i); return __i; }
d466a7e2 215
94a86be0 216 _Tp
33ac58d5 217 operator=(_Tp __i) volatile noexcept
86951993 218 { store(__i); return __i; }
94a86be0
BK
219
220 bool
86951993 221 is_lock_free() const noexcept
8be56851
RH
222 {
223 // Produce a fake, minimally aligned pointer.
310055e7 224 return __atomic_is_lock_free(sizeof(_M_i),
63100c54 225 reinterpret_cast<void *>(-_S_alignment));
8be56851 226 }
94a86be0 227
afd88205 228 bool
86951993 229 is_lock_free() const volatile noexcept
8be56851
RH
230 {
231 // Produce a fake, minimally aligned pointer.
310055e7 232 return __atomic_is_lock_free(sizeof(_M_i),
63100c54 233 reinterpret_cast<void *>(-_S_alignment));
8be56851 234 }
d466a7e2 235
25999a11 236#if __cplusplus >= 201703L
387edf83
JW
237 static constexpr bool is_always_lock_free
238 = __atomic_always_lock_free(sizeof(_M_i), 0);
239#endif
240
94a86be0 241 void
227df36e 242 store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
9f9eb84e 243 { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); }
94a86be0 244
afd88205 245 void
227df36e 246 store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
9f9eb84e 247 { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), __m); }
d466a7e2 248
94a86be0 249 _Tp
227df36e 250 load(memory_order __m = memory_order_seq_cst) const noexcept
33ac58d5 251 {
2ae27b70
JW
252 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
253 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
254 __atomic_load(std::__addressof(_M_i), __ptr, __m);
255 return *__ptr;
86951993 256 }
94a86be0 257
afd88205 258 _Tp
227df36e 259 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
33ac58d5 260 {
2ae27b70
JW
261 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
262 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
263 __atomic_load(std::__addressof(_M_i), __ptr, __m);
264 return *__ptr;
86951993 265 }
d466a7e2 266
94a86be0 267 _Tp
227df36e 268 exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
33ac58d5 269 {
2ae27b70
JW
270 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
271 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
9f9eb84e 272 __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
2ae27b70
JW
273 __ptr, __m);
274 return *__ptr;
86951993 275 }
94a86be0 276
afd88205 277 _Tp
33ac58d5 278 exchange(_Tp __i,
227df36e 279 memory_order __m = memory_order_seq_cst) volatile noexcept
33ac58d5 280 {
2ae27b70
JW
281 alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
282 _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
9f9eb84e 283 __atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
2ae27b70
JW
284 __ptr, __m);
285 return *__ptr;
86951993 286 }
d466a7e2 287
94a86be0 288 bool
33ac58d5 289 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
86951993
AM
290 memory_order __f) noexcept
291 {
9f9eb84e
JW
292 return __atomic_compare_exchange(std::__addressof(_M_i),
293 std::__addressof(__e),
294 std::__addressof(__i),
295 true, __s, __f);
86951993 296 }
94a86be0 297
afd88205 298 bool
33ac58d5 299 compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
86951993
AM
300 memory_order __f) volatile noexcept
301 {
9f9eb84e
JW
302 return __atomic_compare_exchange(std::__addressof(_M_i),
303 std::__addressof(__e),
304 std::__addressof(__i),
305 true, __s, __f);
86951993 306 }
d466a7e2 307
afd88205 308 bool
86951993
AM
309 compare_exchange_weak(_Tp& __e, _Tp __i,
310 memory_order __m = memory_order_seq_cst) noexcept
272827e4
NF
311 { return compare_exchange_weak(__e, __i, __m,
312 __cmpexch_failure_order(__m)); }
d466a7e2 313
afd88205 314 bool
86951993
AM
315 compare_exchange_weak(_Tp& __e, _Tp __i,
316 memory_order __m = memory_order_seq_cst) volatile noexcept
272827e4
NF
317 { return compare_exchange_weak(__e, __i, __m,
318 __cmpexch_failure_order(__m)); }
d466a7e2 319
94a86be0 320 bool
33ac58d5 321 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
86951993
AM
322 memory_order __f) noexcept
323 {
9f9eb84e
JW
324 return __atomic_compare_exchange(std::__addressof(_M_i),
325 std::__addressof(__e),
326 std::__addressof(__i),
327 false, __s, __f);
86951993 328 }
94a86be0
BK
329
330 bool
33ac58d5 331 compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
86951993
AM
332 memory_order __f) volatile noexcept
333 {
9f9eb84e
JW
334 return __atomic_compare_exchange(std::__addressof(_M_i),
335 std::__addressof(__e),
336 std::__addressof(__i),
337 false, __s, __f);
86951993 338 }
94a86be0
BK
339
340 bool
86951993
AM
341 compare_exchange_strong(_Tp& __e, _Tp __i,
342 memory_order __m = memory_order_seq_cst) noexcept
272827e4
NF
343 { return compare_exchange_strong(__e, __i, __m,
344 __cmpexch_failure_order(__m)); }
94a86be0 345
afd88205 346 bool
86951993
AM
347 compare_exchange_strong(_Tp& __e, _Tp __i,
348 memory_order __m = memory_order_seq_cst) volatile noexcept
272827e4
NF
349 { return compare_exchange_strong(__e, __i, __m,
350 __cmpexch_failure_order(__m)); }
50ce8d3d 351 };
d466a7e2 352
d466a7e2 353
50ce8d3d 354 /// Partial specialization for pointer types.
afd88205 355 template<typename _Tp>
036e0d4f 356 struct atomic<_Tp*>
50ce8d3d 357 {
25999a11
JW
358 using value_type = _Tp*;
359 using difference_type = ptrdiff_t;
360
036e0d4f
BK
361 typedef _Tp* __pointer_type;
362 typedef __atomic_base<_Tp*> __base_type;
363 __base_type _M_b;
364
bdc05efb
PC
365 atomic() noexcept = default;
366 ~atomic() noexcept = default;
50ce8d3d 367 atomic(const atomic&) = delete;
036e0d4f 368 atomic& operator=(const atomic&) = delete;
afd88205 369 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 370
bdc05efb 371 constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
94a86be0 372
bdc05efb 373 operator __pointer_type() const noexcept
036e0d4f 374 { return __pointer_type(_M_b); }
d466a7e2 375
bdc05efb 376 operator __pointer_type() const volatile noexcept
036e0d4f 377 { return __pointer_type(_M_b); }
d466a7e2 378
036e0d4f 379 __pointer_type
bdc05efb 380 operator=(__pointer_type __p) noexcept
036e0d4f 381 { return _M_b.operator=(__p); }
d466a7e2 382
036e0d4f 383 __pointer_type
bdc05efb 384 operator=(__pointer_type __p) volatile noexcept
036e0d4f 385 { return _M_b.operator=(__p); }
94a86be0 386
036e0d4f 387 __pointer_type
bdc05efb 388 operator++(int) noexcept
25999a11
JW
389 {
390#if __cplusplus >= 201703L
391 static_assert( is_object<_Tp>::value, "pointer to object type" );
392#endif
393 return _M_b++;
394 }
94a86be0 395
036e0d4f 396 __pointer_type
bdc05efb 397 operator++(int) volatile noexcept
25999a11
JW
398 {
399#if __cplusplus >= 201703L
400 static_assert( is_object<_Tp>::value, "pointer to object type" );
401#endif
402 return _M_b++;
403 }
d466a7e2 404
036e0d4f 405 __pointer_type
bdc05efb 406 operator--(int) noexcept
25999a11
JW
407 {
408#if __cplusplus >= 201703L
409 static_assert( is_object<_Tp>::value, "pointer to object type" );
410#endif
411 return _M_b--;
412 }
d466a7e2 413
036e0d4f 414 __pointer_type
bdc05efb 415 operator--(int) volatile noexcept
25999a11
JW
416 {
417#if __cplusplus >= 201703L
418 static_assert( is_object<_Tp>::value, "pointer to object type" );
419#endif
420 return _M_b--;
421 }
d466a7e2 422
036e0d4f 423 __pointer_type
bdc05efb 424 operator++() noexcept
25999a11
JW
425 {
426#if __cplusplus >= 201703L
427 static_assert( is_object<_Tp>::value, "pointer to object type" );
428#endif
429 return ++_M_b;
430 }
d466a7e2 431
036e0d4f 432 __pointer_type
bdc05efb 433 operator++() volatile noexcept
25999a11
JW
434 {
435#if __cplusplus >= 201703L
436 static_assert( is_object<_Tp>::value, "pointer to object type" );
437#endif
438 return ++_M_b;
439 }
94a86be0 440
036e0d4f 441 __pointer_type
bdc05efb 442 operator--() noexcept
25999a11
JW
443 {
444#if __cplusplus >= 201703L
445 static_assert( is_object<_Tp>::value, "pointer to object type" );
446#endif
447 return --_M_b;
448 }
94a86be0 449
036e0d4f 450 __pointer_type
bdc05efb 451 operator--() volatile noexcept
25999a11
JW
452 {
453#if __cplusplus >= 201703L
454 static_assert( is_object<_Tp>::value, "pointer to object type" );
455#endif
456 return --_M_b;
457 }
036e0d4f
BK
458
459 __pointer_type
bdc05efb 460 operator+=(ptrdiff_t __d) noexcept
25999a11
JW
461 {
462#if __cplusplus >= 201703L
463 static_assert( is_object<_Tp>::value, "pointer to object type" );
464#endif
465 return _M_b.operator+=(__d);
466 }
036e0d4f
BK
467
468 __pointer_type
bdc05efb 469 operator+=(ptrdiff_t __d) volatile noexcept
25999a11
JW
470 {
471#if __cplusplus >= 201703L
472 static_assert( is_object<_Tp>::value, "pointer to object type" );
473#endif
474 return _M_b.operator+=(__d);
475 }
036e0d4f
BK
476
477 __pointer_type
bdc05efb 478 operator-=(ptrdiff_t __d) noexcept
25999a11
JW
479 {
480#if __cplusplus >= 201703L
481 static_assert( is_object<_Tp>::value, "pointer to object type" );
482#endif
483 return _M_b.operator-=(__d);
484 }
036e0d4f
BK
485
486 __pointer_type
bdc05efb 487 operator-=(ptrdiff_t __d) volatile noexcept
25999a11
JW
488 {
489#if __cplusplus >= 201703L
490 static_assert( is_object<_Tp>::value, "pointer to object type" );
491#endif
492 return _M_b.operator-=(__d);
493 }
94a86be0 494
afd88205 495 bool
bdc05efb 496 is_lock_free() const noexcept
036e0d4f 497 { return _M_b.is_lock_free(); }
d466a7e2 498
94a86be0 499 bool
bdc05efb 500 is_lock_free() const volatile noexcept
036e0d4f
BK
501 { return _M_b.is_lock_free(); }
502
25999a11 503#if __cplusplus >= 201703L
387edf83
JW
504 static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2;
505#endif
506
036e0d4f 507 void
bdc05efb
PC
508 store(__pointer_type __p,
509 memory_order __m = memory_order_seq_cst) noexcept
036e0d4f
BK
510 { return _M_b.store(__p, __m); }
511
512 void
513 store(__pointer_type __p,
bdc05efb 514 memory_order __m = memory_order_seq_cst) volatile noexcept
036e0d4f 515 { return _M_b.store(__p, __m); }
94a86be0 516
036e0d4f 517 __pointer_type
bdc05efb 518 load(memory_order __m = memory_order_seq_cst) const noexcept
036e0d4f 519 { return _M_b.load(__m); }
d466a7e2 520
036e0d4f 521 __pointer_type
bdc05efb 522 load(memory_order __m = memory_order_seq_cst) const volatile noexcept
036e0d4f 523 { return _M_b.load(__m); }
94a86be0 524
036e0d4f 525 __pointer_type
bdc05efb
PC
526 exchange(__pointer_type __p,
527 memory_order __m = memory_order_seq_cst) noexcept
036e0d4f 528 { return _M_b.exchange(__p, __m); }
d466a7e2 529
036e0d4f
BK
530 __pointer_type
531 exchange(__pointer_type __p,
bdc05efb 532 memory_order __m = memory_order_seq_cst) volatile noexcept
036e0d4f 533 { return _M_b.exchange(__p, __m); }
94a86be0 534
036e0d4f
BK
535 bool
536 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 537 memory_order __m1, memory_order __m2) noexcept
036e0d4f 538 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
d466a7e2 539
036e0d4f
BK
540 bool
541 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
bdc05efb
PC
542 memory_order __m1,
543 memory_order __m2) volatile noexcept
036e0d4f 544 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
94a86be0 545
036e0d4f
BK
546 bool
547 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 548 memory_order __m = memory_order_seq_cst) noexcept
afd88205 549 {
036e0d4f 550 return compare_exchange_weak(__p1, __p2, __m,
3d0c32fe 551 __cmpexch_failure_order(__m));
50ce8d3d 552 }
d466a7e2 553
036e0d4f
BK
554 bool
555 compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 556 memory_order __m = memory_order_seq_cst) volatile noexcept
94a86be0 557 {
036e0d4f 558 return compare_exchange_weak(__p1, __p2, __m,
3d0c32fe 559 __cmpexch_failure_order(__m));
94a86be0
BK
560 }
561
036e0d4f
BK
562 bool
563 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 564 memory_order __m1, memory_order __m2) noexcept
036e0d4f 565 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
d466a7e2 566
036e0d4f
BK
567 bool
568 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
bdc05efb
PC
569 memory_order __m1,
570 memory_order __m2) volatile noexcept
036e0d4f 571 { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
94a86be0 572
036e0d4f
BK
573 bool
574 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 575 memory_order __m = memory_order_seq_cst) noexcept
036e0d4f
BK
576 {
577 return _M_b.compare_exchange_strong(__p1, __p2, __m,
3d0c32fe 578 __cmpexch_failure_order(__m));
036e0d4f 579 }
d466a7e2 580
036e0d4f
BK
581 bool
582 compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
bdc05efb 583 memory_order __m = memory_order_seq_cst) volatile noexcept
036e0d4f
BK
584 {
585 return _M_b.compare_exchange_strong(__p1, __p2, __m,
3d0c32fe 586 __cmpexch_failure_order(__m));
036e0d4f 587 }
94a86be0 588
036e0d4f 589 __pointer_type
bdc05efb
PC
590 fetch_add(ptrdiff_t __d,
591 memory_order __m = memory_order_seq_cst) noexcept
25999a11
JW
592 {
593#if __cplusplus >= 201703L
594 static_assert( is_object<_Tp>::value, "pointer to object type" );
595#endif
596 return _M_b.fetch_add(__d, __m);
597 }
d466a7e2 598
036e0d4f
BK
599 __pointer_type
600 fetch_add(ptrdiff_t __d,
bdc05efb 601 memory_order __m = memory_order_seq_cst) volatile noexcept
25999a11
JW
602 {
603#if __cplusplus >= 201703L
604 static_assert( is_object<_Tp>::value, "pointer to object type" );
605#endif
606 return _M_b.fetch_add(__d, __m);
607 }
94a86be0 608
036e0d4f 609 __pointer_type
bdc05efb
PC
610 fetch_sub(ptrdiff_t __d,
611 memory_order __m = memory_order_seq_cst) noexcept
25999a11
JW
612 {
613#if __cplusplus >= 201703L
614 static_assert( is_object<_Tp>::value, "pointer to object type" );
615#endif
616 return _M_b.fetch_sub(__d, __m);
617 }
d466a7e2 618
036e0d4f
BK
619 __pointer_type
620 fetch_sub(ptrdiff_t __d,
bdc05efb 621 memory_order __m = memory_order_seq_cst) volatile noexcept
25999a11
JW
622 {
623#if __cplusplus >= 201703L
624 static_assert( is_object<_Tp>::value, "pointer to object type" );
625#endif
626 return _M_b.fetch_sub(__d, __m);
627 }
50ce8d3d 628 };
d466a7e2 629
036e0d4f 630
50ce8d3d 631 /// Explicit specialization for char.
afd88205 632 template<>
d31b8797 633 struct atomic<char> : __atomic_base<char>
50ce8d3d
BK
634 {
635 typedef char __integral_type;
d31b8797 636 typedef __atomic_base<char> __base_type;
d466a7e2 637
bdc05efb
PC
638 atomic() noexcept = default;
639 ~atomic() noexcept = default;
50ce8d3d 640 atomic(const atomic&) = delete;
94a86be0 641 atomic& operator=(const atomic&) = delete;
afd88205 642 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 643
bdc05efb 644 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 645
50ce8d3d
BK
646 using __base_type::operator __integral_type;
647 using __base_type::operator=;
387edf83 648
25999a11 649#if __cplusplus >= 201703L
387edf83
JW
650 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
651#endif
50ce8d3d 652 };
d466a7e2 653
50ce8d3d 654 /// Explicit specialization for signed char.
afd88205 655 template<>
d31b8797 656 struct atomic<signed char> : __atomic_base<signed char>
afd88205 657 {
50ce8d3d 658 typedef signed char __integral_type;
d31b8797 659 typedef __atomic_base<signed char> __base_type;
d466a7e2 660
bdc05efb
PC
661 atomic() noexcept= default;
662 ~atomic() noexcept = default;
50ce8d3d 663 atomic(const atomic&) = delete;
94a86be0 664 atomic& operator=(const atomic&) = delete;
afd88205 665 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 666
bdc05efb 667 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 668
50ce8d3d
BK
669 using __base_type::operator __integral_type;
670 using __base_type::operator=;
387edf83 671
25999a11 672#if __cplusplus >= 201703L
387edf83
JW
673 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
674#endif
50ce8d3d 675 };
d466a7e2 676
50ce8d3d 677 /// Explicit specialization for unsigned char.
afd88205 678 template<>
d31b8797 679 struct atomic<unsigned char> : __atomic_base<unsigned char>
50ce8d3d
BK
680 {
681 typedef unsigned char __integral_type;
d31b8797 682 typedef __atomic_base<unsigned char> __base_type;
d466a7e2 683
bdc05efb
PC
684 atomic() noexcept= default;
685 ~atomic() noexcept = default;
50ce8d3d 686 atomic(const atomic&) = delete;
94a86be0 687 atomic& operator=(const atomic&) = delete;
afd88205 688 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 689
bdc05efb 690 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 691
50ce8d3d
BK
692 using __base_type::operator __integral_type;
693 using __base_type::operator=;
387edf83 694
25999a11 695#if __cplusplus >= 201703L
387edf83
JW
696 static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
697#endif
50ce8d3d 698 };
d466a7e2 699
50ce8d3d 700 /// Explicit specialization for short.
afd88205 701 template<>
d31b8797 702 struct atomic<short> : __atomic_base<short>
50ce8d3d
BK
703 {
704 typedef short __integral_type;
d31b8797 705 typedef __atomic_base<short> __base_type;
d466a7e2 706
bdc05efb
PC
707 atomic() noexcept = default;
708 ~atomic() noexcept = default;
50ce8d3d 709 atomic(const atomic&) = delete;
94a86be0 710 atomic& operator=(const atomic&) = delete;
afd88205 711 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 712
bdc05efb 713 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 714
50ce8d3d
BK
715 using __base_type::operator __integral_type;
716 using __base_type::operator=;
387edf83 717
25999a11 718#if __cplusplus >= 201703L
387edf83
JW
719 static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
720#endif
50ce8d3d 721 };
d466a7e2 722
50ce8d3d 723 /// Explicit specialization for unsigned short.
afd88205 724 template<>
d31b8797 725 struct atomic<unsigned short> : __atomic_base<unsigned short>
50ce8d3d
BK
726 {
727 typedef unsigned short __integral_type;
d31b8797 728 typedef __atomic_base<unsigned short> __base_type;
d466a7e2 729
bdc05efb
PC
730 atomic() noexcept = default;
731 ~atomic() noexcept = default;
50ce8d3d 732 atomic(const atomic&) = delete;
94a86be0 733 atomic& operator=(const atomic&) = delete;
afd88205 734 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 735
bdc05efb 736 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 737
50ce8d3d
BK
738 using __base_type::operator __integral_type;
739 using __base_type::operator=;
387edf83 740
25999a11 741#if __cplusplus >= 201703L
387edf83
JW
742 static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
743#endif
50ce8d3d 744 };
d466a7e2 745
50ce8d3d 746 /// Explicit specialization for int.
afd88205 747 template<>
d31b8797 748 struct atomic<int> : __atomic_base<int>
50ce8d3d
BK
749 {
750 typedef int __integral_type;
d31b8797 751 typedef __atomic_base<int> __base_type;
d466a7e2 752
bdc05efb
PC
753 atomic() noexcept = default;
754 ~atomic() noexcept = default;
50ce8d3d 755 atomic(const atomic&) = delete;
94a86be0 756 atomic& operator=(const atomic&) = delete;
afd88205 757 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 758
bdc05efb 759 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 760
50ce8d3d
BK
761 using __base_type::operator __integral_type;
762 using __base_type::operator=;
387edf83 763
25999a11 764#if __cplusplus >= 201703L
387edf83
JW
765 static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
766#endif
50ce8d3d 767 };
d466a7e2 768
50ce8d3d 769 /// Explicit specialization for unsigned int.
afd88205 770 template<>
d31b8797 771 struct atomic<unsigned int> : __atomic_base<unsigned int>
50ce8d3d
BK
772 {
773 typedef unsigned int __integral_type;
d31b8797 774 typedef __atomic_base<unsigned int> __base_type;
d466a7e2 775
bdc05efb
PC
776 atomic() noexcept = default;
777 ~atomic() noexcept = default;
50ce8d3d 778 atomic(const atomic&) = delete;
94a86be0 779 atomic& operator=(const atomic&) = delete;
afd88205 780 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 781
bdc05efb 782 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 783
50ce8d3d
BK
784 using __base_type::operator __integral_type;
785 using __base_type::operator=;
387edf83 786
25999a11 787#if __cplusplus >= 201703L
387edf83
JW
788 static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
789#endif
50ce8d3d 790 };
d466a7e2 791
50ce8d3d 792 /// Explicit specialization for long.
afd88205 793 template<>
d31b8797 794 struct atomic<long> : __atomic_base<long>
50ce8d3d
BK
795 {
796 typedef long __integral_type;
d31b8797 797 typedef __atomic_base<long> __base_type;
d466a7e2 798
bdc05efb
PC
799 atomic() noexcept = default;
800 ~atomic() noexcept = default;
50ce8d3d 801 atomic(const atomic&) = delete;
94a86be0 802 atomic& operator=(const atomic&) = delete;
afd88205 803 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 804
bdc05efb 805 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 806
50ce8d3d
BK
807 using __base_type::operator __integral_type;
808 using __base_type::operator=;
387edf83 809
25999a11 810#if __cplusplus >= 201703L
387edf83
JW
811 static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
812#endif
50ce8d3d 813 };
d466a7e2 814
50ce8d3d 815 /// Explicit specialization for unsigned long.
afd88205 816 template<>
d31b8797 817 struct atomic<unsigned long> : __atomic_base<unsigned long>
50ce8d3d
BK
818 {
819 typedef unsigned long __integral_type;
d31b8797 820 typedef __atomic_base<unsigned long> __base_type;
d466a7e2 821
bdc05efb
PC
822 atomic() noexcept = default;
823 ~atomic() noexcept = default;
50ce8d3d 824 atomic(const atomic&) = delete;
94a86be0 825 atomic& operator=(const atomic&) = delete;
afd88205 826 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 827
bdc05efb 828 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 829
50ce8d3d
BK
830 using __base_type::operator __integral_type;
831 using __base_type::operator=;
387edf83 832
25999a11 833#if __cplusplus >= 201703L
387edf83
JW
834 static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
835#endif
50ce8d3d 836 };
d466a7e2 837
50ce8d3d 838 /// Explicit specialization for long long.
afd88205 839 template<>
d31b8797 840 struct atomic<long long> : __atomic_base<long long>
50ce8d3d
BK
841 {
842 typedef long long __integral_type;
d31b8797 843 typedef __atomic_base<long long> __base_type;
d466a7e2 844
bdc05efb
PC
845 atomic() noexcept = default;
846 ~atomic() noexcept = default;
50ce8d3d 847 atomic(const atomic&) = delete;
94a86be0 848 atomic& operator=(const atomic&) = delete;
afd88205 849 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 850
bdc05efb 851 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 852
50ce8d3d
BK
853 using __base_type::operator __integral_type;
854 using __base_type::operator=;
387edf83 855
25999a11 856#if __cplusplus >= 201703L
387edf83
JW
857 static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
858#endif
50ce8d3d 859 };
d466a7e2 860
50ce8d3d 861 /// Explicit specialization for unsigned long long.
afd88205 862 template<>
d31b8797 863 struct atomic<unsigned long long> : __atomic_base<unsigned long long>
50ce8d3d
BK
864 {
865 typedef unsigned long long __integral_type;
d31b8797 866 typedef __atomic_base<unsigned long long> __base_type;
d466a7e2 867
bdc05efb
PC
868 atomic() noexcept = default;
869 ~atomic() noexcept = default;
50ce8d3d 870 atomic(const atomic&) = delete;
94a86be0 871 atomic& operator=(const atomic&) = delete;
afd88205 872 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 873
bdc05efb 874 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 875
50ce8d3d
BK
876 using __base_type::operator __integral_type;
877 using __base_type::operator=;
387edf83 878
25999a11 879#if __cplusplus >= 201703L
387edf83
JW
880 static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
881#endif
50ce8d3d 882 };
d466a7e2 883
50ce8d3d 884 /// Explicit specialization for wchar_t.
afd88205 885 template<>
d31b8797 886 struct atomic<wchar_t> : __atomic_base<wchar_t>
50ce8d3d
BK
887 {
888 typedef wchar_t __integral_type;
d31b8797 889 typedef __atomic_base<wchar_t> __base_type;
d466a7e2 890
bdc05efb
PC
891 atomic() noexcept = default;
892 ~atomic() noexcept = default;
50ce8d3d 893 atomic(const atomic&) = delete;
94a86be0 894 atomic& operator=(const atomic&) = delete;
afd88205 895 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 896
bdc05efb 897 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 898
50ce8d3d
BK
899 using __base_type::operator __integral_type;
900 using __base_type::operator=;
387edf83 901
25999a11 902#if __cplusplus >= 201703L
387edf83
JW
903 static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
904#endif
50ce8d3d 905 };
d466a7e2 906
50ce8d3d 907 /// Explicit specialization for char16_t.
afd88205 908 template<>
d31b8797 909 struct atomic<char16_t> : __atomic_base<char16_t>
50ce8d3d
BK
910 {
911 typedef char16_t __integral_type;
d31b8797 912 typedef __atomic_base<char16_t> __base_type;
d466a7e2 913
bdc05efb
PC
914 atomic() noexcept = default;
915 ~atomic() noexcept = default;
50ce8d3d 916 atomic(const atomic&) = delete;
94a86be0 917 atomic& operator=(const atomic&) = delete;
afd88205 918 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 919
bdc05efb 920 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 921
50ce8d3d
BK
922 using __base_type::operator __integral_type;
923 using __base_type::operator=;
387edf83 924
25999a11 925#if __cplusplus >= 201703L
387edf83
JW
926 static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2;
927#endif
50ce8d3d 928 };
d466a7e2 929
50ce8d3d 930 /// Explicit specialization for char32_t.
afd88205 931 template<>
d31b8797 932 struct atomic<char32_t> : __atomic_base<char32_t>
50ce8d3d
BK
933 {
934 typedef char32_t __integral_type;
d31b8797 935 typedef __atomic_base<char32_t> __base_type;
d466a7e2 936
bdc05efb
PC
937 atomic() noexcept = default;
938 ~atomic() noexcept = default;
50ce8d3d 939 atomic(const atomic&) = delete;
94a86be0 940 atomic& operator=(const atomic&) = delete;
afd88205 941 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 942
bdc05efb 943 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 944
50ce8d3d
BK
945 using __base_type::operator __integral_type;
946 using __base_type::operator=;
387edf83 947
25999a11 948#if __cplusplus >= 201703L
387edf83
JW
949 static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2;
950#endif
50ce8d3d 951 };
d466a7e2 952
94a86be0 953
d31b8797
JW
954 /// atomic_bool
955 typedef atomic<bool> atomic_bool;
956
957 /// atomic_char
958 typedef atomic<char> atomic_char;
959
960 /// atomic_schar
961 typedef atomic<signed char> atomic_schar;
962
963 /// atomic_uchar
964 typedef atomic<unsigned char> atomic_uchar;
965
966 /// atomic_short
967 typedef atomic<short> atomic_short;
968
969 /// atomic_ushort
970 typedef atomic<unsigned short> atomic_ushort;
971
972 /// atomic_int
973 typedef atomic<int> atomic_int;
974
975 /// atomic_uint
976 typedef atomic<unsigned int> atomic_uint;
977
978 /// atomic_long
979 typedef atomic<long> atomic_long;
980
981 /// atomic_ulong
982 typedef atomic<unsigned long> atomic_ulong;
983
984 /// atomic_llong
985 typedef atomic<long long> atomic_llong;
986
987 /// atomic_ullong
988 typedef atomic<unsigned long long> atomic_ullong;
989
990 /// atomic_wchar_t
991 typedef atomic<wchar_t> atomic_wchar_t;
992
993 /// atomic_char16_t
994 typedef atomic<char16_t> atomic_char16_t;
995
996 /// atomic_char32_t
997 typedef atomic<char32_t> atomic_char32_t;
998
1b36f603 999#ifdef _GLIBCXX_USE_C99_STDINT_TR1
e87b7d52
JW
1000 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1001 // 2441. Exact-width atomic typedefs should be provided
1002
1003 /// atomic_int8_t
1004 typedef atomic<int8_t> atomic_int8_t;
1005
1006 /// atomic_uint8_t
1007 typedef atomic<uint8_t> atomic_uint8_t;
1008
1009 /// atomic_int16_t
1010 typedef atomic<int16_t> atomic_int16_t;
1011
1012 /// atomic_uint16_t
1013 typedef atomic<uint16_t> atomic_uint16_t;
1014
1015 /// atomic_int32_t
1016 typedef atomic<int32_t> atomic_int32_t;
1017
1018 /// atomic_uint32_t
1019 typedef atomic<uint32_t> atomic_uint32_t;
1020
1021 /// atomic_int64_t
1022 typedef atomic<int64_t> atomic_int64_t;
1023
1024 /// atomic_uint64_t
1025 typedef atomic<uint64_t> atomic_uint64_t;
1026
1027
d31b8797
JW
1028 /// atomic_int_least8_t
1029 typedef atomic<int_least8_t> atomic_int_least8_t;
1030
1031 /// atomic_uint_least8_t
1032 typedef atomic<uint_least8_t> atomic_uint_least8_t;
1033
1034 /// atomic_int_least16_t
1035 typedef atomic<int_least16_t> atomic_int_least16_t;
1036
1037 /// atomic_uint_least16_t
1038 typedef atomic<uint_least16_t> atomic_uint_least16_t;
1039
1040 /// atomic_int_least32_t
1041 typedef atomic<int_least32_t> atomic_int_least32_t;
1042
1043 /// atomic_uint_least32_t
1044 typedef atomic<uint_least32_t> atomic_uint_least32_t;
1045
1046 /// atomic_int_least64_t
1047 typedef atomic<int_least64_t> atomic_int_least64_t;
1048
1049 /// atomic_uint_least64_t
1050 typedef atomic<uint_least64_t> atomic_uint_least64_t;
1051
1052
1053 /// atomic_int_fast8_t
1054 typedef atomic<int_fast8_t> atomic_int_fast8_t;
1055
1056 /// atomic_uint_fast8_t
1057 typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1058
1059 /// atomic_int_fast16_t
1060 typedef atomic<int_fast16_t> atomic_int_fast16_t;
1061
1062 /// atomic_uint_fast16_t
1063 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1064
1065 /// atomic_int_fast32_t
1066 typedef atomic<int_fast32_t> atomic_int_fast32_t;
1067
1068 /// atomic_uint_fast32_t
1069 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1070
1071 /// atomic_int_fast64_t
1072 typedef atomic<int_fast64_t> atomic_int_fast64_t;
1073
1074 /// atomic_uint_fast64_t
1075 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1b36f603 1076#endif
d31b8797
JW
1077
1078
1079 /// atomic_intptr_t
1080 typedef atomic<intptr_t> atomic_intptr_t;
1081
1082 /// atomic_uintptr_t
1083 typedef atomic<uintptr_t> atomic_uintptr_t;
1084
1085 /// atomic_size_t
1086 typedef atomic<size_t> atomic_size_t;
1087
1b36f603
JW
1088 /// atomic_ptrdiff_t
1089 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1090
1091#ifdef _GLIBCXX_USE_C99_STDINT_TR1
d31b8797
JW
1092 /// atomic_intmax_t
1093 typedef atomic<intmax_t> atomic_intmax_t;
1094
1095 /// atomic_uintmax_t
1096 typedef atomic<uintmax_t> atomic_uintmax_t;
1b36f603 1097#endif
d31b8797 1098
94a86be0 1099 // Function definitions, atomic_flag operations.
afd88205 1100 inline bool
bdc05efb
PC
1101 atomic_flag_test_and_set_explicit(atomic_flag* __a,
1102 memory_order __m) noexcept
50ce8d3d 1103 { return __a->test_and_set(__m); }
d466a7e2 1104
94a86be0 1105 inline bool
036e0d4f 1106 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
bdc05efb 1107 memory_order __m) noexcept
94a86be0
BK
1108 { return __a->test_and_set(__m); }
1109
afd88205 1110 inline void
bdc05efb 1111 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
94a86be0
BK
1112 { __a->clear(__m); }
1113
1114 inline void
bdc05efb
PC
1115 atomic_flag_clear_explicit(volatile atomic_flag* __a,
1116 memory_order __m) noexcept
94a86be0 1117 { __a->clear(__m); }
d466a7e2 1118
94a86be0 1119 inline bool
bdc05efb 1120 atomic_flag_test_and_set(atomic_flag* __a) noexcept
94a86be0 1121 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
d466a7e2 1122
94a86be0 1123 inline bool
bdc05efb 1124 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
94a86be0
BK
1125 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1126
1127 inline void
bdc05efb 1128 atomic_flag_clear(atomic_flag* __a) noexcept
94a86be0
BK
1129 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1130
1131 inline void
bdc05efb 1132 atomic_flag_clear(volatile atomic_flag* __a) noexcept
94a86be0 1133 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
94a86be0 1134
d466a7e2 1135
25999a11
JW
1136 template<typename _Tp>
1137 using __atomic_val_t = typename atomic<_Tp>::value_type;
1138 template<typename _Tp>
1139 using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1140
1141 // [atomics.nonmembers] Non-member functions.
036e0d4f 1142 // Function templates generally applicable to atomic types.
94a86be0
BK
1143 template<typename _ITp>
1144 inline bool
bdc05efb 1145 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
94a86be0
BK
1146 { return __a->is_lock_free(); }
1147
1148 template<typename _ITp>
1149 inline bool
bdc05efb 1150 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
94a86be0
BK
1151 { return __a->is_lock_free(); }
1152
1153 template<typename _ITp>
036e0d4f 1154 inline void
25999a11 1155 atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
0e4974d6 1156 { __a->store(__i, memory_order_relaxed); }
94a86be0
BK
1157
1158 template<typename _ITp>
036e0d4f 1159 inline void
25999a11 1160 atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
0e4974d6 1161 { __a->store(__i, memory_order_relaxed); }
d466a7e2 1162
50ce8d3d 1163 template<typename _ITp>
afd88205 1164 inline void
25999a11 1165 atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1166 memory_order __m) noexcept
50ce8d3d
BK
1167 { __a->store(__i, __m); }
1168
94a86be0
BK
1169 template<typename _ITp>
1170 inline void
25999a11 1171 atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1172 memory_order __m) noexcept
94a86be0
BK
1173 { __a->store(__i, __m); }
1174
50ce8d3d
BK
1175 template<typename _ITp>
1176 inline _ITp
bdc05efb 1177 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
afd88205 1178 { return __a->load(__m); }
50ce8d3d 1179
94a86be0
BK
1180 template<typename _ITp>
1181 inline _ITp
036e0d4f 1182 atomic_load_explicit(const volatile atomic<_ITp>* __a,
bdc05efb 1183 memory_order __m) noexcept
94a86be0
BK
1184 { return __a->load(__m); }
1185
50ce8d3d 1186 template<typename _ITp>
afd88205 1187 inline _ITp
25999a11 1188 atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1189 memory_order __m) noexcept
afd88205 1190 { return __a->exchange(__i, __m); }
50ce8d3d 1191
94a86be0
BK
1192 template<typename _ITp>
1193 inline _ITp
25999a11
JW
1194 atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1195 __atomic_val_t<_ITp> __i,
bdc05efb 1196 memory_order __m) noexcept
94a86be0
BK
1197 { return __a->exchange(__i, __m); }
1198
50ce8d3d 1199 template<typename _ITp>
afd88205 1200 inline bool
036e0d4f 1201 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
25999a11
JW
1202 __atomic_val_t<_ITp>* __i1,
1203 __atomic_val_t<_ITp> __i2,
bdc05efb
PC
1204 memory_order __m1,
1205 memory_order __m2) noexcept
50ce8d3d 1206 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
d466a7e2 1207
94a86be0
BK
1208 template<typename _ITp>
1209 inline bool
036e0d4f 1210 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
25999a11
JW
1211 __atomic_val_t<_ITp>* __i1,
1212 __atomic_val_t<_ITp> __i2,
bdc05efb
PC
1213 memory_order __m1,
1214 memory_order __m2) noexcept
94a86be0
BK
1215 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1216
50ce8d3d 1217 template<typename _ITp>
afd88205 1218 inline bool
036e0d4f 1219 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
25999a11
JW
1220 __atomic_val_t<_ITp>* __i1,
1221 __atomic_val_t<_ITp> __i2,
afd88205 1222 memory_order __m1,
bdc05efb 1223 memory_order __m2) noexcept
50ce8d3d
BK
1224 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1225
94a86be0
BK
1226 template<typename _ITp>
1227 inline bool
036e0d4f 1228 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
25999a11
JW
1229 __atomic_val_t<_ITp>* __i1,
1230 __atomic_val_t<_ITp> __i2,
94a86be0 1231 memory_order __m1,
bdc05efb 1232 memory_order __m2) noexcept
94a86be0
BK
1233 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1234
d466a7e2 1235
50ce8d3d 1236 template<typename _ITp>
afd88205 1237 inline void
25999a11 1238 atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1239 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1240
94a86be0
BK
1241 template<typename _ITp>
1242 inline void
25999a11 1243 atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1244 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1245
50ce8d3d 1246 template<typename _ITp>
afd88205 1247 inline _ITp
bdc05efb 1248 atomic_load(const atomic<_ITp>* __a) noexcept
50ce8d3d 1249 { return atomic_load_explicit(__a, memory_order_seq_cst); }
d466a7e2 1250
94a86be0
BK
1251 template<typename _ITp>
1252 inline _ITp
bdc05efb 1253 atomic_load(const volatile atomic<_ITp>* __a) noexcept
94a86be0
BK
1254 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1255
50ce8d3d 1256 template<typename _ITp>
afd88205 1257 inline _ITp
25999a11 1258 atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1259 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1260
94a86be0
BK
1261 template<typename _ITp>
1262 inline _ITp
25999a11
JW
1263 atomic_exchange(volatile atomic<_ITp>* __a,
1264 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1265 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1266
50ce8d3d 1267 template<typename _ITp>
afd88205 1268 inline bool
036e0d4f 1269 atomic_compare_exchange_weak(atomic<_ITp>* __a,
25999a11
JW
1270 __atomic_val_t<_ITp>* __i1,
1271 __atomic_val_t<_ITp> __i2) noexcept
afd88205
BK
1272 {
1273 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
50ce8d3d 1274 memory_order_seq_cst,
afd88205 1275 memory_order_seq_cst);
d466a7e2
BK
1276 }
1277
94a86be0
BK
1278 template<typename _ITp>
1279 inline bool
036e0d4f 1280 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
25999a11
JW
1281 __atomic_val_t<_ITp>* __i1,
1282 __atomic_val_t<_ITp> __i2) noexcept
94a86be0
BK
1283 {
1284 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1285 memory_order_seq_cst,
1286 memory_order_seq_cst);
1287 }
1288
50ce8d3d 1289 template<typename _ITp>
afd88205 1290 inline bool
036e0d4f 1291 atomic_compare_exchange_strong(atomic<_ITp>* __a,
25999a11
JW
1292 __atomic_val_t<_ITp>* __i1,
1293 __atomic_val_t<_ITp> __i2) noexcept
afd88205
BK
1294 {
1295 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
50ce8d3d 1296 memory_order_seq_cst,
afd88205 1297 memory_order_seq_cst);
d466a7e2
BK
1298 }
1299
94a86be0
BK
1300 template<typename _ITp>
1301 inline bool
036e0d4f 1302 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
25999a11
JW
1303 __atomic_val_t<_ITp>* __i1,
1304 __atomic_val_t<_ITp> __i2) noexcept
94a86be0
BK
1305 {
1306 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1307 memory_order_seq_cst,
1308 memory_order_seq_cst);
1309 }
1310
25999a11
JW
1311 // Function templates for atomic_integral and atomic_pointer operations only.
1312 // Some operations (and, or, xor) are only available for atomic integrals,
1313 // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1314
036e0d4f
BK
1315 template<typename _ITp>
1316 inline _ITp
25999a11
JW
1317 atomic_fetch_add_explicit(atomic<_ITp>* __a,
1318 __atomic_diff_t<_ITp> __i,
bdc05efb 1319 memory_order __m) noexcept
036e0d4f
BK
1320 { return __a->fetch_add(__i, __m); }
1321
1322 template<typename _ITp>
1323 inline _ITp
25999a11
JW
1324 atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1325 __atomic_diff_t<_ITp> __i,
bdc05efb 1326 memory_order __m) noexcept
036e0d4f
BK
1327 { return __a->fetch_add(__i, __m); }
1328
1329 template<typename _ITp>
1330 inline _ITp
25999a11
JW
1331 atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1332 __atomic_diff_t<_ITp> __i,
bdc05efb 1333 memory_order __m) noexcept
036e0d4f
BK
1334 { return __a->fetch_sub(__i, __m); }
1335
1336 template<typename _ITp>
1337 inline _ITp
25999a11
JW
1338 atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1339 __atomic_diff_t<_ITp> __i,
bdc05efb 1340 memory_order __m) noexcept
036e0d4f
BK
1341 { return __a->fetch_sub(__i, __m); }
1342
1343 template<typename _ITp>
1344 inline _ITp
25999a11
JW
1345 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1346 __atomic_val_t<_ITp> __i,
bdc05efb 1347 memory_order __m) noexcept
036e0d4f
BK
1348 { return __a->fetch_and(__i, __m); }
1349
1350 template<typename _ITp>
1351 inline _ITp
25999a11
JW
1352 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1353 __atomic_val_t<_ITp> __i,
bdc05efb 1354 memory_order __m) noexcept
036e0d4f
BK
1355 { return __a->fetch_and(__i, __m); }
1356
1357 template<typename _ITp>
1358 inline _ITp
25999a11
JW
1359 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1360 __atomic_val_t<_ITp> __i,
bdc05efb 1361 memory_order __m) noexcept
036e0d4f
BK
1362 { return __a->fetch_or(__i, __m); }
1363
1364 template<typename _ITp>
1365 inline _ITp
25999a11
JW
1366 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1367 __atomic_val_t<_ITp> __i,
bdc05efb 1368 memory_order __m) noexcept
036e0d4f
BK
1369 { return __a->fetch_or(__i, __m); }
1370
1371 template<typename _ITp>
1372 inline _ITp
25999a11
JW
1373 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1374 __atomic_val_t<_ITp> __i,
bdc05efb 1375 memory_order __m) noexcept
036e0d4f
BK
1376 { return __a->fetch_xor(__i, __m); }
1377
1378 template<typename _ITp>
1379 inline _ITp
25999a11
JW
1380 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1381 __atomic_val_t<_ITp> __i,
bdc05efb 1382 memory_order __m) noexcept
036e0d4f
BK
1383 { return __a->fetch_xor(__i, __m); }
1384
50ce8d3d 1385 template<typename _ITp>
afd88205 1386 inline _ITp
25999a11
JW
1387 atomic_fetch_add(atomic<_ITp>* __a,
1388 __atomic_diff_t<_ITp> __i) noexcept
50ce8d3d
BK
1389 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1390
94a86be0
BK
1391 template<typename _ITp>
1392 inline _ITp
25999a11
JW
1393 atomic_fetch_add(volatile atomic<_ITp>* __a,
1394 __atomic_diff_t<_ITp> __i) noexcept
94a86be0
BK
1395 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1396
50ce8d3d 1397 template<typename _ITp>
afd88205 1398 inline _ITp
25999a11
JW
1399 atomic_fetch_sub(atomic<_ITp>* __a,
1400 __atomic_diff_t<_ITp> __i) noexcept
50ce8d3d
BK
1401 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1402
94a86be0
BK
1403 template<typename _ITp>
1404 inline _ITp
25999a11
JW
1405 atomic_fetch_sub(volatile atomic<_ITp>* __a,
1406 __atomic_diff_t<_ITp> __i) noexcept
94a86be0
BK
1407 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1408
50ce8d3d 1409 template<typename _ITp>
afd88205 1410 inline _ITp
25999a11
JW
1411 atomic_fetch_and(__atomic_base<_ITp>* __a,
1412 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d
BK
1413 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1414
94a86be0
BK
1415 template<typename _ITp>
1416 inline _ITp
25999a11
JW
1417 atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1418 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1419 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1420
50ce8d3d 1421 template<typename _ITp>
afd88205 1422 inline _ITp
25999a11
JW
1423 atomic_fetch_or(__atomic_base<_ITp>* __a,
1424 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d
BK
1425 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1426
94a86be0
BK
1427 template<typename _ITp>
1428 inline _ITp
25999a11
JW
1429 atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1430 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1431 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1432
50ce8d3d 1433 template<typename _ITp>
afd88205 1434 inline _ITp
25999a11
JW
1435 atomic_fetch_xor(__atomic_base<_ITp>* __a,
1436 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1437 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1438
94a86be0
BK
1439 template<typename _ITp>
1440 inline _ITp
25999a11
JW
1441 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1442 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1443 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1444
5b9daa7e
BK
1445 // @} group atomics
1446
12ffa228
BK
1447_GLIBCXX_END_NAMESPACE_VERSION
1448} // namespace
d466a7e2 1449
709def90
PC
1450#endif // C++11
1451
1452#endif // _GLIBCXX_ATOMIC