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