]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/atomic
i386: Add AVX512 unaligned intrinsics
[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
8b9482b2 243 { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); }
94a86be0 244
afd88205 245 void
227df36e 246 store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
8b9482b2 247 { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__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);
8b9482b2 254 __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2ae27b70 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);
8b9482b2 263 __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2ae27b70 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),
8b9482b2 273 __ptr, int(__m));
2ae27b70 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),
8b9482b2 284 __ptr, int(__m));
2ae27b70 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),
8b9482b2 295 true, int(__s), int(__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),
8b9482b2 305 true, int(__s), int(__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),
8b9482b2 327 false, int(__s), int(__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),
8b9482b2 337 false, int(__s), int(__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
c124af93
TH
907#ifdef _GLIBCXX_USE_CHAR8_T
908 /// Explicit specialization for char8_t.
909 template<>
910 struct atomic<char8_t> : __atomic_base<char8_t>
911 {
912 typedef char8_t __integral_type;
913 typedef __atomic_base<char8_t> __base_type;
914
915 atomic() noexcept = default;
916 ~atomic() noexcept = default;
917 atomic(const atomic&) = delete;
918 atomic& operator=(const atomic&) = delete;
919 atomic& operator=(const atomic&) volatile = delete;
920
921 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
922
923 using __base_type::operator __integral_type;
924 using __base_type::operator=;
925
926#if __cplusplus > 201402L
927 static constexpr bool is_always_lock_free = ATOMIC_CHAR8_T_LOCK_FREE == 2;
928#endif
929 };
930#endif
931
50ce8d3d 932 /// Explicit specialization for char16_t.
afd88205 933 template<>
d31b8797 934 struct atomic<char16_t> : __atomic_base<char16_t>
50ce8d3d
BK
935 {
936 typedef char16_t __integral_type;
d31b8797 937 typedef __atomic_base<char16_t> __base_type;
d466a7e2 938
bdc05efb
PC
939 atomic() noexcept = default;
940 ~atomic() noexcept = default;
50ce8d3d 941 atomic(const atomic&) = delete;
94a86be0 942 atomic& operator=(const atomic&) = delete;
afd88205 943 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 944
bdc05efb 945 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 946
50ce8d3d
BK
947 using __base_type::operator __integral_type;
948 using __base_type::operator=;
387edf83 949
25999a11 950#if __cplusplus >= 201703L
387edf83
JW
951 static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2;
952#endif
50ce8d3d 953 };
d466a7e2 954
50ce8d3d 955 /// Explicit specialization for char32_t.
afd88205 956 template<>
d31b8797 957 struct atomic<char32_t> : __atomic_base<char32_t>
50ce8d3d
BK
958 {
959 typedef char32_t __integral_type;
d31b8797 960 typedef __atomic_base<char32_t> __base_type;
d466a7e2 961
bdc05efb
PC
962 atomic() noexcept = default;
963 ~atomic() noexcept = default;
50ce8d3d 964 atomic(const atomic&) = delete;
94a86be0 965 atomic& operator=(const atomic&) = delete;
afd88205 966 atomic& operator=(const atomic&) volatile = delete;
d466a7e2 967
bdc05efb 968 constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
d466a7e2 969
50ce8d3d
BK
970 using __base_type::operator __integral_type;
971 using __base_type::operator=;
387edf83 972
25999a11 973#if __cplusplus >= 201703L
387edf83
JW
974 static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2;
975#endif
50ce8d3d 976 };
d466a7e2 977
94a86be0 978
d31b8797
JW
979 /// atomic_bool
980 typedef atomic<bool> atomic_bool;
981
982 /// atomic_char
983 typedef atomic<char> atomic_char;
984
985 /// atomic_schar
986 typedef atomic<signed char> atomic_schar;
987
988 /// atomic_uchar
989 typedef atomic<unsigned char> atomic_uchar;
990
991 /// atomic_short
992 typedef atomic<short> atomic_short;
993
994 /// atomic_ushort
995 typedef atomic<unsigned short> atomic_ushort;
996
997 /// atomic_int
998 typedef atomic<int> atomic_int;
999
1000 /// atomic_uint
1001 typedef atomic<unsigned int> atomic_uint;
1002
1003 /// atomic_long
1004 typedef atomic<long> atomic_long;
1005
1006 /// atomic_ulong
1007 typedef atomic<unsigned long> atomic_ulong;
1008
1009 /// atomic_llong
1010 typedef atomic<long long> atomic_llong;
1011
1012 /// atomic_ullong
1013 typedef atomic<unsigned long long> atomic_ullong;
1014
1015 /// atomic_wchar_t
1016 typedef atomic<wchar_t> atomic_wchar_t;
1017
c124af93
TH
1018#ifdef _GLIBCXX_USE_CHAR8_T
1019 /// atomic_char8_t
1020 typedef atomic<char8_t> atomic_char8_t;
1021#endif
1022
d31b8797
JW
1023 /// atomic_char16_t
1024 typedef atomic<char16_t> atomic_char16_t;
1025
1026 /// atomic_char32_t
1027 typedef atomic<char32_t> atomic_char32_t;
1028
1b36f603 1029#ifdef _GLIBCXX_USE_C99_STDINT_TR1
e87b7d52
JW
1030 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1031 // 2441. Exact-width atomic typedefs should be provided
1032
1033 /// atomic_int8_t
1034 typedef atomic<int8_t> atomic_int8_t;
1035
1036 /// atomic_uint8_t
1037 typedef atomic<uint8_t> atomic_uint8_t;
1038
1039 /// atomic_int16_t
1040 typedef atomic<int16_t> atomic_int16_t;
1041
1042 /// atomic_uint16_t
1043 typedef atomic<uint16_t> atomic_uint16_t;
1044
1045 /// atomic_int32_t
1046 typedef atomic<int32_t> atomic_int32_t;
1047
1048 /// atomic_uint32_t
1049 typedef atomic<uint32_t> atomic_uint32_t;
1050
1051 /// atomic_int64_t
1052 typedef atomic<int64_t> atomic_int64_t;
1053
1054 /// atomic_uint64_t
1055 typedef atomic<uint64_t> atomic_uint64_t;
1056
1057
d31b8797
JW
1058 /// atomic_int_least8_t
1059 typedef atomic<int_least8_t> atomic_int_least8_t;
1060
1061 /// atomic_uint_least8_t
1062 typedef atomic<uint_least8_t> atomic_uint_least8_t;
1063
1064 /// atomic_int_least16_t
1065 typedef atomic<int_least16_t> atomic_int_least16_t;
1066
1067 /// atomic_uint_least16_t
1068 typedef atomic<uint_least16_t> atomic_uint_least16_t;
1069
1070 /// atomic_int_least32_t
1071 typedef atomic<int_least32_t> atomic_int_least32_t;
1072
1073 /// atomic_uint_least32_t
1074 typedef atomic<uint_least32_t> atomic_uint_least32_t;
1075
1076 /// atomic_int_least64_t
1077 typedef atomic<int_least64_t> atomic_int_least64_t;
1078
1079 /// atomic_uint_least64_t
1080 typedef atomic<uint_least64_t> atomic_uint_least64_t;
1081
1082
1083 /// atomic_int_fast8_t
1084 typedef atomic<int_fast8_t> atomic_int_fast8_t;
1085
1086 /// atomic_uint_fast8_t
1087 typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1088
1089 /// atomic_int_fast16_t
1090 typedef atomic<int_fast16_t> atomic_int_fast16_t;
1091
1092 /// atomic_uint_fast16_t
1093 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1094
1095 /// atomic_int_fast32_t
1096 typedef atomic<int_fast32_t> atomic_int_fast32_t;
1097
1098 /// atomic_uint_fast32_t
1099 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1100
1101 /// atomic_int_fast64_t
1102 typedef atomic<int_fast64_t> atomic_int_fast64_t;
1103
1104 /// atomic_uint_fast64_t
1105 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1b36f603 1106#endif
d31b8797
JW
1107
1108
1109 /// atomic_intptr_t
1110 typedef atomic<intptr_t> atomic_intptr_t;
1111
1112 /// atomic_uintptr_t
1113 typedef atomic<uintptr_t> atomic_uintptr_t;
1114
1115 /// atomic_size_t
1116 typedef atomic<size_t> atomic_size_t;
1117
1b36f603
JW
1118 /// atomic_ptrdiff_t
1119 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1120
1121#ifdef _GLIBCXX_USE_C99_STDINT_TR1
d31b8797
JW
1122 /// atomic_intmax_t
1123 typedef atomic<intmax_t> atomic_intmax_t;
1124
1125 /// atomic_uintmax_t
1126 typedef atomic<uintmax_t> atomic_uintmax_t;
1b36f603 1127#endif
d31b8797 1128
94a86be0 1129 // Function definitions, atomic_flag operations.
afd88205 1130 inline bool
bdc05efb
PC
1131 atomic_flag_test_and_set_explicit(atomic_flag* __a,
1132 memory_order __m) noexcept
50ce8d3d 1133 { return __a->test_and_set(__m); }
d466a7e2 1134
94a86be0 1135 inline bool
036e0d4f 1136 atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
bdc05efb 1137 memory_order __m) noexcept
94a86be0
BK
1138 { return __a->test_and_set(__m); }
1139
afd88205 1140 inline void
bdc05efb 1141 atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
94a86be0
BK
1142 { __a->clear(__m); }
1143
1144 inline void
bdc05efb
PC
1145 atomic_flag_clear_explicit(volatile atomic_flag* __a,
1146 memory_order __m) noexcept
94a86be0 1147 { __a->clear(__m); }
d466a7e2 1148
94a86be0 1149 inline bool
bdc05efb 1150 atomic_flag_test_and_set(atomic_flag* __a) noexcept
94a86be0 1151 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
d466a7e2 1152
94a86be0 1153 inline bool
bdc05efb 1154 atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
94a86be0
BK
1155 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1156
1157 inline void
bdc05efb 1158 atomic_flag_clear(atomic_flag* __a) noexcept
94a86be0
BK
1159 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1160
1161 inline void
bdc05efb 1162 atomic_flag_clear(volatile atomic_flag* __a) noexcept
94a86be0 1163 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
94a86be0 1164
d466a7e2 1165
25999a11
JW
1166 template<typename _Tp>
1167 using __atomic_val_t = typename atomic<_Tp>::value_type;
1168 template<typename _Tp>
1169 using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1170
1171 // [atomics.nonmembers] Non-member functions.
036e0d4f 1172 // Function templates generally applicable to atomic types.
94a86be0
BK
1173 template<typename _ITp>
1174 inline bool
bdc05efb 1175 atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
94a86be0
BK
1176 { return __a->is_lock_free(); }
1177
1178 template<typename _ITp>
1179 inline bool
bdc05efb 1180 atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
94a86be0
BK
1181 { return __a->is_lock_free(); }
1182
1183 template<typename _ITp>
036e0d4f 1184 inline void
25999a11 1185 atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
0e4974d6 1186 { __a->store(__i, memory_order_relaxed); }
94a86be0
BK
1187
1188 template<typename _ITp>
036e0d4f 1189 inline void
25999a11 1190 atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
0e4974d6 1191 { __a->store(__i, memory_order_relaxed); }
d466a7e2 1192
50ce8d3d 1193 template<typename _ITp>
afd88205 1194 inline void
25999a11 1195 atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1196 memory_order __m) noexcept
50ce8d3d
BK
1197 { __a->store(__i, __m); }
1198
94a86be0
BK
1199 template<typename _ITp>
1200 inline void
25999a11 1201 atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1202 memory_order __m) noexcept
94a86be0
BK
1203 { __a->store(__i, __m); }
1204
50ce8d3d
BK
1205 template<typename _ITp>
1206 inline _ITp
bdc05efb 1207 atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
afd88205 1208 { return __a->load(__m); }
50ce8d3d 1209
94a86be0
BK
1210 template<typename _ITp>
1211 inline _ITp
036e0d4f 1212 atomic_load_explicit(const volatile atomic<_ITp>* __a,
bdc05efb 1213 memory_order __m) noexcept
94a86be0
BK
1214 { return __a->load(__m); }
1215
50ce8d3d 1216 template<typename _ITp>
afd88205 1217 inline _ITp
25999a11 1218 atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
bdc05efb 1219 memory_order __m) noexcept
afd88205 1220 { return __a->exchange(__i, __m); }
50ce8d3d 1221
94a86be0
BK
1222 template<typename _ITp>
1223 inline _ITp
25999a11
JW
1224 atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1225 __atomic_val_t<_ITp> __i,
bdc05efb 1226 memory_order __m) noexcept
94a86be0
BK
1227 { return __a->exchange(__i, __m); }
1228
50ce8d3d 1229 template<typename _ITp>
afd88205 1230 inline bool
036e0d4f 1231 atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
25999a11
JW
1232 __atomic_val_t<_ITp>* __i1,
1233 __atomic_val_t<_ITp> __i2,
bdc05efb
PC
1234 memory_order __m1,
1235 memory_order __m2) noexcept
50ce8d3d 1236 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
d466a7e2 1237
94a86be0
BK
1238 template<typename _ITp>
1239 inline bool
036e0d4f 1240 atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
25999a11
JW
1241 __atomic_val_t<_ITp>* __i1,
1242 __atomic_val_t<_ITp> __i2,
bdc05efb
PC
1243 memory_order __m1,
1244 memory_order __m2) noexcept
94a86be0
BK
1245 { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1246
50ce8d3d 1247 template<typename _ITp>
afd88205 1248 inline bool
036e0d4f 1249 atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
25999a11
JW
1250 __atomic_val_t<_ITp>* __i1,
1251 __atomic_val_t<_ITp> __i2,
afd88205 1252 memory_order __m1,
bdc05efb 1253 memory_order __m2) noexcept
50ce8d3d
BK
1254 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1255
94a86be0
BK
1256 template<typename _ITp>
1257 inline bool
036e0d4f 1258 atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
25999a11
JW
1259 __atomic_val_t<_ITp>* __i1,
1260 __atomic_val_t<_ITp> __i2,
94a86be0 1261 memory_order __m1,
bdc05efb 1262 memory_order __m2) noexcept
94a86be0
BK
1263 { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1264
d466a7e2 1265
50ce8d3d 1266 template<typename _ITp>
afd88205 1267 inline void
25999a11 1268 atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1269 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1270
94a86be0
BK
1271 template<typename _ITp>
1272 inline void
25999a11 1273 atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1274 { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1275
50ce8d3d 1276 template<typename _ITp>
afd88205 1277 inline _ITp
bdc05efb 1278 atomic_load(const atomic<_ITp>* __a) noexcept
50ce8d3d 1279 { return atomic_load_explicit(__a, memory_order_seq_cst); }
d466a7e2 1280
94a86be0
BK
1281 template<typename _ITp>
1282 inline _ITp
bdc05efb 1283 atomic_load(const volatile atomic<_ITp>* __a) noexcept
94a86be0
BK
1284 { return atomic_load_explicit(__a, memory_order_seq_cst); }
1285
50ce8d3d 1286 template<typename _ITp>
afd88205 1287 inline _ITp
25999a11 1288 atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1289 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1290
94a86be0
BK
1291 template<typename _ITp>
1292 inline _ITp
25999a11
JW
1293 atomic_exchange(volatile atomic<_ITp>* __a,
1294 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1295 { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1296
50ce8d3d 1297 template<typename _ITp>
afd88205 1298 inline bool
036e0d4f 1299 atomic_compare_exchange_weak(atomic<_ITp>* __a,
25999a11
JW
1300 __atomic_val_t<_ITp>* __i1,
1301 __atomic_val_t<_ITp> __i2) noexcept
afd88205
BK
1302 {
1303 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
50ce8d3d 1304 memory_order_seq_cst,
afd88205 1305 memory_order_seq_cst);
d466a7e2
BK
1306 }
1307
94a86be0
BK
1308 template<typename _ITp>
1309 inline bool
036e0d4f 1310 atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
25999a11
JW
1311 __atomic_val_t<_ITp>* __i1,
1312 __atomic_val_t<_ITp> __i2) noexcept
94a86be0
BK
1313 {
1314 return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1315 memory_order_seq_cst,
1316 memory_order_seq_cst);
1317 }
1318
50ce8d3d 1319 template<typename _ITp>
afd88205 1320 inline bool
036e0d4f 1321 atomic_compare_exchange_strong(atomic<_ITp>* __a,
25999a11
JW
1322 __atomic_val_t<_ITp>* __i1,
1323 __atomic_val_t<_ITp> __i2) noexcept
afd88205
BK
1324 {
1325 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
50ce8d3d 1326 memory_order_seq_cst,
afd88205 1327 memory_order_seq_cst);
d466a7e2
BK
1328 }
1329
94a86be0
BK
1330 template<typename _ITp>
1331 inline bool
036e0d4f 1332 atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
25999a11
JW
1333 __atomic_val_t<_ITp>* __i1,
1334 __atomic_val_t<_ITp> __i2) noexcept
94a86be0
BK
1335 {
1336 return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1337 memory_order_seq_cst,
1338 memory_order_seq_cst);
1339 }
1340
25999a11
JW
1341 // Function templates for atomic_integral and atomic_pointer operations only.
1342 // Some operations (and, or, xor) are only available for atomic integrals,
1343 // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1344
036e0d4f
BK
1345 template<typename _ITp>
1346 inline _ITp
25999a11
JW
1347 atomic_fetch_add_explicit(atomic<_ITp>* __a,
1348 __atomic_diff_t<_ITp> __i,
bdc05efb 1349 memory_order __m) noexcept
036e0d4f
BK
1350 { return __a->fetch_add(__i, __m); }
1351
1352 template<typename _ITp>
1353 inline _ITp
25999a11
JW
1354 atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1355 __atomic_diff_t<_ITp> __i,
bdc05efb 1356 memory_order __m) noexcept
036e0d4f
BK
1357 { return __a->fetch_add(__i, __m); }
1358
1359 template<typename _ITp>
1360 inline _ITp
25999a11
JW
1361 atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1362 __atomic_diff_t<_ITp> __i,
bdc05efb 1363 memory_order __m) noexcept
036e0d4f
BK
1364 { return __a->fetch_sub(__i, __m); }
1365
1366 template<typename _ITp>
1367 inline _ITp
25999a11
JW
1368 atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1369 __atomic_diff_t<_ITp> __i,
bdc05efb 1370 memory_order __m) noexcept
036e0d4f
BK
1371 { return __a->fetch_sub(__i, __m); }
1372
1373 template<typename _ITp>
1374 inline _ITp
25999a11
JW
1375 atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1376 __atomic_val_t<_ITp> __i,
bdc05efb 1377 memory_order __m) noexcept
036e0d4f
BK
1378 { return __a->fetch_and(__i, __m); }
1379
1380 template<typename _ITp>
1381 inline _ITp
25999a11
JW
1382 atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1383 __atomic_val_t<_ITp> __i,
bdc05efb 1384 memory_order __m) noexcept
036e0d4f
BK
1385 { return __a->fetch_and(__i, __m); }
1386
1387 template<typename _ITp>
1388 inline _ITp
25999a11
JW
1389 atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1390 __atomic_val_t<_ITp> __i,
bdc05efb 1391 memory_order __m) noexcept
036e0d4f
BK
1392 { return __a->fetch_or(__i, __m); }
1393
1394 template<typename _ITp>
1395 inline _ITp
25999a11
JW
1396 atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1397 __atomic_val_t<_ITp> __i,
bdc05efb 1398 memory_order __m) noexcept
036e0d4f
BK
1399 { return __a->fetch_or(__i, __m); }
1400
1401 template<typename _ITp>
1402 inline _ITp
25999a11
JW
1403 atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1404 __atomic_val_t<_ITp> __i,
bdc05efb 1405 memory_order __m) noexcept
036e0d4f
BK
1406 { return __a->fetch_xor(__i, __m); }
1407
1408 template<typename _ITp>
1409 inline _ITp
25999a11
JW
1410 atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1411 __atomic_val_t<_ITp> __i,
bdc05efb 1412 memory_order __m) noexcept
036e0d4f
BK
1413 { return __a->fetch_xor(__i, __m); }
1414
50ce8d3d 1415 template<typename _ITp>
afd88205 1416 inline _ITp
25999a11
JW
1417 atomic_fetch_add(atomic<_ITp>* __a,
1418 __atomic_diff_t<_ITp> __i) noexcept
50ce8d3d
BK
1419 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1420
94a86be0
BK
1421 template<typename _ITp>
1422 inline _ITp
25999a11
JW
1423 atomic_fetch_add(volatile atomic<_ITp>* __a,
1424 __atomic_diff_t<_ITp> __i) noexcept
94a86be0
BK
1425 { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1426
50ce8d3d 1427 template<typename _ITp>
afd88205 1428 inline _ITp
25999a11
JW
1429 atomic_fetch_sub(atomic<_ITp>* __a,
1430 __atomic_diff_t<_ITp> __i) noexcept
50ce8d3d
BK
1431 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1432
94a86be0
BK
1433 template<typename _ITp>
1434 inline _ITp
25999a11
JW
1435 atomic_fetch_sub(volatile atomic<_ITp>* __a,
1436 __atomic_diff_t<_ITp> __i) noexcept
94a86be0
BK
1437 { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1438
50ce8d3d 1439 template<typename _ITp>
afd88205 1440 inline _ITp
25999a11
JW
1441 atomic_fetch_and(__atomic_base<_ITp>* __a,
1442 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d
BK
1443 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1444
94a86be0
BK
1445 template<typename _ITp>
1446 inline _ITp
25999a11
JW
1447 atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1448 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1449 { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1450
50ce8d3d 1451 template<typename _ITp>
afd88205 1452 inline _ITp
25999a11
JW
1453 atomic_fetch_or(__atomic_base<_ITp>* __a,
1454 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d
BK
1455 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1456
94a86be0
BK
1457 template<typename _ITp>
1458 inline _ITp
25999a11
JW
1459 atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1460 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1461 { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1462
50ce8d3d 1463 template<typename _ITp>
afd88205 1464 inline _ITp
25999a11
JW
1465 atomic_fetch_xor(__atomic_base<_ITp>* __a,
1466 __atomic_val_t<_ITp> __i) noexcept
50ce8d3d 1467 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
d466a7e2 1468
94a86be0
BK
1469 template<typename _ITp>
1470 inline _ITp
25999a11
JW
1471 atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1472 __atomic_val_t<_ITp> __i) noexcept
94a86be0
BK
1473 { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1474
5b9daa7e
BK
1475 // @} group atomics
1476
12ffa228
BK
1477_GLIBCXX_END_NAMESPACE_VERSION
1478} // namespace
d466a7e2 1479
709def90
PC
1480#endif // C++11
1481
1482#endif // _GLIBCXX_ATOMIC