Home | History | Annotate | Download | only in 4.8
      1 // -*- C++ -*- header.
      2 
      3 // Copyright (C) 2008-2013 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 #endif
     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   /// atomic_bool
     53   // NB: No operators or fetch-operations for this type.
     54   struct atomic_bool
     55   {
     56   private:
     57     __atomic_base<bool>	_M_base;
     58 
     59   public:
     60     atomic_bool() noexcept = default;
     61     ~atomic_bool() noexcept = default;
     62     atomic_bool(const atomic_bool&) = delete;
     63     atomic_bool& operator=(const atomic_bool&) = delete;
     64     atomic_bool& operator=(const atomic_bool&) volatile = delete;
     65 
     66     constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
     67 
     68     bool
     69     operator=(bool __i) noexcept
     70     { return _M_base.operator=(__i); }
     71 
     72     bool
     73     operator=(bool __i) volatile noexcept
     74     { return _M_base.operator=(__i); }
     75 
     76     operator bool() const noexcept
     77     { return _M_base.load(); }
     78 
     79     operator bool() const volatile noexcept
     80     { return _M_base.load(); }
     81 
     82     bool
     83     is_lock_free() const noexcept { return _M_base.is_lock_free(); }
     84 
     85     bool
     86     is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
     87 
     88     void
     89     store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
     90     { _M_base.store(__i, __m); }
     91 
     92     void
     93     store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
     94     { _M_base.store(__i, __m); }
     95 
     96     bool
     97     load(memory_order __m = memory_order_seq_cst) const noexcept
     98     { return _M_base.load(__m); }
     99 
    100     bool
    101     load(memory_order __m = memory_order_seq_cst) const volatile noexcept
    102     { return _M_base.load(__m); }
    103 
    104     bool
    105     exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
    106     { return _M_base.exchange(__i, __m); }
    107 
    108     bool
    109     exchange(bool __i,
    110 	     memory_order __m = memory_order_seq_cst) volatile noexcept
    111     { return _M_base.exchange(__i, __m); }
    112 
    113     bool
    114     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    115 			  memory_order __m2) noexcept
    116     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    117 
    118     bool
    119     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    120 			  memory_order __m2) volatile noexcept
    121     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    122 
    123     bool
    124     compare_exchange_weak(bool& __i1, bool __i2,
    125 			  memory_order __m = memory_order_seq_cst) noexcept
    126     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    127 
    128     bool
    129     compare_exchange_weak(bool& __i1, bool __i2,
    130 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    131     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    132 
    133     bool
    134     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    135 			    memory_order __m2) noexcept
    136     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    137 
    138     bool
    139     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    140 			    memory_order __m2) volatile noexcept
    141     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    142 
    143     bool
    144     compare_exchange_strong(bool& __i1, bool __i2,
    145 			    memory_order __m = memory_order_seq_cst) noexcept
    146     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    147 
    148     bool
    149     compare_exchange_strong(bool& __i1, bool __i2,
    150 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    151     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    152   };
    153 
    154 
    155   /**
    156    *  @brief Generic atomic type, primary class template.
    157    *
    158    *  @tparam _Tp  Type to be made atomic, must be trivally copyable.
    159    */
    160   template<typename _Tp>
    161     struct atomic
    162     {
    163     private:
    164       _Tp _M_i;
    165 
    166     public:
    167       atomic() noexcept = default;
    168       ~atomic() noexcept = default;
    169       atomic(const atomic&) = delete;
    170       atomic& operator=(const atomic&) = delete;
    171       atomic& operator=(const atomic&) volatile = delete;
    172 
    173       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
    174 
    175       operator _Tp() const noexcept
    176       { return load(); }
    177 
    178       operator _Tp() const volatile noexcept
    179       { return load(); }
    180 
    181       _Tp
    182       operator=(_Tp __i) noexcept 
    183       { store(__i); return __i; }
    184 
    185       _Tp
    186       operator=(_Tp __i) volatile noexcept 
    187       { store(__i); return __i; }
    188 
    189       bool
    190       is_lock_free() const noexcept
    191       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
    192 
    193       bool
    194       is_lock_free() const volatile noexcept
    195       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
    196 
    197       void
    198       store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
    199       { __atomic_store(&_M_i, &__i, _m); }
    200 
    201       void
    202       store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
    203       { __atomic_store(&_M_i, &__i, _m); }
    204 
    205       _Tp
    206       load(memory_order _m = memory_order_seq_cst) const noexcept
    207       { 
    208         _Tp tmp;
    209 	__atomic_load(&_M_i, &tmp, _m); 
    210 	return tmp;
    211       }
    212 
    213       _Tp
    214       load(memory_order _m = memory_order_seq_cst) const volatile noexcept
    215       { 
    216         _Tp tmp;
    217 	__atomic_load(&_M_i, &tmp, _m); 
    218 	return tmp;
    219       }
    220 
    221       _Tp
    222       exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
    223       { 
    224         _Tp tmp;
    225 	__atomic_exchange(&_M_i, &__i, &tmp, _m); 
    226 	return tmp;
    227       }
    228 
    229       _Tp
    230       exchange(_Tp __i, 
    231 	       memory_order _m = memory_order_seq_cst) volatile noexcept
    232       { 
    233         _Tp tmp;
    234 	__atomic_exchange(&_M_i, &__i, &tmp, _m); 
    235 	return tmp;
    236       }
    237 
    238       bool
    239       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
    240 			    memory_order __f) noexcept
    241       {
    242 	return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
    243       }
    244 
    245       bool
    246       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
    247 			    memory_order __f) volatile noexcept
    248       {
    249 	return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
    250       }
    251 
    252       bool
    253       compare_exchange_weak(_Tp& __e, _Tp __i,
    254 			    memory_order __m = memory_order_seq_cst) noexcept
    255       { return compare_exchange_weak(__e, __i, __m, __m); }
    256 
    257       bool
    258       compare_exchange_weak(_Tp& __e, _Tp __i,
    259 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    260       { return compare_exchange_weak(__e, __i, __m, __m); }
    261 
    262       bool
    263       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
    264 			      memory_order __f) noexcept
    265       {
    266 	return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
    267       }
    268 
    269       bool
    270       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
    271 			      memory_order __f) volatile noexcept
    272       {
    273 	return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
    274       }
    275 
    276       bool
    277       compare_exchange_strong(_Tp& __e, _Tp __i,
    278 			       memory_order __m = memory_order_seq_cst) noexcept
    279       { return compare_exchange_strong(__e, __i, __m, __m); }
    280 
    281       bool
    282       compare_exchange_strong(_Tp& __e, _Tp __i,
    283 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    284       { return compare_exchange_strong(__e, __i, __m, __m); }
    285     };
    286 
    287 
    288   /// Partial specialization for pointer types.
    289   template<typename _Tp>
    290     struct atomic<_Tp*>
    291     {
    292       typedef _Tp* 			__pointer_type;
    293       typedef __atomic_base<_Tp*>	__base_type;
    294       __base_type			_M_b;
    295 
    296       atomic() noexcept = default;
    297       ~atomic() noexcept = default;
    298       atomic(const atomic&) = delete;
    299       atomic& operator=(const atomic&) = delete;
    300       atomic& operator=(const atomic&) volatile = delete;
    301 
    302       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
    303 
    304       operator __pointer_type() const noexcept
    305       { return __pointer_type(_M_b); }
    306 
    307       operator __pointer_type() const volatile noexcept
    308       { return __pointer_type(_M_b); }
    309 
    310       __pointer_type
    311       operator=(__pointer_type __p) noexcept
    312       { return _M_b.operator=(__p); }
    313 
    314       __pointer_type
    315       operator=(__pointer_type __p) volatile noexcept
    316       { return _M_b.operator=(__p); }
    317 
    318       __pointer_type
    319       operator++(int) noexcept
    320       { return _M_b++; }
    321 
    322       __pointer_type
    323       operator++(int) volatile noexcept
    324       { return _M_b++; }
    325 
    326       __pointer_type
    327       operator--(int) noexcept
    328       { return _M_b--; }
    329 
    330       __pointer_type
    331       operator--(int) volatile noexcept
    332       { return _M_b--; }
    333 
    334       __pointer_type
    335       operator++() noexcept
    336       { return ++_M_b; }
    337 
    338       __pointer_type
    339       operator++() volatile noexcept
    340       { return ++_M_b; }
    341 
    342       __pointer_type
    343       operator--() noexcept
    344       { return --_M_b; }
    345 
    346       __pointer_type
    347       operator--() volatile noexcept
    348       { return --_M_b; }
    349 
    350       __pointer_type
    351       operator+=(ptrdiff_t __d) noexcept
    352       { return _M_b.operator+=(__d); }
    353 
    354       __pointer_type
    355       operator+=(ptrdiff_t __d) volatile noexcept
    356       { return _M_b.operator+=(__d); }
    357 
    358       __pointer_type
    359       operator-=(ptrdiff_t __d) noexcept
    360       { return _M_b.operator-=(__d); }
    361 
    362       __pointer_type
    363       operator-=(ptrdiff_t __d) volatile noexcept
    364       { return _M_b.operator-=(__d); }
    365 
    366       bool
    367       is_lock_free() const noexcept
    368       { return _M_b.is_lock_free(); }
    369 
    370       bool
    371       is_lock_free() const volatile noexcept
    372       { return _M_b.is_lock_free(); }
    373 
    374       void
    375       store(__pointer_type __p,
    376 	    memory_order __m = memory_order_seq_cst) noexcept
    377       { return _M_b.store(__p, __m); }
    378 
    379       void
    380       store(__pointer_type __p,
    381 	    memory_order __m = memory_order_seq_cst) volatile noexcept
    382       { return _M_b.store(__p, __m); }
    383 
    384       __pointer_type
    385       load(memory_order __m = memory_order_seq_cst) const noexcept
    386       { return _M_b.load(__m); }
    387 
    388       __pointer_type
    389       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
    390       { return _M_b.load(__m); }
    391 
    392       __pointer_type
    393       exchange(__pointer_type __p,
    394 	       memory_order __m = memory_order_seq_cst) noexcept
    395       { return _M_b.exchange(__p, __m); }
    396 
    397       __pointer_type
    398       exchange(__pointer_type __p,
    399 	       memory_order __m = memory_order_seq_cst) volatile noexcept
    400       { return _M_b.exchange(__p, __m); }
    401 
    402       bool
    403       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    404 			    memory_order __m1, memory_order __m2) noexcept
    405       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    406 
    407       bool
    408       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    409 			    memory_order __m1,
    410 			    memory_order __m2) volatile noexcept
    411       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    412 
    413       bool
    414       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    415 			    memory_order __m = memory_order_seq_cst) noexcept
    416       {
    417 	return compare_exchange_weak(__p1, __p2, __m,
    418 				     __cmpexch_failure_order(__m));
    419       }
    420 
    421       bool
    422       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    423 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    424       {
    425 	return compare_exchange_weak(__p1, __p2, __m,
    426 				     __cmpexch_failure_order(__m));
    427       }
    428 
    429       bool
    430       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    431 			      memory_order __m1, memory_order __m2) noexcept
    432       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    433 
    434       bool
    435       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    436 			      memory_order __m1,
    437 			      memory_order __m2) volatile noexcept
    438       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    439 
    440       bool
    441       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    442 			      memory_order __m = memory_order_seq_cst) noexcept
    443       {
    444 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    445 					    __cmpexch_failure_order(__m));
    446       }
    447 
    448       bool
    449       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    450 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    451       {
    452 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    453 					    __cmpexch_failure_order(__m));
    454       }
    455 
    456       __pointer_type
    457       fetch_add(ptrdiff_t __d,
    458 		memory_order __m = memory_order_seq_cst) noexcept
    459       { return _M_b.fetch_add(__d, __m); }
    460 
    461       __pointer_type
    462       fetch_add(ptrdiff_t __d,
    463 		memory_order __m = memory_order_seq_cst) volatile noexcept
    464       { return _M_b.fetch_add(__d, __m); }
    465 
    466       __pointer_type
    467       fetch_sub(ptrdiff_t __d,
    468 		memory_order __m = memory_order_seq_cst) noexcept
    469       { return _M_b.fetch_sub(__d, __m); }
    470 
    471       __pointer_type
    472       fetch_sub(ptrdiff_t __d,
    473 		memory_order __m = memory_order_seq_cst) volatile noexcept
    474       { return _M_b.fetch_sub(__d, __m); }
    475     };
    476 
    477 
    478   /// Explicit specialization for bool.
    479   template<>
    480     struct atomic<bool> : public atomic_bool
    481     {
    482       typedef bool 			__integral_type;
    483       typedef atomic_bool 		__base_type;
    484 
    485       atomic() noexcept = default;
    486       ~atomic() noexcept = default;
    487       atomic(const atomic&) = delete;
    488       atomic& operator=(const atomic&) = delete;
    489       atomic& operator=(const atomic&) volatile = delete;
    490 
    491       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    492 
    493       using __base_type::operator __integral_type;
    494       using __base_type::operator=;
    495     };
    496 
    497   /// Explicit specialization for char.
    498   template<>
    499     struct atomic<char> : public atomic_char
    500     {
    501       typedef char 			__integral_type;
    502       typedef atomic_char 		__base_type;
    503 
    504       atomic() noexcept = default;
    505       ~atomic() noexcept = default;
    506       atomic(const atomic&) = delete;
    507       atomic& operator=(const atomic&) = delete;
    508       atomic& operator=(const atomic&) volatile = delete;
    509 
    510       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    511 
    512       using __base_type::operator __integral_type;
    513       using __base_type::operator=;
    514     };
    515 
    516   /// Explicit specialization for signed char.
    517   template<>
    518     struct atomic<signed char> : public atomic_schar
    519     {
    520       typedef signed char 		__integral_type;
    521       typedef atomic_schar 		__base_type;
    522 
    523       atomic() noexcept= default;
    524       ~atomic() noexcept = default;
    525       atomic(const atomic&) = delete;
    526       atomic& operator=(const atomic&) = delete;
    527       atomic& operator=(const atomic&) volatile = delete;
    528 
    529       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    530 
    531       using __base_type::operator __integral_type;
    532       using __base_type::operator=;
    533     };
    534 
    535   /// Explicit specialization for unsigned char.
    536   template<>
    537     struct atomic<unsigned char> : public atomic_uchar
    538     {
    539       typedef unsigned char 		__integral_type;
    540       typedef atomic_uchar 		__base_type;
    541 
    542       atomic() noexcept= default;
    543       ~atomic() noexcept = default;
    544       atomic(const atomic&) = delete;
    545       atomic& operator=(const atomic&) = delete;
    546       atomic& operator=(const atomic&) volatile = delete;
    547 
    548       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    549 
    550       using __base_type::operator __integral_type;
    551       using __base_type::operator=;
    552     };
    553 
    554   /// Explicit specialization for short.
    555   template<>
    556     struct atomic<short> : public atomic_short
    557     {
    558       typedef short 			__integral_type;
    559       typedef atomic_short 		__base_type;
    560 
    561       atomic() noexcept = default;
    562       ~atomic() noexcept = default;
    563       atomic(const atomic&) = delete;
    564       atomic& operator=(const atomic&) = delete;
    565       atomic& operator=(const atomic&) volatile = delete;
    566 
    567       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    568 
    569       using __base_type::operator __integral_type;
    570       using __base_type::operator=;
    571     };
    572 
    573   /// Explicit specialization for unsigned short.
    574   template<>
    575     struct atomic<unsigned short> : public atomic_ushort
    576     {
    577       typedef unsigned short 	      	__integral_type;
    578       typedef atomic_ushort 		__base_type;
    579 
    580       atomic() noexcept = default;
    581       ~atomic() noexcept = default;
    582       atomic(const atomic&) = delete;
    583       atomic& operator=(const atomic&) = delete;
    584       atomic& operator=(const atomic&) volatile = delete;
    585 
    586       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    587 
    588       using __base_type::operator __integral_type;
    589       using __base_type::operator=;
    590     };
    591 
    592   /// Explicit specialization for int.
    593   template<>
    594     struct atomic<int> : atomic_int
    595     {
    596       typedef int 			__integral_type;
    597       typedef atomic_int 		__base_type;
    598 
    599       atomic() noexcept = default;
    600       ~atomic() noexcept = default;
    601       atomic(const atomic&) = delete;
    602       atomic& operator=(const atomic&) = delete;
    603       atomic& operator=(const atomic&) volatile = delete;
    604 
    605       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    606 
    607       using __base_type::operator __integral_type;
    608       using __base_type::operator=;
    609     };
    610 
    611   /// Explicit specialization for unsigned int.
    612   template<>
    613     struct atomic<unsigned int> : public atomic_uint
    614     {
    615       typedef unsigned int		__integral_type;
    616       typedef atomic_uint 		__base_type;
    617 
    618       atomic() noexcept = default;
    619       ~atomic() noexcept = default;
    620       atomic(const atomic&) = delete;
    621       atomic& operator=(const atomic&) = delete;
    622       atomic& operator=(const atomic&) volatile = delete;
    623 
    624       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    625 
    626       using __base_type::operator __integral_type;
    627       using __base_type::operator=;
    628     };
    629 
    630   /// Explicit specialization for long.
    631   template<>
    632     struct atomic<long> : public atomic_long
    633     {
    634       typedef long 			__integral_type;
    635       typedef atomic_long 		__base_type;
    636 
    637       atomic() noexcept = default;
    638       ~atomic() noexcept = default;
    639       atomic(const atomic&) = delete;
    640       atomic& operator=(const atomic&) = delete;
    641       atomic& operator=(const atomic&) volatile = delete;
    642 
    643       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    644 
    645       using __base_type::operator __integral_type;
    646       using __base_type::operator=;
    647     };
    648 
    649   /// Explicit specialization for unsigned long.
    650   template<>
    651     struct atomic<unsigned long> : public atomic_ulong
    652     {
    653       typedef unsigned long 		__integral_type;
    654       typedef atomic_ulong 		__base_type;
    655 
    656       atomic() noexcept = default;
    657       ~atomic() noexcept = default;
    658       atomic(const atomic&) = delete;
    659       atomic& operator=(const atomic&) = delete;
    660       atomic& operator=(const atomic&) volatile = delete;
    661 
    662       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    663 
    664       using __base_type::operator __integral_type;
    665       using __base_type::operator=;
    666     };
    667 
    668   /// Explicit specialization for long long.
    669   template<>
    670     struct atomic<long long> : public atomic_llong
    671     {
    672       typedef long long 		__integral_type;
    673       typedef atomic_llong 		__base_type;
    674 
    675       atomic() noexcept = default;
    676       ~atomic() noexcept = default;
    677       atomic(const atomic&) = delete;
    678       atomic& operator=(const atomic&) = delete;
    679       atomic& operator=(const atomic&) volatile = delete;
    680 
    681       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    682 
    683       using __base_type::operator __integral_type;
    684       using __base_type::operator=;
    685     };
    686 
    687   /// Explicit specialization for unsigned long long.
    688   template<>
    689     struct atomic<unsigned long long> : public atomic_ullong
    690     {
    691       typedef unsigned long long       	__integral_type;
    692       typedef atomic_ullong 		__base_type;
    693 
    694       atomic() noexcept = default;
    695       ~atomic() noexcept = default;
    696       atomic(const atomic&) = delete;
    697       atomic& operator=(const atomic&) = delete;
    698       atomic& operator=(const atomic&) volatile = delete;
    699 
    700       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    701 
    702       using __base_type::operator __integral_type;
    703       using __base_type::operator=;
    704     };
    705 
    706   /// Explicit specialization for wchar_t.
    707   template<>
    708     struct atomic<wchar_t> : public atomic_wchar_t
    709     {
    710       typedef wchar_t 			__integral_type;
    711       typedef atomic_wchar_t 		__base_type;
    712 
    713       atomic() noexcept = default;
    714       ~atomic() noexcept = default;
    715       atomic(const atomic&) = delete;
    716       atomic& operator=(const atomic&) = delete;
    717       atomic& operator=(const atomic&) volatile = delete;
    718 
    719       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    720 
    721       using __base_type::operator __integral_type;
    722       using __base_type::operator=;
    723     };
    724 
    725   /// Explicit specialization for char16_t.
    726   template<>
    727     struct atomic<char16_t> : public atomic_char16_t
    728     {
    729       typedef char16_t 			__integral_type;
    730       typedef atomic_char16_t 		__base_type;
    731 
    732       atomic() noexcept = default;
    733       ~atomic() noexcept = default;
    734       atomic(const atomic&) = delete;
    735       atomic& operator=(const atomic&) = delete;
    736       atomic& operator=(const atomic&) volatile = delete;
    737 
    738       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    739 
    740       using __base_type::operator __integral_type;
    741       using __base_type::operator=;
    742     };
    743 
    744   /// Explicit specialization for char32_t.
    745   template<>
    746     struct atomic<char32_t> : public atomic_char32_t
    747     {
    748       typedef char32_t 			__integral_type;
    749       typedef atomic_char32_t 		__base_type;
    750 
    751       atomic() noexcept = default;
    752       ~atomic() noexcept = default;
    753       atomic(const atomic&) = delete;
    754       atomic& operator=(const atomic&) = delete;
    755       atomic& operator=(const atomic&) volatile = delete;
    756 
    757       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    758 
    759       using __base_type::operator __integral_type;
    760       using __base_type::operator=;
    761     };
    762 
    763 
    764   // Function definitions, atomic_flag operations.
    765   inline bool
    766   atomic_flag_test_and_set_explicit(atomic_flag* __a,
    767 				    memory_order __m) noexcept
    768   { return __a->test_and_set(__m); }
    769 
    770   inline bool
    771   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
    772 				    memory_order __m) noexcept
    773   { return __a->test_and_set(__m); }
    774 
    775   inline void
    776   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
    777   { __a->clear(__m); }
    778 
    779   inline void
    780   atomic_flag_clear_explicit(volatile atomic_flag* __a,
    781 			     memory_order __m) noexcept
    782   { __a->clear(__m); }
    783 
    784   inline bool
    785   atomic_flag_test_and_set(atomic_flag* __a) noexcept
    786   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
    787 
    788   inline bool
    789   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
    790   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
    791 
    792   inline void
    793   atomic_flag_clear(atomic_flag* __a) noexcept
    794   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
    795 
    796   inline void
    797   atomic_flag_clear(volatile atomic_flag* __a) noexcept
    798   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
    799 
    800 
    801   // Function templates generally applicable to atomic types.
    802   template<typename _ITp>
    803     inline bool
    804     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
    805     { return __a->is_lock_free(); }
    806 
    807   template<typename _ITp>
    808     inline bool
    809     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
    810     { return __a->is_lock_free(); }
    811 
    812   template<typename _ITp>
    813     inline void
    814     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
    815 
    816   template<typename _ITp>
    817     inline void
    818     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
    819 
    820   template<typename _ITp>
    821     inline void
    822     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
    823 			  memory_order __m) noexcept
    824     { __a->store(__i, __m); }
    825 
    826   template<typename _ITp>
    827     inline void
    828     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
    829 			  memory_order __m) noexcept
    830     { __a->store(__i, __m); }
    831 
    832   template<typename _ITp>
    833     inline _ITp
    834     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
    835     { return __a->load(__m); }
    836 
    837   template<typename _ITp>
    838     inline _ITp
    839     atomic_load_explicit(const volatile atomic<_ITp>* __a,
    840 			 memory_order __m) noexcept
    841     { return __a->load(__m); }
    842 
    843   template<typename _ITp>
    844     inline _ITp
    845     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
    846 			     memory_order __m) noexcept
    847     { return __a->exchange(__i, __m); }
    848 
    849   template<typename _ITp>
    850     inline _ITp
    851     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
    852 			     memory_order __m) noexcept
    853     { return __a->exchange(__i, __m); }
    854 
    855   template<typename _ITp>
    856     inline bool
    857     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
    858 					  _ITp* __i1, _ITp __i2,
    859 					  memory_order __m1,
    860 					  memory_order __m2) noexcept
    861     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
    862 
    863   template<typename _ITp>
    864     inline bool
    865     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
    866 					  _ITp* __i1, _ITp __i2,
    867 					  memory_order __m1,
    868 					  memory_order __m2) noexcept
    869     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
    870 
    871   template<typename _ITp>
    872     inline bool
    873     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
    874 					    _ITp* __i1, _ITp __i2,
    875 					    memory_order __m1,
    876 					    memory_order __m2) noexcept
    877     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
    878 
    879   template<typename _ITp>
    880     inline bool
    881     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
    882 					    _ITp* __i1, _ITp __i2,
    883 					    memory_order __m1,
    884 					    memory_order __m2) noexcept
    885     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
    886 
    887 
    888   template<typename _ITp>
    889     inline void
    890     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
    891     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
    892 
    893   template<typename _ITp>
    894     inline void
    895     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
    896     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
    897 
    898   template<typename _ITp>
    899     inline _ITp
    900     atomic_load(const atomic<_ITp>* __a) noexcept
    901     { return atomic_load_explicit(__a, memory_order_seq_cst); }
    902 
    903   template<typename _ITp>
    904     inline _ITp
    905     atomic_load(const volatile atomic<_ITp>* __a) noexcept
    906     { return atomic_load_explicit(__a, memory_order_seq_cst); }
    907 
    908   template<typename _ITp>
    909     inline _ITp
    910     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
    911     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
    912 
    913   template<typename _ITp>
    914     inline _ITp
    915     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
    916     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
    917 
    918   template<typename _ITp>
    919     inline bool
    920     atomic_compare_exchange_weak(atomic<_ITp>* __a,
    921 				 _ITp* __i1, _ITp __i2) noexcept
    922     {
    923       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
    924 						   memory_order_seq_cst,
    925 						   memory_order_seq_cst);
    926     }
    927 
    928   template<typename _ITp>
    929     inline bool
    930     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
    931 				 _ITp* __i1, _ITp __i2) noexcept
    932     {
    933       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
    934 						   memory_order_seq_cst,
    935 						   memory_order_seq_cst);
    936     }
    937 
    938   template<typename _ITp>
    939     inline bool
    940     atomic_compare_exchange_strong(atomic<_ITp>* __a,
    941 				   _ITp* __i1, _ITp __i2) noexcept
    942     {
    943       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
    944 						     memory_order_seq_cst,
    945 						     memory_order_seq_cst);
    946     }
    947 
    948   template<typename _ITp>
    949     inline bool
    950     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
    951 				   _ITp* __i1, _ITp __i2) noexcept
    952     {
    953       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
    954 						     memory_order_seq_cst,
    955 						     memory_order_seq_cst);
    956     }
    957 
    958   // Function templates for atomic_integral operations only, using
    959   // __atomic_base. Template argument should be constricted to
    960   // intergral types as specified in the standard, excluding address
    961   // types.
    962   template<typename _ITp>
    963     inline _ITp
    964     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    965 			      memory_order __m) noexcept
    966     { return __a->fetch_add(__i, __m); }
    967 
    968   template<typename _ITp>
    969     inline _ITp
    970     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    971 			      memory_order __m) noexcept
    972     { return __a->fetch_add(__i, __m); }
    973 
    974   template<typename _ITp>
    975     inline _ITp
    976     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    977 			      memory_order __m) noexcept
    978     { return __a->fetch_sub(__i, __m); }
    979 
    980   template<typename _ITp>
    981     inline _ITp
    982     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    983 			      memory_order __m) noexcept
    984     { return __a->fetch_sub(__i, __m); }
    985 
    986   template<typename _ITp>
    987     inline _ITp
    988     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    989 			      memory_order __m) noexcept
    990     { return __a->fetch_and(__i, __m); }
    991 
    992   template<typename _ITp>
    993     inline _ITp
    994     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    995 			      memory_order __m) noexcept
    996     { return __a->fetch_and(__i, __m); }
    997 
    998   template<typename _ITp>
    999     inline _ITp
   1000     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
   1001 			     memory_order __m) noexcept
   1002     { return __a->fetch_or(__i, __m); }
   1003 
   1004   template<typename _ITp>
   1005     inline _ITp
   1006     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
   1007 			     memory_order __m) noexcept
   1008     { return __a->fetch_or(__i, __m); }
   1009 
   1010   template<typename _ITp>
   1011     inline _ITp
   1012     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
   1013 			      memory_order __m) noexcept
   1014     { return __a->fetch_xor(__i, __m); }
   1015 
   1016   template<typename _ITp>
   1017     inline _ITp
   1018     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
   1019 			      memory_order __m) noexcept
   1020     { return __a->fetch_xor(__i, __m); }
   1021 
   1022   template<typename _ITp>
   1023     inline _ITp
   1024     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
   1025     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
   1026 
   1027   template<typename _ITp>
   1028     inline _ITp
   1029     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
   1030     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
   1031 
   1032   template<typename _ITp>
   1033     inline _ITp
   1034     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
   1035     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
   1036 
   1037   template<typename _ITp>
   1038     inline _ITp
   1039     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
   1040     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
   1041 
   1042   template<typename _ITp>
   1043     inline _ITp
   1044     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
   1045     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
   1046 
   1047   template<typename _ITp>
   1048     inline _ITp
   1049     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
   1050     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
   1051 
   1052   template<typename _ITp>
   1053     inline _ITp
   1054     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
   1055     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
   1056 
   1057   template<typename _ITp>
   1058     inline _ITp
   1059     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
   1060     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
   1061 
   1062   template<typename _ITp>
   1063     inline _ITp
   1064     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
   1065     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
   1066 
   1067   template<typename _ITp>
   1068     inline _ITp
   1069     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
   1070     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
   1071 
   1072 
   1073   // Partial specializations for pointers.
   1074   template<typename _ITp>
   1075     inline _ITp*
   1076     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
   1077 			      memory_order __m) noexcept
   1078     { return __a->fetch_add(__d, __m); }
   1079 
   1080   template<typename _ITp>
   1081     inline _ITp*
   1082     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
   1083 			      memory_order __m) noexcept
   1084     { return __a->fetch_add(__d, __m); }
   1085 
   1086   template<typename _ITp>
   1087     inline _ITp*
   1088     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
   1089     { return __a->fetch_add(__d); }
   1090 
   1091   template<typename _ITp>
   1092     inline _ITp*
   1093     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
   1094     { return __a->fetch_add(__d); }
   1095 
   1096   template<typename _ITp>
   1097     inline _ITp*
   1098     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
   1099 			      ptrdiff_t __d, memory_order __m) noexcept
   1100     { return __a->fetch_sub(__d, __m); }
   1101 
   1102   template<typename _ITp>
   1103     inline _ITp*
   1104     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
   1105 			      memory_order __m) noexcept
   1106     { return __a->fetch_sub(__d, __m); }
   1107 
   1108   template<typename _ITp>
   1109     inline _ITp*
   1110     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
   1111     { return __a->fetch_sub(__d); }
   1112 
   1113   template<typename _ITp>
   1114     inline _ITp*
   1115     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
   1116     { return __a->fetch_sub(__d); }
   1117   // @} group atomics
   1118 
   1119 _GLIBCXX_END_NAMESPACE_VERSION
   1120 } // namespace
   1121 
   1122 #endif
   1123