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