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