libstdc++
atomic
Go to the documentation of this file.
1 // -*- C++ -*- header.
2 
3 // Copyright (C) 2008-2025 Free Software Foundation, Inc.
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
8 // Free Software Foundation; either version 3, or (at your option)
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 
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/>.
24 
25 /** @file include/atomic
26  * This is a Standard C++ Library header.
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 
32 #ifndef _GLIBCXX_ATOMIC
33 #define _GLIBCXX_ATOMIC 1
34 
35 #ifdef _GLIBCXX_SYSHDR
36 #pragma GCC system_header
37 #endif
38 
39 #if __cplusplus < 201103L
40 # include <bits/c++0x_warning.h>
41 #else
42 
43 #define __glibcxx_want_atomic_is_always_lock_free
44 #define __glibcxx_want_atomic_flag_test
45 #define __glibcxx_want_atomic_float
46 #define __glibcxx_want_atomic_ref
47 #define __glibcxx_want_atomic_lock_free_type_aliases
48 #define __glibcxx_want_atomic_value_initialization
49 #define __glibcxx_want_atomic_wait
50 #include <bits/version.h>
51 
52 #include <bits/atomic_base.h>
53 #include <cstdint>
54 #include <type_traits>
55 
56 namespace std _GLIBCXX_VISIBILITY(default)
57 {
58 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 
60  /**
61  * @addtogroup atomics
62  * @{
63  */
64 
65  template<typename _Tp>
66  struct atomic;
67 
68  /// atomic<bool>
69  // NB: No operators or fetch-operations for this type.
70  template<>
71  struct atomic<bool>
72  {
73  using value_type = bool;
74 
75  private:
76  __atomic_base<bool> _M_base;
77 
78  public:
79  atomic() noexcept = default;
80  ~atomic() noexcept = default;
81  atomic(const atomic&) = delete;
82  atomic& operator=(const atomic&) = delete;
83  atomic& operator=(const atomic&) volatile = delete;
84 
85  constexpr atomic(bool __i) noexcept : _M_base(__i) { }
86 
87  bool
88  operator=(bool __i) noexcept
89  { return _M_base.operator=(__i); }
90 
91  bool
92  operator=(bool __i) volatile noexcept
93  { return _M_base.operator=(__i); }
94 
95  operator bool() const noexcept
96  { return _M_base.load(); }
97 
98  operator bool() const volatile noexcept
99  { return _M_base.load(); }
100 
101  bool
102  is_lock_free() const noexcept { return _M_base.is_lock_free(); }
103 
104  bool
105  is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
106 
107 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
108  static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
109 #endif
110 
111  void
112  store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
113  { _M_base.store(__i, __m); }
114 
115  void
116  store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
117  { _M_base.store(__i, __m); }
118 
119  bool
120  load(memory_order __m = memory_order_seq_cst) const noexcept
121  { return _M_base.load(__m); }
122 
123  bool
124  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
125  { return _M_base.load(__m); }
126 
127  bool
128  exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
129  { return _M_base.exchange(__i, __m); }
130 
131  bool
132  exchange(bool __i,
133  memory_order __m = memory_order_seq_cst) volatile noexcept
134  { return _M_base.exchange(__i, __m); }
135 
136  bool
137  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
138  memory_order __m2) noexcept
139  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
140 
141  bool
142  compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
143  memory_order __m2) volatile noexcept
144  { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
145 
146  bool
147  compare_exchange_weak(bool& __i1, bool __i2,
148  memory_order __m = memory_order_seq_cst) noexcept
149  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
150 
151  bool
152  compare_exchange_weak(bool& __i1, bool __i2,
153  memory_order __m = memory_order_seq_cst) volatile noexcept
154  { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
155 
156  bool
157  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
158  memory_order __m2) noexcept
159  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
160 
161  bool
162  compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
163  memory_order __m2) volatile noexcept
164  { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
165 
166  bool
167  compare_exchange_strong(bool& __i1, bool __i2,
168  memory_order __m = memory_order_seq_cst) noexcept
169  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
170 
171  bool
172  compare_exchange_strong(bool& __i1, bool __i2,
173  memory_order __m = memory_order_seq_cst) volatile noexcept
174  { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
175 
176 #if __cpp_lib_atomic_wait
177  void
178  wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
179  { _M_base.wait(__old, __m); }
180 
181  // TODO add const volatile overload
182 
183  void
184  notify_one() noexcept
185  { _M_base.notify_one(); }
186 
187  void
188  notify_all() noexcept
189  { _M_base.notify_all(); }
190 #endif // __cpp_lib_atomic_wait
191  };
192 
193  /**
194  * @brief Generic atomic type, primary class template.
195  *
196  * @tparam _Tp Type to be made atomic, must be trivially copyable.
197  */
198  template<typename _Tp>
199  struct atomic
200  {
201  using value_type = _Tp;
202 
203  private:
204  // Align 1/2/4/8/16-byte types to at least their size.
205  static constexpr int _S_min_alignment
206  = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
207  ? 0 : sizeof(_Tp);
208 
209  static constexpr int _S_alignment
210  = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
211 
212  alignas(_S_alignment) _Tp _M_i;
213 
214  static_assert(__is_trivially_copyable(_Tp),
215  "std::atomic requires a trivially copyable type");
216 
217  static_assert(sizeof(_Tp) > 0,
218  "Incomplete or zero-sized types are not supported");
219 
220 #if __cplusplus > 201703L
221  static_assert(is_copy_constructible_v<_Tp>);
222  static_assert(is_move_constructible_v<_Tp>);
223  static_assert(is_copy_assignable_v<_Tp>);
224  static_assert(is_move_assignable_v<_Tp>);
225 #endif
226 
227  public:
228 #if __cpp_lib_atomic_value_initialization
229  // _GLIBCXX_RESOLVE_LIB_DEFECTS
230  // 4169. std::atomic<T>'s default constructor should be constrained
231  constexpr atomic() noexcept(is_nothrow_default_constructible_v<_Tp>)
232  requires is_default_constructible_v<_Tp>
233  : _M_i()
234  {}
235 #else
236  atomic() = default;
237 #endif
238 
239  ~atomic() noexcept = default;
240  atomic(const atomic&) = delete;
241  atomic& operator=(const atomic&) = delete;
242  atomic& operator=(const atomic&) volatile = delete;
243 
244 #pragma GCC diagnostic push
245 #pragma GCC diagnostic ignored "-Wc++14-extensions" // constexpr ctor body
246  constexpr atomic(_Tp __i) noexcept : _M_i(__i)
247  {
248 #if __has_builtin(__builtin_clear_padding)
249  if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>())
250  if (!std::__is_constant_evaluated())
251  __builtin_clear_padding(std::__addressof(_M_i));
252 #endif
253  }
254 #pragma GCC diagnostic pop
255 
256  operator _Tp() const noexcept
257  { return load(); }
258 
259  operator _Tp() const volatile noexcept
260  { return load(); }
261 
262  _Tp
263  operator=(_Tp __i) noexcept
264  { store(__i); return __i; }
265 
266  _Tp
267  operator=(_Tp __i) volatile noexcept
268  { store(__i); return __i; }
269 
270  bool
271  is_lock_free() const noexcept
272  {
273  // Produce a fake, minimally aligned pointer.
274  return __atomic_is_lock_free(sizeof(_M_i),
275  reinterpret_cast<void *>(-_S_alignment));
276  }
277 
278  bool
279  is_lock_free() const volatile noexcept
280  {
281  // Produce a fake, minimally aligned pointer.
282  return __atomic_is_lock_free(sizeof(_M_i),
283  reinterpret_cast<void *>(-_S_alignment));
284  }
285 
286 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
287  static constexpr bool is_always_lock_free
288  = __atomic_always_lock_free(sizeof(_M_i), 0);
289 #endif
290 
291  void
292  store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
293  {
294  __atomic_store(std::__addressof(_M_i),
295  __atomic_impl::__clear_padding(__i),
296  int(__m));
297  }
298 
299  void
300  store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
301  {
302  __atomic_store(std::__addressof(_M_i),
303  __atomic_impl::__clear_padding(__i),
304  int(__m));
305  }
306 
307  _Tp
308  load(memory_order __m = memory_order_seq_cst) const noexcept
309  {
310  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
311  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
312  __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
313  return *__ptr;
314  }
315 
316  _Tp
317  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
318  {
319  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
320  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
321  __atomic_load(std::__addressof(_M_i), __ptr, int(__m));
322  return *__ptr;
323  }
324 
325  _Tp
326  exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
327  {
328  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
329  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
330  __atomic_exchange(std::__addressof(_M_i),
331  __atomic_impl::__clear_padding(__i),
332  __ptr, int(__m));
333  return *__ptr;
334  }
335 
336  _Tp
337  exchange(_Tp __i,
338  memory_order __m = memory_order_seq_cst) volatile noexcept
339  {
340  alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
341  _Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
342  __atomic_exchange(std::__addressof(_M_i),
343  __atomic_impl::__clear_padding(__i),
344  __ptr, int(__m));
345  return *__ptr;
346  }
347 
348  bool
349  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
350  memory_order __f) noexcept
351  {
352  return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
353  __s, __f);
354  }
355 
356  bool
357  compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
358  memory_order __f) volatile noexcept
359  {
360  return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
361  __s, __f);
362  }
363 
364  bool
365  compare_exchange_weak(_Tp& __e, _Tp __i,
366  memory_order __m = memory_order_seq_cst) noexcept
367  { return compare_exchange_weak(__e, __i, __m,
368  __cmpexch_failure_order(__m)); }
369 
370  bool
371  compare_exchange_weak(_Tp& __e, _Tp __i,
372  memory_order __m = memory_order_seq_cst) volatile noexcept
373  { return compare_exchange_weak(__e, __i, __m,
374  __cmpexch_failure_order(__m)); }
375 
376  bool
377  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
378  memory_order __f) noexcept
379  {
380  return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
381  __s, __f);
382  }
383 
384  bool
385  compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
386  memory_order __f) volatile noexcept
387  {
388  return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
389  __s, __f);
390  }
391 
392  bool
393  compare_exchange_strong(_Tp& __e, _Tp __i,
394  memory_order __m = memory_order_seq_cst) noexcept
395  { return compare_exchange_strong(__e, __i, __m,
396  __cmpexch_failure_order(__m)); }
397 
398  bool
399  compare_exchange_strong(_Tp& __e, _Tp __i,
400  memory_order __m = memory_order_seq_cst) volatile noexcept
401  { return compare_exchange_strong(__e, __i, __m,
402  __cmpexch_failure_order(__m)); }
403 
404 #if __cpp_lib_atomic_wait // C++ >= 20
405  void
406  wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
407  {
408  std::__atomic_wait_address_v(std::addressof(_M_i), __old,
409  [__m, this] { return this->load(__m); });
410  }
411 
412  // TODO add const volatile overload
413 
414  void
415  notify_one() noexcept
416  { std::__atomic_notify_address(std::addressof(_M_i), false); }
417 
418  void
419  notify_all() noexcept
420  { std::__atomic_notify_address(std::addressof(_M_i), true); }
421 #endif // __cpp_lib_atomic_wait
422  };
423 
424  /// Partial specialization for pointer types.
425  template<typename _Tp>
426  struct atomic<_Tp*>
427  {
428  using value_type = _Tp*;
429  using difference_type = ptrdiff_t;
430 
431  typedef _Tp* __pointer_type;
432  typedef __atomic_base<_Tp*> __base_type;
433  __base_type _M_b;
434 
435  atomic() noexcept = default;
436  ~atomic() noexcept = default;
437  atomic(const atomic&) = delete;
438  atomic& operator=(const atomic&) = delete;
439  atomic& operator=(const atomic&) volatile = delete;
440 
441  constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
442 
443  operator __pointer_type() const noexcept
444  { return __pointer_type(_M_b); }
445 
446  operator __pointer_type() const volatile noexcept
447  { return __pointer_type(_M_b); }
448 
449  __pointer_type
450  operator=(__pointer_type __p) noexcept
451  { return _M_b.operator=(__p); }
452 
453  __pointer_type
454  operator=(__pointer_type __p) volatile noexcept
455  { return _M_b.operator=(__p); }
456 
457  __pointer_type
458  operator++(int) noexcept
459  {
460 #if __cplusplus >= 201703L
461  static_assert( is_object_v<_Tp>, "pointer to object type" );
462 #endif
463  return _M_b++;
464  }
465 
466  __pointer_type
467  operator++(int) volatile noexcept
468  {
469 #if __cplusplus >= 201703L
470  static_assert( is_object_v<_Tp>, "pointer to object type" );
471 #endif
472  return _M_b++;
473  }
474 
475  __pointer_type
476  operator--(int) noexcept
477  {
478 #if __cplusplus >= 201703L
479  static_assert( is_object_v<_Tp>, "pointer to object type" );
480 #endif
481  return _M_b--;
482  }
483 
484  __pointer_type
485  operator--(int) volatile noexcept
486  {
487 #if __cplusplus >= 201703L
488  static_assert( is_object_v<_Tp>, "pointer to object type" );
489 #endif
490  return _M_b--;
491  }
492 
493  __pointer_type
494  operator++() noexcept
495  {
496 #if __cplusplus >= 201703L
497  static_assert( is_object_v<_Tp>, "pointer to object type" );
498 #endif
499  return ++_M_b;
500  }
501 
502  __pointer_type
503  operator++() volatile noexcept
504  {
505 #if __cplusplus >= 201703L
506  static_assert( is_object_v<_Tp>, "pointer to object type" );
507 #endif
508  return ++_M_b;
509  }
510 
511  __pointer_type
512  operator--() noexcept
513  {
514 #if __cplusplus >= 201703L
515  static_assert( is_object_v<_Tp>, "pointer to object type" );
516 #endif
517  return --_M_b;
518  }
519 
520  __pointer_type
521  operator--() volatile noexcept
522  {
523 #if __cplusplus >= 201703L
524  static_assert( is_object_v<_Tp>, "pointer to object type" );
525 #endif
526  return --_M_b;
527  }
528 
529  __pointer_type
530  operator+=(ptrdiff_t __d) noexcept
531  {
532 #if __cplusplus >= 201703L
533  static_assert( is_object_v<_Tp>, "pointer to object type" );
534 #endif
535  return _M_b.operator+=(__d);
536  }
537 
538  __pointer_type
539  operator+=(ptrdiff_t __d) volatile noexcept
540  {
541 #if __cplusplus >= 201703L
542  static_assert( is_object_v<_Tp>, "pointer to object type" );
543 #endif
544  return _M_b.operator+=(__d);
545  }
546 
547  __pointer_type
548  operator-=(ptrdiff_t __d) noexcept
549  {
550 #if __cplusplus >= 201703L
551  static_assert( is_object_v<_Tp>, "pointer to object type" );
552 #endif
553  return _M_b.operator-=(__d);
554  }
555 
556  __pointer_type
557  operator-=(ptrdiff_t __d) volatile noexcept
558  {
559 #if __cplusplus >= 201703L
560  static_assert( is_object_v<_Tp>, "pointer to object type" );
561 #endif
562  return _M_b.operator-=(__d);
563  }
564 
565  bool
566  is_lock_free() const noexcept
567  { return _M_b.is_lock_free(); }
568 
569  bool
570  is_lock_free() const volatile noexcept
571  { return _M_b.is_lock_free(); }
572 
573 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
574  static constexpr bool is_always_lock_free
575  = ATOMIC_POINTER_LOCK_FREE == 2;
576 #endif
577 
578  void
579  store(__pointer_type __p,
580  memory_order __m = memory_order_seq_cst) noexcept
581  { return _M_b.store(__p, __m); }
582 
583  void
584  store(__pointer_type __p,
585  memory_order __m = memory_order_seq_cst) volatile noexcept
586  { return _M_b.store(__p, __m); }
587 
588  __pointer_type
589  load(memory_order __m = memory_order_seq_cst) const noexcept
590  { return _M_b.load(__m); }
591 
592  __pointer_type
593  load(memory_order __m = memory_order_seq_cst) const volatile noexcept
594  { return _M_b.load(__m); }
595 
596  __pointer_type
597  exchange(__pointer_type __p,
598  memory_order __m = memory_order_seq_cst) noexcept
599  { return _M_b.exchange(__p, __m); }
600 
601  __pointer_type
602  exchange(__pointer_type __p,
603  memory_order __m = memory_order_seq_cst) volatile noexcept
604  { return _M_b.exchange(__p, __m); }
605 
606  bool
607  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
608  memory_order __m1, memory_order __m2) noexcept
609  { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
610 
611  bool
612  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
613  memory_order __m1,
614  memory_order __m2) volatile noexcept
615  { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
616 
617  bool
618  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
619  memory_order __m = memory_order_seq_cst) noexcept
620  {
621  return compare_exchange_weak(__p1, __p2, __m,
622  __cmpexch_failure_order(__m));
623  }
624 
625  bool
626  compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
627  memory_order __m = memory_order_seq_cst) volatile noexcept
628  {
629  return compare_exchange_weak(__p1, __p2, __m,
630  __cmpexch_failure_order(__m));
631  }
632 
633  bool
634  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
635  memory_order __m1, memory_order __m2) noexcept
636  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
637 
638  bool
639  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
640  memory_order __m1,
641  memory_order __m2) volatile noexcept
642  { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
643 
644  bool
645  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
646  memory_order __m = memory_order_seq_cst) noexcept
647  {
648  return _M_b.compare_exchange_strong(__p1, __p2, __m,
649  __cmpexch_failure_order(__m));
650  }
651 
652  bool
653  compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
654  memory_order __m = memory_order_seq_cst) volatile noexcept
655  {
656  return _M_b.compare_exchange_strong(__p1, __p2, __m,
657  __cmpexch_failure_order(__m));
658  }
659 
660 #if __cpp_lib_atomic_wait
661  void
662  wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
663  { _M_b.wait(__old, __m); }
664 
665  // TODO add const volatile overload
666 
667  void
668  notify_one() noexcept
669  { _M_b.notify_one(); }
670 
671  void
672  notify_all() noexcept
673  { _M_b.notify_all(); }
674 #endif // __cpp_lib_atomic_wait
675 
676  __pointer_type
677  fetch_add(ptrdiff_t __d,
678  memory_order __m = memory_order_seq_cst) noexcept
679  {
680 #if __cplusplus >= 201703L
681  static_assert( is_object_v<_Tp>, "pointer to object type" );
682 #endif
683  return _M_b.fetch_add(__d, __m);
684  }
685 
686  __pointer_type
687  fetch_add(ptrdiff_t __d,
688  memory_order __m = memory_order_seq_cst) volatile noexcept
689  {
690 #if __cplusplus >= 201703L
691  static_assert( is_object_v<_Tp>, "pointer to object type" );
692 #endif
693  return _M_b.fetch_add(__d, __m);
694  }
695 
696  __pointer_type
697  fetch_sub(ptrdiff_t __d,
698  memory_order __m = memory_order_seq_cst) noexcept
699  {
700 #if __cplusplus >= 201703L
701  static_assert( is_object_v<_Tp>, "pointer to object type" );
702 #endif
703  return _M_b.fetch_sub(__d, __m);
704  }
705 
706  __pointer_type
707  fetch_sub(ptrdiff_t __d,
708  memory_order __m = memory_order_seq_cst) volatile noexcept
709  {
710 #if __cplusplus >= 201703L
711  static_assert( is_object_v<_Tp>, "pointer to object type" );
712 #endif
713  return _M_b.fetch_sub(__d, __m);
714  }
715  };
716 
717 
718  /// Explicit specialization for char.
719  template<>
720  struct atomic<char> : __atomic_base<char>
721  {
722  typedef char __integral_type;
723  typedef __atomic_base<char> __base_type;
724 
725  atomic() noexcept = default;
726  ~atomic() noexcept = default;
727  atomic(const atomic&) = delete;
728  atomic& operator=(const atomic&) = delete;
729  atomic& operator=(const atomic&) volatile = delete;
730 
731  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
732 
733  using __base_type::operator __integral_type;
734  using __base_type::operator=;
735 
736 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
737  static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
738 #endif
739  };
740 
741  /// Explicit specialization for signed char.
742  template<>
743  struct atomic<signed char> : __atomic_base<signed char>
744  {
745  typedef signed char __integral_type;
746  typedef __atomic_base<signed char> __base_type;
747 
748  atomic() noexcept= default;
749  ~atomic() noexcept = default;
750  atomic(const atomic&) = delete;
751  atomic& operator=(const atomic&) = delete;
752  atomic& operator=(const atomic&) volatile = delete;
753 
754  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
755 
756  using __base_type::operator __integral_type;
757  using __base_type::operator=;
758 
759 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
760  static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
761 #endif
762  };
763 
764  /// Explicit specialization for unsigned char.
765  template<>
766  struct atomic<unsigned char> : __atomic_base<unsigned char>
767  {
768  typedef unsigned char __integral_type;
769  typedef __atomic_base<unsigned char> __base_type;
770 
771  atomic() noexcept= default;
772  ~atomic() noexcept = default;
773  atomic(const atomic&) = delete;
774  atomic& operator=(const atomic&) = delete;
775  atomic& operator=(const atomic&) volatile = delete;
776 
777  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
778 
779  using __base_type::operator __integral_type;
780  using __base_type::operator=;
781 
782 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
783  static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
784 #endif
785  };
786 
787  /// Explicit specialization for short.
788  template<>
789  struct atomic<short> : __atomic_base<short>
790  {
791  typedef short __integral_type;
792  typedef __atomic_base<short> __base_type;
793 
794  atomic() noexcept = default;
795  ~atomic() noexcept = default;
796  atomic(const atomic&) = delete;
797  atomic& operator=(const atomic&) = delete;
798  atomic& operator=(const atomic&) volatile = delete;
799 
800  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
801 
802  using __base_type::operator __integral_type;
803  using __base_type::operator=;
804 
805 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
806  static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
807 #endif
808  };
809 
810  /// Explicit specialization for unsigned short.
811  template<>
812  struct atomic<unsigned short> : __atomic_base<unsigned short>
813  {
814  typedef unsigned short __integral_type;
815  typedef __atomic_base<unsigned short> __base_type;
816 
817  atomic() noexcept = default;
818  ~atomic() noexcept = default;
819  atomic(const atomic&) = delete;
820  atomic& operator=(const atomic&) = delete;
821  atomic& operator=(const atomic&) volatile = delete;
822 
823  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
824 
825  using __base_type::operator __integral_type;
826  using __base_type::operator=;
827 
828 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
829  static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
830 #endif
831  };
832 
833  /// Explicit specialization for int.
834  template<>
835  struct atomic<int> : __atomic_base<int>
836  {
837  typedef int __integral_type;
838  typedef __atomic_base<int> __base_type;
839 
840  atomic() noexcept = default;
841  ~atomic() noexcept = default;
842  atomic(const atomic&) = delete;
843  atomic& operator=(const atomic&) = delete;
844  atomic& operator=(const atomic&) volatile = delete;
845 
846  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
847 
848  using __base_type::operator __integral_type;
849  using __base_type::operator=;
850 
851 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
852  static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
853 #endif
854  };
855 
856  /// Explicit specialization for unsigned int.
857  template<>
858  struct atomic<unsigned int> : __atomic_base<unsigned int>
859  {
860  typedef unsigned int __integral_type;
861  typedef __atomic_base<unsigned int> __base_type;
862 
863  atomic() noexcept = default;
864  ~atomic() noexcept = default;
865  atomic(const atomic&) = delete;
866  atomic& operator=(const atomic&) = delete;
867  atomic& operator=(const atomic&) volatile = delete;
868 
869  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
870 
871  using __base_type::operator __integral_type;
872  using __base_type::operator=;
873 
874 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
875  static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
876 #endif
877  };
878 
879  /// Explicit specialization for long.
880  template<>
881  struct atomic<long> : __atomic_base<long>
882  {
883  typedef long __integral_type;
884  typedef __atomic_base<long> __base_type;
885 
886  atomic() noexcept = default;
887  ~atomic() noexcept = default;
888  atomic(const atomic&) = delete;
889  atomic& operator=(const atomic&) = delete;
890  atomic& operator=(const atomic&) volatile = delete;
891 
892  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
893 
894  using __base_type::operator __integral_type;
895  using __base_type::operator=;
896 
897 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
898  static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
899 #endif
900  };
901 
902  /// Explicit specialization for unsigned long.
903  template<>
904  struct atomic<unsigned long> : __atomic_base<unsigned long>
905  {
906  typedef unsigned long __integral_type;
907  typedef __atomic_base<unsigned long> __base_type;
908 
909  atomic() noexcept = default;
910  ~atomic() noexcept = default;
911  atomic(const atomic&) = delete;
912  atomic& operator=(const atomic&) = delete;
913  atomic& operator=(const atomic&) volatile = delete;
914 
915  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
916 
917  using __base_type::operator __integral_type;
918  using __base_type::operator=;
919 
920 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
921  static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
922 #endif
923  };
924 
925  /// Explicit specialization for long long.
926  template<>
927  struct atomic<long long> : __atomic_base<long long>
928  {
929  typedef long long __integral_type;
930  typedef __atomic_base<long long> __base_type;
931 
932  atomic() noexcept = default;
933  ~atomic() noexcept = default;
934  atomic(const atomic&) = delete;
935  atomic& operator=(const atomic&) = delete;
936  atomic& operator=(const atomic&) volatile = delete;
937 
938  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
939 
940  using __base_type::operator __integral_type;
941  using __base_type::operator=;
942 
943 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
944  static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
945 #endif
946  };
947 
948  /// Explicit specialization for unsigned long long.
949  template<>
950  struct atomic<unsigned long long> : __atomic_base<unsigned long long>
951  {
952  typedef unsigned long long __integral_type;
953  typedef __atomic_base<unsigned long long> __base_type;
954 
955  atomic() noexcept = default;
956  ~atomic() noexcept = default;
957  atomic(const atomic&) = delete;
958  atomic& operator=(const atomic&) = delete;
959  atomic& operator=(const atomic&) volatile = delete;
960 
961  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
962 
963  using __base_type::operator __integral_type;
964  using __base_type::operator=;
965 
966 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
967  static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
968 #endif
969  };
970 
971  /// Explicit specialization for wchar_t.
972  template<>
973  struct atomic<wchar_t> : __atomic_base<wchar_t>
974  {
975  typedef wchar_t __integral_type;
976  typedef __atomic_base<wchar_t> __base_type;
977 
978  atomic() noexcept = default;
979  ~atomic() noexcept = default;
980  atomic(const atomic&) = delete;
981  atomic& operator=(const atomic&) = delete;
982  atomic& operator=(const atomic&) volatile = delete;
983 
984  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
985 
986  using __base_type::operator __integral_type;
987  using __base_type::operator=;
988 
989 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
990  static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
991 #endif
992  };
993 
994 #ifdef _GLIBCXX_USE_CHAR8_T
995  /// Explicit specialization for char8_t.
996  template<>
997  struct atomic<char8_t> : __atomic_base<char8_t>
998  {
999  typedef char8_t __integral_type;
1000  typedef __atomic_base<char8_t> __base_type;
1001 
1002  atomic() noexcept = default;
1003  ~atomic() noexcept = default;
1004  atomic(const atomic&) = delete;
1005  atomic& operator=(const atomic&) = delete;
1006  atomic& operator=(const atomic&) volatile = delete;
1007 
1008  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1009 
1010  using __base_type::operator __integral_type;
1011  using __base_type::operator=;
1012 
1013 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
1014  static constexpr bool is_always_lock_free
1015  = ATOMIC_CHAR8_T_LOCK_FREE == 2;
1016 #endif
1017  };
1018 #endif
1019 
1020  /// Explicit specialization for char16_t.
1021  template<>
1022  struct atomic<char16_t> : __atomic_base<char16_t>
1023  {
1024  typedef char16_t __integral_type;
1025  typedef __atomic_base<char16_t> __base_type;
1026 
1027  atomic() noexcept = default;
1028  ~atomic() noexcept = default;
1029  atomic(const atomic&) = delete;
1030  atomic& operator=(const atomic&) = delete;
1031  atomic& operator=(const atomic&) volatile = delete;
1032 
1033  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1034 
1035  using __base_type::operator __integral_type;
1036  using __base_type::operator=;
1037 
1038 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
1039  static constexpr bool is_always_lock_free
1040  = ATOMIC_CHAR16_T_LOCK_FREE == 2;
1041 #endif
1042  };
1043 
1044  /// Explicit specialization for char32_t.
1045  template<>
1046  struct atomic<char32_t> : __atomic_base<char32_t>
1047  {
1048  typedef char32_t __integral_type;
1049  typedef __atomic_base<char32_t> __base_type;
1050 
1051  atomic() noexcept = default;
1052  ~atomic() noexcept = default;
1053  atomic(const atomic&) = delete;
1054  atomic& operator=(const atomic&) = delete;
1055  atomic& operator=(const atomic&) volatile = delete;
1056 
1057  constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1058 
1059  using __base_type::operator __integral_type;
1060  using __base_type::operator=;
1061 
1062 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
1063  static constexpr bool is_always_lock_free
1064  = ATOMIC_CHAR32_T_LOCK_FREE == 2;
1065 #endif
1066  };
1067 
1068 
1069  /// atomic_bool
1070  typedef atomic<bool> atomic_bool;
1071 
1072  /// atomic_char
1073  typedef atomic<char> atomic_char;
1074 
1075  /// atomic_schar
1076  typedef atomic<signed char> atomic_schar;
1077 
1078  /// atomic_uchar
1079  typedef atomic<unsigned char> atomic_uchar;
1080 
1081  /// atomic_short
1082  typedef atomic<short> atomic_short;
1083 
1084  /// atomic_ushort
1085  typedef atomic<unsigned short> atomic_ushort;
1086 
1087  /// atomic_int
1088  typedef atomic<int> atomic_int;
1089 
1090  /// atomic_uint
1091  typedef atomic<unsigned int> atomic_uint;
1092 
1093  /// atomic_long
1094  typedef atomic<long> atomic_long;
1095 
1096  /// atomic_ulong
1097  typedef atomic<unsigned long> atomic_ulong;
1098 
1099  /// atomic_llong
1100  typedef atomic<long long> atomic_llong;
1101 
1102  /// atomic_ullong
1103  typedef atomic<unsigned long long> atomic_ullong;
1104 
1105  /// atomic_wchar_t
1106  typedef atomic<wchar_t> atomic_wchar_t;
1107 
1108 #ifdef _GLIBCXX_USE_CHAR8_T
1109  /// atomic_char8_t
1110  typedef atomic<char8_t> atomic_char8_t;
1111 #endif
1112 
1113  /// atomic_char16_t
1114  typedef atomic<char16_t> atomic_char16_t;
1115 
1116  /// atomic_char32_t
1117  typedef atomic<char32_t> atomic_char32_t;
1118 
1119 #ifdef _GLIBCXX_USE_C99_STDINT
1120  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1121  // 2441. Exact-width atomic typedefs should be provided
1122 
1123  /// atomic_int8_t
1124  typedef atomic<int8_t> atomic_int8_t;
1125 
1126  /// atomic_uint8_t
1127  typedef atomic<uint8_t> atomic_uint8_t;
1128 
1129  /// atomic_int16_t
1130  typedef atomic<int16_t> atomic_int16_t;
1131 
1132  /// atomic_uint16_t
1133  typedef atomic<uint16_t> atomic_uint16_t;
1134 
1135  /// atomic_int32_t
1136  typedef atomic<int32_t> atomic_int32_t;
1137 
1138  /// atomic_uint32_t
1139  typedef atomic<uint32_t> atomic_uint32_t;
1140 
1141  /// atomic_int64_t
1142  typedef atomic<int64_t> atomic_int64_t;
1143 
1144  /// atomic_uint64_t
1145  typedef atomic<uint64_t> atomic_uint64_t;
1146 #endif
1147 
1148  /// atomic_int_least8_t
1149  typedef atomic<int_least8_t> atomic_int_least8_t;
1150 
1151  /// atomic_uint_least8_t
1152  typedef atomic<uint_least8_t> atomic_uint_least8_t;
1153 
1154  /// atomic_int_least16_t
1155  typedef atomic<int_least16_t> atomic_int_least16_t;
1156 
1157  /// atomic_uint_least16_t
1158  typedef atomic<uint_least16_t> atomic_uint_least16_t;
1159 
1160  /// atomic_int_least32_t
1161  typedef atomic<int_least32_t> atomic_int_least32_t;
1162 
1163  /// atomic_uint_least32_t
1164  typedef atomic<uint_least32_t> atomic_uint_least32_t;
1165 
1166  /// atomic_int_least64_t
1167  typedef atomic<int_least64_t> atomic_int_least64_t;
1168 
1169  /// atomic_uint_least64_t
1170  typedef atomic<uint_least64_t> atomic_uint_least64_t;
1171 
1172 
1173  /// atomic_int_fast8_t
1174  typedef atomic<int_fast8_t> atomic_int_fast8_t;
1175 
1176  /// atomic_uint_fast8_t
1177  typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1178 
1179  /// atomic_int_fast16_t
1180  typedef atomic<int_fast16_t> atomic_int_fast16_t;
1181 
1182  /// atomic_uint_fast16_t
1183  typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1184 
1185  /// atomic_int_fast32_t
1186  typedef atomic<int_fast32_t> atomic_int_fast32_t;
1187 
1188  /// atomic_uint_fast32_t
1189  typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1190 
1191  /// atomic_int_fast64_t
1192  typedef atomic<int_fast64_t> atomic_int_fast64_t;
1193 
1194  /// atomic_uint_fast64_t
1195  typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1196 
1197 
1198  /// atomic_intptr_t
1199  typedef atomic<intptr_t> atomic_intptr_t;
1200 
1201  /// atomic_uintptr_t
1202  typedef atomic<uintptr_t> atomic_uintptr_t;
1203 
1204  /// atomic_size_t
1205  typedef atomic<size_t> atomic_size_t;
1206 
1207  /// atomic_ptrdiff_t
1208  typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1209 
1210  /// atomic_intmax_t
1211  typedef atomic<intmax_t> atomic_intmax_t;
1212 
1213  /// atomic_uintmax_t
1214  typedef atomic<uintmax_t> atomic_uintmax_t;
1215 
1216  // Function definitions, atomic_flag operations.
1217  inline bool
1218  atomic_flag_test_and_set_explicit(atomic_flag* __a,
1219  memory_order __m) noexcept
1220  { return __a->test_and_set(__m); }
1221 
1222  inline bool
1223  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
1224  memory_order __m) noexcept
1225  { return __a->test_and_set(__m); }
1226 
1227 #if __cpp_lib_atomic_flag_test
1228  inline bool
1229  atomic_flag_test(const atomic_flag* __a) noexcept
1230  { return __a->test(); }
1231 
1232  inline bool
1233  atomic_flag_test(const volatile atomic_flag* __a) noexcept
1234  { return __a->test(); }
1235 
1236  inline bool
1237  atomic_flag_test_explicit(const atomic_flag* __a,
1238  memory_order __m) noexcept
1239  { return __a->test(__m); }
1240 
1241  inline bool
1242  atomic_flag_test_explicit(const volatile atomic_flag* __a,
1243  memory_order __m) noexcept
1244  { return __a->test(__m); }
1245 #endif
1246 
1247  inline void
1248  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
1249  { __a->clear(__m); }
1250 
1251  inline void
1252  atomic_flag_clear_explicit(volatile atomic_flag* __a,
1253  memory_order __m) noexcept
1254  { __a->clear(__m); }
1255 
1256  inline bool
1257  atomic_flag_test_and_set(atomic_flag* __a) noexcept
1258  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1259 
1260  inline bool
1261  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
1262  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1263 
1264  inline void
1265  atomic_flag_clear(atomic_flag* __a) noexcept
1266  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1267 
1268  inline void
1269  atomic_flag_clear(volatile atomic_flag* __a) noexcept
1270  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1271 
1272 #if __cpp_lib_atomic_wait
1273  inline void
1274  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
1275  { __a->wait(__old); }
1276 
1277  inline void
1278  atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
1279  memory_order __m) noexcept
1280  { __a->wait(__old, __m); }
1281 
1282  inline void
1283  atomic_flag_notify_one(atomic_flag* __a) noexcept
1284  { __a->notify_one(); }
1285 
1286  inline void
1287  atomic_flag_notify_all(atomic_flag* __a) noexcept
1288  { __a->notify_all(); }
1289 #endif // __cpp_lib_atomic_wait
1290 
1291  /// @cond undocumented
1292  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1293  // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
1294  template<typename _Tp>
1295  using __atomic_val_t = __type_identity_t<_Tp>;
1296  template<typename _Tp>
1297  using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1298  /// @endcond
1299 
1300  // [atomics.nonmembers] Non-member functions.
1301  // Function templates generally applicable to atomic types.
1302  template<typename _ITp>
1303  inline bool
1304  atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
1305  { return __a->is_lock_free(); }
1306 
1307  template<typename _ITp>
1308  inline bool
1309  atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
1310  { return __a->is_lock_free(); }
1311 
1312  template<typename _ITp>
1313  inline void
1314  atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1315  { __a->store(__i, memory_order_relaxed); }
1316 
1317  template<typename _ITp>
1318  inline void
1319  atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1320  { __a->store(__i, memory_order_relaxed); }
1321 
1322  template<typename _ITp>
1323  inline void
1324  atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1325  memory_order __m) noexcept
1326  { __a->store(__i, __m); }
1327 
1328  template<typename _ITp>
1329  inline void
1330  atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1331  memory_order __m) noexcept
1332  { __a->store(__i, __m); }
1333 
1334  template<typename _ITp>
1335  inline _ITp
1336  atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
1337  { return __a->load(__m); }
1338 
1339  template<typename _ITp>
1340  inline _ITp
1341  atomic_load_explicit(const volatile atomic<_ITp>* __a,
1342  memory_order __m) noexcept
1343  { return __a->load(__m); }
1344 
1345  template<typename _ITp>
1346  inline _ITp
1347  atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
1348  memory_order __m) noexcept
1349  { return __a->exchange(__i, __m); }
1350 
1351  template<typename _ITp>
1352  inline _ITp
1353  atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1354  __atomic_val_t<_ITp> __i,
1355  memory_order __m) noexcept
1356  { return __a->exchange(__i, __m); }
1357 
1358  template<typename _ITp>
1359  inline bool
1360  atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1361  __atomic_val_t<_ITp>* __i1,
1362  __atomic_val_t<_ITp> __i2,
1363  memory_order __m1,
1364  memory_order __m2) noexcept
1365  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1366 
1367  template<typename _ITp>
1368  inline bool
1369  atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1370  __atomic_val_t<_ITp>* __i1,
1371  __atomic_val_t<_ITp> __i2,
1372  memory_order __m1,
1373  memory_order __m2) noexcept
1374  { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1375 
1376  template<typename _ITp>
1377  inline bool
1378  atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1379  __atomic_val_t<_ITp>* __i1,
1380  __atomic_val_t<_ITp> __i2,
1381  memory_order __m1,
1382  memory_order __m2) noexcept
1383  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1384 
1385  template<typename _ITp>
1386  inline bool
1387  atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1388  __atomic_val_t<_ITp>* __i1,
1389  __atomic_val_t<_ITp> __i2,
1390  memory_order __m1,
1391  memory_order __m2) noexcept
1392  { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1393 
1394 
1395  template<typename _ITp>
1396  inline void
1397  atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1398  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1399 
1400  template<typename _ITp>
1401  inline void
1402  atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1403  { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1404 
1405  template<typename _ITp>
1406  inline _ITp
1407  atomic_load(const atomic<_ITp>* __a) noexcept
1408  { return atomic_load_explicit(__a, memory_order_seq_cst); }
1409 
1410  template<typename _ITp>
1411  inline _ITp
1412  atomic_load(const volatile atomic<_ITp>* __a) noexcept
1413  { return atomic_load_explicit(__a, memory_order_seq_cst); }
1414 
1415  template<typename _ITp>
1416  inline _ITp
1417  atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
1418  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1419 
1420  template<typename _ITp>
1421  inline _ITp
1422  atomic_exchange(volatile atomic<_ITp>* __a,
1423  __atomic_val_t<_ITp> __i) noexcept
1424  { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1425 
1426  template<typename _ITp>
1427  inline bool
1428  atomic_compare_exchange_weak(atomic<_ITp>* __a,
1429  __atomic_val_t<_ITp>* __i1,
1430  __atomic_val_t<_ITp> __i2) noexcept
1431  {
1432  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1433  memory_order_seq_cst,
1434  memory_order_seq_cst);
1435  }
1436 
1437  template<typename _ITp>
1438  inline bool
1439  atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1440  __atomic_val_t<_ITp>* __i1,
1441  __atomic_val_t<_ITp> __i2) noexcept
1442  {
1443  return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1444  memory_order_seq_cst,
1445  memory_order_seq_cst);
1446  }
1447 
1448  template<typename _ITp>
1449  inline bool
1450  atomic_compare_exchange_strong(atomic<_ITp>* __a,
1451  __atomic_val_t<_ITp>* __i1,
1452  __atomic_val_t<_ITp> __i2) noexcept
1453  {
1454  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1455  memory_order_seq_cst,
1456  memory_order_seq_cst);
1457  }
1458 
1459  template<typename _ITp>
1460  inline bool
1461  atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1462  __atomic_val_t<_ITp>* __i1,
1463  __atomic_val_t<_ITp> __i2) noexcept
1464  {
1465  return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1466  memory_order_seq_cst,
1467  memory_order_seq_cst);
1468  }
1469 
1470 
1471 #if __cpp_lib_atomic_wait
1472  template<typename _Tp>
1473  inline void
1474  atomic_wait(const atomic<_Tp>* __a,
1475  typename std::atomic<_Tp>::value_type __old) noexcept
1476  { __a->wait(__old); }
1477 
1478  template<typename _Tp>
1479  inline void
1480  atomic_wait_explicit(const atomic<_Tp>* __a,
1481  typename std::atomic<_Tp>::value_type __old,
1482  std::memory_order __m) noexcept
1483  { __a->wait(__old, __m); }
1484 
1485  template<typename _Tp>
1486  inline void
1487  atomic_notify_one(atomic<_Tp>* __a) noexcept
1488  { __a->notify_one(); }
1489 
1490  template<typename _Tp>
1491  inline void
1492  atomic_notify_all(atomic<_Tp>* __a) noexcept
1493  { __a->notify_all(); }
1494 #endif // __cpp_lib_atomic_wait
1495 
1496  // Function templates for atomic_integral and atomic_pointer operations only.
1497  // Some operations (and, or, xor) are only available for atomic integrals,
1498  // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1499 
1500  template<typename _ITp>
1501  inline _ITp
1502  atomic_fetch_add_explicit(atomic<_ITp>* __a,
1503  __atomic_diff_t<_ITp> __i,
1504  memory_order __m) noexcept
1505  { return __a->fetch_add(__i, __m); }
1506 
1507  template<typename _ITp>
1508  inline _ITp
1509  atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1510  __atomic_diff_t<_ITp> __i,
1511  memory_order __m) noexcept
1512  { return __a->fetch_add(__i, __m); }
1513 
1514  template<typename _ITp>
1515  inline _ITp
1516  atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1517  __atomic_diff_t<_ITp> __i,
1518  memory_order __m) noexcept
1519  { return __a->fetch_sub(__i, __m); }
1520 
1521  template<typename _ITp>
1522  inline _ITp
1523  atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1524  __atomic_diff_t<_ITp> __i,
1525  memory_order __m) noexcept
1526  { return __a->fetch_sub(__i, __m); }
1527 
1528  template<typename _ITp>
1529  inline _ITp
1530  atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1531  __atomic_val_t<_ITp> __i,
1532  memory_order __m) noexcept
1533  { return __a->fetch_and(__i, __m); }
1534 
1535  template<typename _ITp>
1536  inline _ITp
1537  atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1538  __atomic_val_t<_ITp> __i,
1539  memory_order __m) noexcept
1540  { return __a->fetch_and(__i, __m); }
1541 
1542  template<typename _ITp>
1543  inline _ITp
1544  atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1545  __atomic_val_t<_ITp> __i,
1546  memory_order __m) noexcept
1547  { return __a->fetch_or(__i, __m); }
1548 
1549  template<typename _ITp>
1550  inline _ITp
1551  atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1552  __atomic_val_t<_ITp> __i,
1553  memory_order __m) noexcept
1554  { return __a->fetch_or(__i, __m); }
1555 
1556  template<typename _ITp>
1557  inline _ITp
1558  atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1559  __atomic_val_t<_ITp> __i,
1560  memory_order __m) noexcept
1561  { return __a->fetch_xor(__i, __m); }
1562 
1563  template<typename _ITp>
1564  inline _ITp
1565  atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1566  __atomic_val_t<_ITp> __i,
1567  memory_order __m) noexcept
1568  { return __a->fetch_xor(__i, __m); }
1569 
1570  template<typename _ITp>
1571  inline _ITp
1572  atomic_fetch_add(atomic<_ITp>* __a,
1573  __atomic_diff_t<_ITp> __i) noexcept
1574  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1575 
1576  template<typename _ITp>
1577  inline _ITp
1578  atomic_fetch_add(volatile atomic<_ITp>* __a,
1579  __atomic_diff_t<_ITp> __i) noexcept
1580  { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1581 
1582  template<typename _ITp>
1583  inline _ITp
1584  atomic_fetch_sub(atomic<_ITp>* __a,
1585  __atomic_diff_t<_ITp> __i) noexcept
1586  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1587 
1588  template<typename _ITp>
1589  inline _ITp
1590  atomic_fetch_sub(volatile atomic<_ITp>* __a,
1591  __atomic_diff_t<_ITp> __i) noexcept
1592  { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1593 
1594  template<typename _ITp>
1595  inline _ITp
1596  atomic_fetch_and(__atomic_base<_ITp>* __a,
1597  __atomic_val_t<_ITp> __i) noexcept
1598  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1599 
1600  template<typename _ITp>
1601  inline _ITp
1602  atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1603  __atomic_val_t<_ITp> __i) noexcept
1604  { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1605 
1606  template<typename _ITp>
1607  inline _ITp
1608  atomic_fetch_or(__atomic_base<_ITp>* __a,
1609  __atomic_val_t<_ITp> __i) noexcept
1610  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1611 
1612  template<typename _ITp>
1613  inline _ITp
1614  atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1615  __atomic_val_t<_ITp> __i) noexcept
1616  { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1617 
1618  template<typename _ITp>
1619  inline _ITp
1620  atomic_fetch_xor(__atomic_base<_ITp>* __a,
1621  __atomic_val_t<_ITp> __i) noexcept
1622  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1623 
1624  template<typename _ITp>
1625  inline _ITp
1626  atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1627  __atomic_val_t<_ITp> __i) noexcept
1628  { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1629 
1630 #ifdef __cpp_lib_atomic_float
1631  template<>
1632  struct atomic<float> : __atomic_float<float>
1633  {
1634  atomic() noexcept = default;
1635 
1636  constexpr
1637  atomic(float __fp) noexcept : __atomic_float<float>(__fp)
1638  { }
1639 
1640  atomic& operator=(const atomic&) volatile = delete;
1641  atomic& operator=(const atomic&) = delete;
1642 
1643  using __atomic_float<float>::operator=;
1644  };
1645 
1646  template<>
1647  struct atomic<double> : __atomic_float<double>
1648  {
1649  atomic() noexcept = default;
1650 
1651  constexpr
1652  atomic(double __fp) noexcept : __atomic_float<double>(__fp)
1653  { }
1654 
1655  atomic& operator=(const atomic&) volatile = delete;
1656  atomic& operator=(const atomic&) = delete;
1657 
1658  using __atomic_float<double>::operator=;
1659  };
1660 
1661  template<>
1662  struct atomic<long double> : __atomic_float<long double>
1663  {
1664  atomic() noexcept = default;
1665 
1666  constexpr
1667  atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
1668  { }
1669 
1670  atomic& operator=(const atomic&) volatile = delete;
1671  atomic& operator=(const atomic&) = delete;
1672 
1673  using __atomic_float<long double>::operator=;
1674  };
1675 
1676 #ifdef __STDCPP_FLOAT16_T__
1677  template<>
1678  struct atomic<_Float16> : __atomic_float<_Float16>
1679  {
1680  atomic() noexcept = default;
1681 
1682  constexpr
1683  atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp)
1684  { }
1685 
1686  atomic& operator=(const atomic&) volatile = delete;
1687  atomic& operator=(const atomic&) = delete;
1688 
1689  using __atomic_float<_Float16>::operator=;
1690  };
1691 #endif
1692 
1693 #ifdef __STDCPP_FLOAT32_T__
1694  template<>
1695  struct atomic<_Float32> : __atomic_float<_Float32>
1696  {
1697  atomic() noexcept = default;
1698 
1699  constexpr
1700  atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp)
1701  { }
1702 
1703  atomic& operator=(const atomic&) volatile = delete;
1704  atomic& operator=(const atomic&) = delete;
1705 
1706  using __atomic_float<_Float32>::operator=;
1707  };
1708 #endif
1709 
1710 #ifdef __STDCPP_FLOAT64_T__
1711  template<>
1712  struct atomic<_Float64> : __atomic_float<_Float64>
1713  {
1714  atomic() noexcept = default;
1715 
1716  constexpr
1717  atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp)
1718  { }
1719 
1720  atomic& operator=(const atomic&) volatile = delete;
1721  atomic& operator=(const atomic&) = delete;
1722 
1723  using __atomic_float<_Float64>::operator=;
1724  };
1725 #endif
1726 
1727 #ifdef __STDCPP_FLOAT128_T__
1728  template<>
1729  struct atomic<_Float128> : __atomic_float<_Float128>
1730  {
1731  atomic() noexcept = default;
1732 
1733  constexpr
1734  atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp)
1735  { }
1736 
1737  atomic& operator=(const atomic&) volatile = delete;
1738  atomic& operator=(const atomic&) = delete;
1739 
1740  using __atomic_float<_Float128>::operator=;
1741  };
1742 #endif
1743 
1744 #ifdef __STDCPP_BFLOAT16_T__
1745  template<>
1746  struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
1747  {
1748  atomic() noexcept = default;
1749 
1750  constexpr
1751  atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
1752  { }
1753 
1754  atomic& operator=(const atomic&) volatile = delete;
1755  atomic& operator=(const atomic&) = delete;
1756 
1757  using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
1758  };
1759 #endif
1760 #endif // __cpp_lib_atomic_float
1761 
1762 #ifdef __cpp_lib_atomic_ref
1763  /// Class template to provide atomic operations on a non-atomic variable.
1764  template<typename _Tp>
1765  struct atomic_ref : __atomic_ref<_Tp>
1766  {
1767  explicit
1768  atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
1769  { }
1770 
1771  atomic_ref& operator=(const atomic_ref&) = delete;
1772 
1773  atomic_ref(const atomic_ref&) = default;
1774 
1775  using __atomic_ref<_Tp>::operator=;
1776  };
1777 #endif // __cpp_lib_atomic_ref
1778 
1779 #ifdef __cpp_lib_atomic_lock_free_type_aliases
1780 # ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
1781  using atomic_signed_lock_free
1782  = atomic<make_signed_t<__detail::__platform_wait_t>>;
1783  using atomic_unsigned_lock_free
1784  = atomic<make_unsigned_t<__detail::__platform_wait_t>>;
1785 # elif ATOMIC_INT_LOCK_FREE == 2
1786  using atomic_signed_lock_free = atomic<signed int>;
1787  using atomic_unsigned_lock_free = atomic<unsigned int>;
1788 # elif ATOMIC_LONG_LOCK_FREE == 2
1789  using atomic_signed_lock_free = atomic<signed long>;
1790  using atomic_unsigned_lock_free = atomic<unsigned long>;
1791 # elif ATOMIC_CHAR_LOCK_FREE == 2
1792  using atomic_signed_lock_free = atomic<signed char>;
1793  using atomic_unsigned_lock_free = atomic<unsigned char>;
1794 # else
1795 # error "libstdc++ bug: no lock-free atomics but they were emitted in <version>"
1796 # endif
1797 #endif
1798 
1799  /// @} group atomics
1800 
1801 _GLIBCXX_END_NAMESPACE_VERSION
1802 } // namespace
1803 
1804 #endif // C++11
1805 
1806 #endif // _GLIBCXX_ATOMIC