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