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