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