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