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