1// -*- C++ -*- header.
2
3// Copyright (C) 2008-2018 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
44namespace 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#ifdef _GLIBCXX_USE_C99_STDINT_TR1
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#endif
990
991
992  /// atomic_intptr_t
993  typedef atomic<intptr_t>		atomic_intptr_t;
994
995  /// atomic_uintptr_t
996  typedef atomic<uintptr_t>		atomic_uintptr_t;
997
998  /// atomic_size_t
999  typedef atomic<size_t>		atomic_size_t;
1000
1001  /// atomic_ptrdiff_t
1002  typedef atomic<ptrdiff_t>		atomic_ptrdiff_t;
1003
1004#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1005  /// atomic_intmax_t
1006  typedef atomic<intmax_t>		atomic_intmax_t;
1007
1008  /// atomic_uintmax_t
1009  typedef atomic<uintmax_t>		atomic_uintmax_t;
1010#endif
1011
1012  // Function definitions, atomic_flag operations.
1013  inline bool
1014  atomic_flag_test_and_set_explicit(atomic_flag* __a,
1015				    memory_order __m) noexcept
1016  { return __a->test_and_set(__m); }
1017
1018  inline bool
1019  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
1020				    memory_order __m) noexcept
1021  { return __a->test_and_set(__m); }
1022
1023  inline void
1024  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
1025  { __a->clear(__m); }
1026
1027  inline void
1028  atomic_flag_clear_explicit(volatile atomic_flag* __a,
1029			     memory_order __m) noexcept
1030  { __a->clear(__m); }
1031
1032  inline bool
1033  atomic_flag_test_and_set(atomic_flag* __a) noexcept
1034  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1035
1036  inline bool
1037  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
1038  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
1039
1040  inline void
1041  atomic_flag_clear(atomic_flag* __a) noexcept
1042  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1043
1044  inline void
1045  atomic_flag_clear(volatile atomic_flag* __a) noexcept
1046  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
1047
1048
1049  // Function templates generally applicable to atomic types.
1050  template<typename _ITp>
1051    inline bool
1052    atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
1053    { return __a->is_lock_free(); }
1054
1055  template<typename _ITp>
1056    inline bool
1057    atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
1058    { return __a->is_lock_free(); }
1059
1060  template<typename _ITp>
1061    inline void
1062    atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
1063    { __a->store(__i, memory_order_relaxed); }
1064
1065  template<typename _ITp>
1066    inline void
1067    atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1068    { __a->store(__i, memory_order_relaxed); }
1069
1070  template<typename _ITp>
1071    inline void
1072    atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
1073			  memory_order __m) noexcept
1074    { __a->store(__i, __m); }
1075
1076  template<typename _ITp>
1077    inline void
1078    atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
1079			  memory_order __m) noexcept
1080    { __a->store(__i, __m); }
1081
1082  template<typename _ITp>
1083    inline _ITp
1084    atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
1085    { return __a->load(__m); }
1086
1087  template<typename _ITp>
1088    inline _ITp
1089    atomic_load_explicit(const volatile atomic<_ITp>* __a,
1090			 memory_order __m) noexcept
1091    { return __a->load(__m); }
1092
1093  template<typename _ITp>
1094    inline _ITp
1095    atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
1096			     memory_order __m) noexcept
1097    { return __a->exchange(__i, __m); }
1098
1099  template<typename _ITp>
1100    inline _ITp
1101    atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
1102			     memory_order __m) noexcept
1103    { return __a->exchange(__i, __m); }
1104
1105  template<typename _ITp>
1106    inline bool
1107    atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1108					  _ITp* __i1, _ITp __i2,
1109					  memory_order __m1,
1110					  memory_order __m2) noexcept
1111    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1112
1113  template<typename _ITp>
1114    inline bool
1115    atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1116					  _ITp* __i1, _ITp __i2,
1117					  memory_order __m1,
1118					  memory_order __m2) noexcept
1119    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
1120
1121  template<typename _ITp>
1122    inline bool
1123    atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1124					    _ITp* __i1, _ITp __i2,
1125					    memory_order __m1,
1126					    memory_order __m2) noexcept
1127    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1128
1129  template<typename _ITp>
1130    inline bool
1131    atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1132					    _ITp* __i1, _ITp __i2,
1133					    memory_order __m1,
1134					    memory_order __m2) noexcept
1135    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
1136
1137
1138  template<typename _ITp>
1139    inline void
1140    atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
1141    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1142
1143  template<typename _ITp>
1144    inline void
1145    atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1146    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
1147
1148  template<typename _ITp>
1149    inline _ITp
1150    atomic_load(const atomic<_ITp>* __a) noexcept
1151    { return atomic_load_explicit(__a, memory_order_seq_cst); }
1152
1153  template<typename _ITp>
1154    inline _ITp
1155    atomic_load(const volatile atomic<_ITp>* __a) noexcept
1156    { return atomic_load_explicit(__a, memory_order_seq_cst); }
1157
1158  template<typename _ITp>
1159    inline _ITp
1160    atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
1161    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1162
1163  template<typename _ITp>
1164    inline _ITp
1165    atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
1166    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
1167
1168  template<typename _ITp>
1169    inline bool
1170    atomic_compare_exchange_weak(atomic<_ITp>* __a,
1171				 _ITp* __i1, _ITp __i2) noexcept
1172    {
1173      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1174						   memory_order_seq_cst,
1175						   memory_order_seq_cst);
1176    }
1177
1178  template<typename _ITp>
1179    inline bool
1180    atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1181				 _ITp* __i1, _ITp __i2) noexcept
1182    {
1183      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
1184						   memory_order_seq_cst,
1185						   memory_order_seq_cst);
1186    }
1187
1188  template<typename _ITp>
1189    inline bool
1190    atomic_compare_exchange_strong(atomic<_ITp>* __a,
1191				   _ITp* __i1, _ITp __i2) noexcept
1192    {
1193      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1194						     memory_order_seq_cst,
1195						     memory_order_seq_cst);
1196    }
1197
1198  template<typename _ITp>
1199    inline bool
1200    atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1201				   _ITp* __i1, _ITp __i2) noexcept
1202    {
1203      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
1204						     memory_order_seq_cst,
1205						     memory_order_seq_cst);
1206    }
1207
1208  // Function templates for atomic_integral operations only, using
1209  // __atomic_base. Template argument should be constricted to
1210  // intergral types as specified in the standard, excluding address
1211  // types.
1212  template<typename _ITp>
1213    inline _ITp
1214    atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1215			      memory_order __m) noexcept
1216    { return __a->fetch_add(__i, __m); }
1217
1218  template<typename _ITp>
1219    inline _ITp
1220    atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1221			      memory_order __m) noexcept
1222    { return __a->fetch_add(__i, __m); }
1223
1224  template<typename _ITp>
1225    inline _ITp
1226    atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1227			      memory_order __m) noexcept
1228    { return __a->fetch_sub(__i, __m); }
1229
1230  template<typename _ITp>
1231    inline _ITp
1232    atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1233			      memory_order __m) noexcept
1234    { return __a->fetch_sub(__i, __m); }
1235
1236  template<typename _ITp>
1237    inline _ITp
1238    atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1239			      memory_order __m) noexcept
1240    { return __a->fetch_and(__i, __m); }
1241
1242  template<typename _ITp>
1243    inline _ITp
1244    atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1245			      memory_order __m) noexcept
1246    { return __a->fetch_and(__i, __m); }
1247
1248  template<typename _ITp>
1249    inline _ITp
1250    atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1251			     memory_order __m) noexcept
1252    { return __a->fetch_or(__i, __m); }
1253
1254  template<typename _ITp>
1255    inline _ITp
1256    atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1257			     memory_order __m) noexcept
1258    { return __a->fetch_or(__i, __m); }
1259
1260  template<typename _ITp>
1261    inline _ITp
1262    atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
1263			      memory_order __m) noexcept
1264    { return __a->fetch_xor(__i, __m); }
1265
1266  template<typename _ITp>
1267    inline _ITp
1268    atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
1269			      memory_order __m) noexcept
1270    { return __a->fetch_xor(__i, __m); }
1271
1272  template<typename _ITp>
1273    inline _ITp
1274    atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1275    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1276
1277  template<typename _ITp>
1278    inline _ITp
1279    atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1280    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
1281
1282  template<typename _ITp>
1283    inline _ITp
1284    atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1285    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1286
1287  template<typename _ITp>
1288    inline _ITp
1289    atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1290    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
1291
1292  template<typename _ITp>
1293    inline _ITp
1294    atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1295    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1296
1297  template<typename _ITp>
1298    inline _ITp
1299    atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1300    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
1301
1302  template<typename _ITp>
1303    inline _ITp
1304    atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1305    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1306
1307  template<typename _ITp>
1308    inline _ITp
1309    atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1310    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
1311
1312  template<typename _ITp>
1313    inline _ITp
1314    atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
1315    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1316
1317  template<typename _ITp>
1318    inline _ITp
1319    atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
1320    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
1321
1322
1323  // Partial specializations for pointers.
1324  template<typename _ITp>
1325    inline _ITp*
1326    atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1327			      memory_order __m) noexcept
1328    { return __a->fetch_add(__d, __m); }
1329
1330  template<typename _ITp>
1331    inline _ITp*
1332    atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
1333			      memory_order __m) noexcept
1334    { return __a->fetch_add(__d, __m); }
1335
1336  template<typename _ITp>
1337    inline _ITp*
1338    atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1339    { return __a->fetch_add(__d); }
1340
1341  template<typename _ITp>
1342    inline _ITp*
1343    atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1344    { return __a->fetch_add(__d); }
1345
1346  template<typename _ITp>
1347    inline _ITp*
1348    atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
1349			      ptrdiff_t __d, memory_order __m) noexcept
1350    { return __a->fetch_sub(__d, __m); }
1351
1352  template<typename _ITp>
1353    inline _ITp*
1354    atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
1355			      memory_order __m) noexcept
1356    { return __a->fetch_sub(__d, __m); }
1357
1358  template<typename _ITp>
1359    inline _ITp*
1360    atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1361    { return __a->fetch_sub(__d); }
1362
1363  template<typename _ITp>
1364    inline _ITp*
1365    atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
1366    { return __a->fetch_sub(__d); }
1367  // @} group atomics
1368
1369_GLIBCXX_END_NAMESPACE_VERSION
1370} // namespace
1371
1372#endif // C++11
1373
1374#endif // _GLIBCXX_ATOMIC
1375