libstdc++
atomic
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008-2014 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/atomic
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
00030 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
00031 
00032 #ifndef _GLIBCXX_ATOMIC
00033 #define _GLIBCXX_ATOMIC 1
00034 
00035 #pragma GCC system_header
00036 
00037 #if __cplusplus < 201103L
00038 # include <bits/c++0x_warning.h>
00039 #endif
00040 
00041 #include <bits/atomic_base.h>
00042 
00043 namespace std _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046 
00047   /**
00048    * @addtogroup atomics
00049    * @{
00050    */
00051 
00052   /// atomic_bool
00053   // NB: No operators or fetch-operations for this type.
00054   struct atomic_bool
00055   {
00056   private:
00057     __atomic_base<bool> _M_base;
00058 
00059   public:
00060     atomic_bool() noexcept = default;
00061     ~atomic_bool() noexcept = default;
00062     atomic_bool(const atomic_bool&) = delete;
00063     atomic_bool& operator=(const atomic_bool&) = delete;
00064     atomic_bool& operator=(const atomic_bool&) volatile = delete;
00065 
00066     constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { }
00067 
00068     bool
00069     operator=(bool __i) noexcept
00070     { return _M_base.operator=(__i); }
00071 
00072     bool
00073     operator=(bool __i) volatile noexcept
00074     { return _M_base.operator=(__i); }
00075 
00076     operator bool() const noexcept
00077     { return _M_base.load(); }
00078 
00079     operator bool() const volatile noexcept
00080     { return _M_base.load(); }
00081 
00082     bool
00083     is_lock_free() const noexcept { return _M_base.is_lock_free(); }
00084 
00085     bool
00086     is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
00087 
00088     void
00089     store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
00090     { _M_base.store(__i, __m); }
00091 
00092     void
00093     store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
00094     { _M_base.store(__i, __m); }
00095 
00096     bool
00097     load(memory_order __m = memory_order_seq_cst) const noexcept
00098     { return _M_base.load(__m); }
00099 
00100     bool
00101     load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00102     { return _M_base.load(__m); }
00103 
00104     bool
00105     exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
00106     { return _M_base.exchange(__i, __m); }
00107 
00108     bool
00109     exchange(bool __i,
00110          memory_order __m = memory_order_seq_cst) volatile noexcept
00111     { return _M_base.exchange(__i, __m); }
00112 
00113     bool
00114     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00115               memory_order __m2) noexcept
00116     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00117 
00118     bool
00119     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00120               memory_order __m2) volatile noexcept
00121     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00122 
00123     bool
00124     compare_exchange_weak(bool& __i1, bool __i2,
00125               memory_order __m = memory_order_seq_cst) noexcept
00126     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00127 
00128     bool
00129     compare_exchange_weak(bool& __i1, bool __i2,
00130              memory_order __m = memory_order_seq_cst) volatile noexcept
00131     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00132 
00133     bool
00134     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00135                 memory_order __m2) noexcept
00136     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00137 
00138     bool
00139     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00140                 memory_order __m2) volatile noexcept
00141     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00142 
00143     bool
00144     compare_exchange_strong(bool& __i1, bool __i2,
00145                 memory_order __m = memory_order_seq_cst) noexcept
00146     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00147 
00148     bool
00149     compare_exchange_strong(bool& __i1, bool __i2,
00150             memory_order __m = memory_order_seq_cst) volatile noexcept
00151     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00152   };
00153 
00154 
00155   /**
00156    *  @brief Generic atomic type, primary class template.
00157    *
00158    *  @tparam _Tp  Type to be made atomic, must be trivally copyable.
00159    */
00160   template<typename _Tp>
00161     struct atomic
00162     {
00163     private:
00164       _Tp _M_i;
00165 
00166     public:
00167       atomic() noexcept = default;
00168       ~atomic() noexcept = default;
00169       atomic(const atomic&) = delete;
00170       atomic& operator=(const atomic&) = delete;
00171       atomic& operator=(const atomic&) volatile = delete;
00172 
00173       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
00174 
00175       operator _Tp() const noexcept
00176       { return load(); }
00177 
00178       operator _Tp() const volatile noexcept
00179       { return load(); }
00180 
00181       _Tp
00182       operator=(_Tp __i) noexcept 
00183       { store(__i); return __i; }
00184 
00185       _Tp
00186       operator=(_Tp __i) volatile noexcept 
00187       { store(__i); return __i; }
00188 
00189       bool
00190       is_lock_free() const noexcept
00191       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
00192 
00193       bool
00194       is_lock_free() const volatile noexcept
00195       { return __atomic_is_lock_free(sizeof(_M_i), nullptr); }
00196 
00197       void
00198       store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
00199       { __atomic_store(&_M_i, &__i, _m); }
00200 
00201       void
00202       store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
00203       { __atomic_store(&_M_i, &__i, _m); }
00204 
00205       _Tp
00206       load(memory_order _m = memory_order_seq_cst) const noexcept
00207       { 
00208         _Tp tmp;
00209     __atomic_load(&_M_i, &tmp, _m); 
00210     return tmp;
00211       }
00212 
00213       _Tp
00214       load(memory_order _m = memory_order_seq_cst) const volatile noexcept
00215       { 
00216         _Tp tmp;
00217     __atomic_load(&_M_i, &tmp, _m); 
00218     return tmp;
00219       }
00220 
00221       _Tp
00222       exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
00223       { 
00224         _Tp tmp;
00225     __atomic_exchange(&_M_i, &__i, &tmp, _m); 
00226     return tmp;
00227       }
00228 
00229       _Tp
00230       exchange(_Tp __i, 
00231            memory_order _m = memory_order_seq_cst) volatile noexcept
00232       { 
00233         _Tp tmp;
00234     __atomic_exchange(&_M_i, &__i, &tmp, _m); 
00235     return tmp;
00236       }
00237 
00238       bool
00239       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00240                 memory_order __f) noexcept
00241       {
00242     return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
00243       }
00244 
00245       bool
00246       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00247                 memory_order __f) volatile noexcept
00248       {
00249     return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
00250       }
00251 
00252       bool
00253       compare_exchange_weak(_Tp& __e, _Tp __i,
00254                 memory_order __m = memory_order_seq_cst) noexcept
00255       { return compare_exchange_weak(__e, __i, __m,
00256                                      __cmpexch_failure_order(__m)); }
00257 
00258       bool
00259       compare_exchange_weak(_Tp& __e, _Tp __i,
00260              memory_order __m = memory_order_seq_cst) volatile noexcept
00261       { return compare_exchange_weak(__e, __i, __m,
00262                                      __cmpexch_failure_order(__m)); }
00263 
00264       bool
00265       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00266                   memory_order __f) noexcept
00267       {
00268     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00269       }
00270 
00271       bool
00272       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00273                   memory_order __f) volatile noexcept
00274       {
00275     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00276       }
00277 
00278       bool
00279       compare_exchange_strong(_Tp& __e, _Tp __i,
00280                    memory_order __m = memory_order_seq_cst) noexcept
00281       { return compare_exchange_strong(__e, __i, __m,
00282                                        __cmpexch_failure_order(__m)); }
00283 
00284       bool
00285       compare_exchange_strong(_Tp& __e, _Tp __i,
00286              memory_order __m = memory_order_seq_cst) volatile noexcept
00287       { return compare_exchange_strong(__e, __i, __m,
00288                                        __cmpexch_failure_order(__m)); }
00289     };
00290 
00291 
00292   /// Partial specialization for pointer types.
00293   template<typename _Tp>
00294     struct atomic<_Tp*>
00295     {
00296       typedef _Tp*          __pointer_type;
00297       typedef __atomic_base<_Tp*>   __base_type;
00298       __base_type           _M_b;
00299 
00300       atomic() noexcept = default;
00301       ~atomic() noexcept = default;
00302       atomic(const atomic&) = delete;
00303       atomic& operator=(const atomic&) = delete;
00304       atomic& operator=(const atomic&) volatile = delete;
00305 
00306       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
00307 
00308       operator __pointer_type() const noexcept
00309       { return __pointer_type(_M_b); }
00310 
00311       operator __pointer_type() const volatile noexcept
00312       { return __pointer_type(_M_b); }
00313 
00314       __pointer_type
00315       operator=(__pointer_type __p) noexcept
00316       { return _M_b.operator=(__p); }
00317 
00318       __pointer_type
00319       operator=(__pointer_type __p) volatile noexcept
00320       { return _M_b.operator=(__p); }
00321 
00322       __pointer_type
00323       operator++(int) noexcept
00324       { return _M_b++; }
00325 
00326       __pointer_type
00327       operator++(int) volatile noexcept
00328       { return _M_b++; }
00329 
00330       __pointer_type
00331       operator--(int) noexcept
00332       { return _M_b--; }
00333 
00334       __pointer_type
00335       operator--(int) volatile noexcept
00336       { return _M_b--; }
00337 
00338       __pointer_type
00339       operator++() noexcept
00340       { return ++_M_b; }
00341 
00342       __pointer_type
00343       operator++() volatile noexcept
00344       { return ++_M_b; }
00345 
00346       __pointer_type
00347       operator--() noexcept
00348       { return --_M_b; }
00349 
00350       __pointer_type
00351       operator--() volatile noexcept
00352       { return --_M_b; }
00353 
00354       __pointer_type
00355       operator+=(ptrdiff_t __d) noexcept
00356       { return _M_b.operator+=(__d); }
00357 
00358       __pointer_type
00359       operator+=(ptrdiff_t __d) volatile noexcept
00360       { return _M_b.operator+=(__d); }
00361 
00362       __pointer_type
00363       operator-=(ptrdiff_t __d) noexcept
00364       { return _M_b.operator-=(__d); }
00365 
00366       __pointer_type
00367       operator-=(ptrdiff_t __d) volatile noexcept
00368       { return _M_b.operator-=(__d); }
00369 
00370       bool
00371       is_lock_free() const noexcept
00372       { return _M_b.is_lock_free(); }
00373 
00374       bool
00375       is_lock_free() const volatile noexcept
00376       { return _M_b.is_lock_free(); }
00377 
00378       void
00379       store(__pointer_type __p,
00380         memory_order __m = memory_order_seq_cst) noexcept
00381       { return _M_b.store(__p, __m); }
00382 
00383       void
00384       store(__pointer_type __p,
00385         memory_order __m = memory_order_seq_cst) volatile noexcept
00386       { return _M_b.store(__p, __m); }
00387 
00388       __pointer_type
00389       load(memory_order __m = memory_order_seq_cst) const noexcept
00390       { return _M_b.load(__m); }
00391 
00392       __pointer_type
00393       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00394       { return _M_b.load(__m); }
00395 
00396       __pointer_type
00397       exchange(__pointer_type __p,
00398            memory_order __m = memory_order_seq_cst) noexcept
00399       { return _M_b.exchange(__p, __m); }
00400 
00401       __pointer_type
00402       exchange(__pointer_type __p,
00403            memory_order __m = memory_order_seq_cst) volatile noexcept
00404       { return _M_b.exchange(__p, __m); }
00405 
00406       bool
00407       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00408                 memory_order __m1, memory_order __m2) noexcept
00409       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00410 
00411       bool
00412       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00413                 memory_order __m1,
00414                 memory_order __m2) volatile noexcept
00415       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00416 
00417       bool
00418       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00419                 memory_order __m = memory_order_seq_cst) noexcept
00420       {
00421     return compare_exchange_weak(__p1, __p2, __m,
00422                      __cmpexch_failure_order(__m));
00423       }
00424 
00425       bool
00426       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00427             memory_order __m = memory_order_seq_cst) volatile noexcept
00428       {
00429     return compare_exchange_weak(__p1, __p2, __m,
00430                      __cmpexch_failure_order(__m));
00431       }
00432 
00433       bool
00434       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00435                   memory_order __m1, memory_order __m2) noexcept
00436       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00437 
00438       bool
00439       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00440                   memory_order __m1,
00441                   memory_order __m2) volatile noexcept
00442       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00443 
00444       bool
00445       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00446                   memory_order __m = memory_order_seq_cst) noexcept
00447       {
00448     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00449                         __cmpexch_failure_order(__m));
00450       }
00451 
00452       bool
00453       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00454             memory_order __m = memory_order_seq_cst) volatile noexcept
00455       {
00456     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00457                         __cmpexch_failure_order(__m));
00458       }
00459 
00460       __pointer_type
00461       fetch_add(ptrdiff_t __d,
00462         memory_order __m = memory_order_seq_cst) noexcept
00463       { return _M_b.fetch_add(__d, __m); }
00464 
00465       __pointer_type
00466       fetch_add(ptrdiff_t __d,
00467         memory_order __m = memory_order_seq_cst) volatile noexcept
00468       { return _M_b.fetch_add(__d, __m); }
00469 
00470       __pointer_type
00471       fetch_sub(ptrdiff_t __d,
00472         memory_order __m = memory_order_seq_cst) noexcept
00473       { return _M_b.fetch_sub(__d, __m); }
00474 
00475       __pointer_type
00476       fetch_sub(ptrdiff_t __d,
00477         memory_order __m = memory_order_seq_cst) volatile noexcept
00478       { return _M_b.fetch_sub(__d, __m); }
00479     };
00480 
00481 
00482   /// Explicit specialization for bool.
00483   template<>
00484     struct atomic<bool> : public atomic_bool
00485     {
00486       typedef bool          __integral_type;
00487       typedef atomic_bool       __base_type;
00488 
00489       atomic() noexcept = default;
00490       ~atomic() noexcept = default;
00491       atomic(const atomic&) = delete;
00492       atomic& operator=(const atomic&) = delete;
00493       atomic& operator=(const atomic&) volatile = delete;
00494 
00495       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00496 
00497       using __base_type::operator __integral_type;
00498       using __base_type::operator=;
00499     };
00500 
00501   /// Explicit specialization for char.
00502   template<>
00503     struct atomic<char> : public atomic_char
00504     {
00505       typedef char          __integral_type;
00506       typedef atomic_char       __base_type;
00507 
00508       atomic() noexcept = default;
00509       ~atomic() noexcept = default;
00510       atomic(const atomic&) = delete;
00511       atomic& operator=(const atomic&) = delete;
00512       atomic& operator=(const atomic&) volatile = delete;
00513 
00514       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00515 
00516       using __base_type::operator __integral_type;
00517       using __base_type::operator=;
00518     };
00519 
00520   /// Explicit specialization for signed char.
00521   template<>
00522     struct atomic<signed char> : public atomic_schar
00523     {
00524       typedef signed char       __integral_type;
00525       typedef atomic_schar      __base_type;
00526 
00527       atomic() noexcept= default;
00528       ~atomic() noexcept = default;
00529       atomic(const atomic&) = delete;
00530       atomic& operator=(const atomic&) = delete;
00531       atomic& operator=(const atomic&) volatile = delete;
00532 
00533       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00534 
00535       using __base_type::operator __integral_type;
00536       using __base_type::operator=;
00537     };
00538 
00539   /// Explicit specialization for unsigned char.
00540   template<>
00541     struct atomic<unsigned char> : public atomic_uchar
00542     {
00543       typedef unsigned char         __integral_type;
00544       typedef atomic_uchar      __base_type;
00545 
00546       atomic() noexcept= default;
00547       ~atomic() noexcept = default;
00548       atomic(const atomic&) = delete;
00549       atomic& operator=(const atomic&) = delete;
00550       atomic& operator=(const atomic&) volatile = delete;
00551 
00552       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00553 
00554       using __base_type::operator __integral_type;
00555       using __base_type::operator=;
00556     };
00557 
00558   /// Explicit specialization for short.
00559   template<>
00560     struct atomic<short> : public atomic_short
00561     {
00562       typedef short             __integral_type;
00563       typedef atomic_short      __base_type;
00564 
00565       atomic() noexcept = default;
00566       ~atomic() noexcept = default;
00567       atomic(const atomic&) = delete;
00568       atomic& operator=(const atomic&) = delete;
00569       atomic& operator=(const atomic&) volatile = delete;
00570 
00571       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00572 
00573       using __base_type::operator __integral_type;
00574       using __base_type::operator=;
00575     };
00576 
00577   /// Explicit specialization for unsigned short.
00578   template<>
00579     struct atomic<unsigned short> : public atomic_ushort
00580     {
00581       typedef unsigned short            __integral_type;
00582       typedef atomic_ushort         __base_type;
00583 
00584       atomic() noexcept = default;
00585       ~atomic() noexcept = default;
00586       atomic(const atomic&) = delete;
00587       atomic& operator=(const atomic&) = delete;
00588       atomic& operator=(const atomic&) volatile = delete;
00589 
00590       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00591 
00592       using __base_type::operator __integral_type;
00593       using __base_type::operator=;
00594     };
00595 
00596   /// Explicit specialization for int.
00597   template<>
00598     struct atomic<int> : atomic_int
00599     {
00600       typedef int           __integral_type;
00601       typedef atomic_int        __base_type;
00602 
00603       atomic() noexcept = default;
00604       ~atomic() noexcept = default;
00605       atomic(const atomic&) = delete;
00606       atomic& operator=(const atomic&) = delete;
00607       atomic& operator=(const atomic&) volatile = delete;
00608 
00609       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00610 
00611       using __base_type::operator __integral_type;
00612       using __base_type::operator=;
00613     };
00614 
00615   /// Explicit specialization for unsigned int.
00616   template<>
00617     struct atomic<unsigned int> : public atomic_uint
00618     {
00619       typedef unsigned int      __integral_type;
00620       typedef atomic_uint       __base_type;
00621 
00622       atomic() noexcept = default;
00623       ~atomic() noexcept = default;
00624       atomic(const atomic&) = delete;
00625       atomic& operator=(const atomic&) = delete;
00626       atomic& operator=(const atomic&) volatile = delete;
00627 
00628       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00629 
00630       using __base_type::operator __integral_type;
00631       using __base_type::operator=;
00632     };
00633 
00634   /// Explicit specialization for long.
00635   template<>
00636     struct atomic<long> : public atomic_long
00637     {
00638       typedef long          __integral_type;
00639       typedef atomic_long       __base_type;
00640 
00641       atomic() noexcept = default;
00642       ~atomic() noexcept = default;
00643       atomic(const atomic&) = delete;
00644       atomic& operator=(const atomic&) = delete;
00645       atomic& operator=(const atomic&) volatile = delete;
00646 
00647       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00648 
00649       using __base_type::operator __integral_type;
00650       using __base_type::operator=;
00651     };
00652 
00653   /// Explicit specialization for unsigned long.
00654   template<>
00655     struct atomic<unsigned long> : public atomic_ulong
00656     {
00657       typedef unsigned long         __integral_type;
00658       typedef atomic_ulong      __base_type;
00659 
00660       atomic() noexcept = default;
00661       ~atomic() noexcept = default;
00662       atomic(const atomic&) = delete;
00663       atomic& operator=(const atomic&) = delete;
00664       atomic& operator=(const atomic&) volatile = delete;
00665 
00666       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00667 
00668       using __base_type::operator __integral_type;
00669       using __base_type::operator=;
00670     };
00671 
00672   /// Explicit specialization for long long.
00673   template<>
00674     struct atomic<long long> : public atomic_llong
00675     {
00676       typedef long long         __integral_type;
00677       typedef atomic_llong      __base_type;
00678 
00679       atomic() noexcept = default;
00680       ~atomic() noexcept = default;
00681       atomic(const atomic&) = delete;
00682       atomic& operator=(const atomic&) = delete;
00683       atomic& operator=(const atomic&) volatile = delete;
00684 
00685       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00686 
00687       using __base_type::operator __integral_type;
00688       using __base_type::operator=;
00689     };
00690 
00691   /// Explicit specialization for unsigned long long.
00692   template<>
00693     struct atomic<unsigned long long> : public atomic_ullong
00694     {
00695       typedef unsigned long long        __integral_type;
00696       typedef atomic_ullong         __base_type;
00697 
00698       atomic() noexcept = default;
00699       ~atomic() noexcept = default;
00700       atomic(const atomic&) = delete;
00701       atomic& operator=(const atomic&) = delete;
00702       atomic& operator=(const atomic&) volatile = delete;
00703 
00704       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00705 
00706       using __base_type::operator __integral_type;
00707       using __base_type::operator=;
00708     };
00709 
00710   /// Explicit specialization for wchar_t.
00711   template<>
00712     struct atomic<wchar_t> : public atomic_wchar_t
00713     {
00714       typedef wchar_t           __integral_type;
00715       typedef atomic_wchar_t        __base_type;
00716 
00717       atomic() noexcept = default;
00718       ~atomic() noexcept = default;
00719       atomic(const atomic&) = delete;
00720       atomic& operator=(const atomic&) = delete;
00721       atomic& operator=(const atomic&) volatile = delete;
00722 
00723       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00724 
00725       using __base_type::operator __integral_type;
00726       using __base_type::operator=;
00727     };
00728 
00729   /// Explicit specialization for char16_t.
00730   template<>
00731     struct atomic<char16_t> : public atomic_char16_t
00732     {
00733       typedef char16_t          __integral_type;
00734       typedef atomic_char16_t       __base_type;
00735 
00736       atomic() noexcept = default;
00737       ~atomic() noexcept = default;
00738       atomic(const atomic&) = delete;
00739       atomic& operator=(const atomic&) = delete;
00740       atomic& operator=(const atomic&) volatile = delete;
00741 
00742       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00743 
00744       using __base_type::operator __integral_type;
00745       using __base_type::operator=;
00746     };
00747 
00748   /// Explicit specialization for char32_t.
00749   template<>
00750     struct atomic<char32_t> : public atomic_char32_t
00751     {
00752       typedef char32_t          __integral_type;
00753       typedef atomic_char32_t       __base_type;
00754 
00755       atomic() noexcept = default;
00756       ~atomic() noexcept = default;
00757       atomic(const atomic&) = delete;
00758       atomic& operator=(const atomic&) = delete;
00759       atomic& operator=(const atomic&) volatile = delete;
00760 
00761       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00762 
00763       using __base_type::operator __integral_type;
00764       using __base_type::operator=;
00765     };
00766 
00767 
00768   // Function definitions, atomic_flag operations.
00769   inline bool
00770   atomic_flag_test_and_set_explicit(atomic_flag* __a,
00771                     memory_order __m) noexcept
00772   { return __a->test_and_set(__m); }
00773 
00774   inline bool
00775   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
00776                     memory_order __m) noexcept
00777   { return __a->test_and_set(__m); }
00778 
00779   inline void
00780   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
00781   { __a->clear(__m); }
00782 
00783   inline void
00784   atomic_flag_clear_explicit(volatile atomic_flag* __a,
00785                  memory_order __m) noexcept
00786   { __a->clear(__m); }
00787 
00788   inline bool
00789   atomic_flag_test_and_set(atomic_flag* __a) noexcept
00790   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00791 
00792   inline bool
00793   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
00794   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00795 
00796   inline void
00797   atomic_flag_clear(atomic_flag* __a) noexcept
00798   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00799 
00800   inline void
00801   atomic_flag_clear(volatile atomic_flag* __a) noexcept
00802   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00803 
00804 
00805   // Function templates generally applicable to atomic types.
00806   template<typename _ITp>
00807     inline bool
00808     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
00809     { return __a->is_lock_free(); }
00810 
00811   template<typename _ITp>
00812     inline bool
00813     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
00814     { return __a->is_lock_free(); }
00815 
00816   template<typename _ITp>
00817     inline void
00818     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
00819     { __a->store(__i, memory_order_relaxed); }
00820 
00821   template<typename _ITp>
00822     inline void
00823     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00824     { __a->store(__i, memory_order_relaxed); }
00825 
00826   template<typename _ITp>
00827     inline void
00828     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
00829               memory_order __m) noexcept
00830     { __a->store(__i, __m); }
00831 
00832   template<typename _ITp>
00833     inline void
00834     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00835               memory_order __m) noexcept
00836     { __a->store(__i, __m); }
00837 
00838   template<typename _ITp>
00839     inline _ITp
00840     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
00841     { return __a->load(__m); }
00842 
00843   template<typename _ITp>
00844     inline _ITp
00845     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00846              memory_order __m) noexcept
00847     { return __a->load(__m); }
00848 
00849   template<typename _ITp>
00850     inline _ITp
00851     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00852                  memory_order __m) noexcept
00853     { return __a->exchange(__i, __m); }
00854 
00855   template<typename _ITp>
00856     inline _ITp
00857     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00858                  memory_order __m) noexcept
00859     { return __a->exchange(__i, __m); }
00860 
00861   template<typename _ITp>
00862     inline bool
00863     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00864                       _ITp* __i1, _ITp __i2,
00865                       memory_order __m1,
00866                       memory_order __m2) noexcept
00867     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00868 
00869   template<typename _ITp>
00870     inline bool
00871     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00872                       _ITp* __i1, _ITp __i2,
00873                       memory_order __m1,
00874                       memory_order __m2) noexcept
00875     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00876 
00877   template<typename _ITp>
00878     inline bool
00879     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
00880                         _ITp* __i1, _ITp __i2,
00881                         memory_order __m1,
00882                         memory_order __m2) noexcept
00883     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00884 
00885   template<typename _ITp>
00886     inline bool
00887     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
00888                         _ITp* __i1, _ITp __i2,
00889                         memory_order __m1,
00890                         memory_order __m2) noexcept
00891     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00892 
00893 
00894   template<typename _ITp>
00895     inline void
00896     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
00897     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00898 
00899   template<typename _ITp>
00900     inline void
00901     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00902     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00903 
00904   template<typename _ITp>
00905     inline _ITp
00906     atomic_load(const atomic<_ITp>* __a) noexcept
00907     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00908 
00909   template<typename _ITp>
00910     inline _ITp
00911     atomic_load(const volatile atomic<_ITp>* __a) noexcept
00912     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00913 
00914   template<typename _ITp>
00915     inline _ITp
00916     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
00917     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00918 
00919   template<typename _ITp>
00920     inline _ITp
00921     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00922     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00923 
00924   template<typename _ITp>
00925     inline bool
00926     atomic_compare_exchange_weak(atomic<_ITp>* __a,
00927                  _ITp* __i1, _ITp __i2) noexcept
00928     {
00929       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00930                            memory_order_seq_cst,
00931                            memory_order_seq_cst);
00932     }
00933 
00934   template<typename _ITp>
00935     inline bool
00936     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
00937                  _ITp* __i1, _ITp __i2) noexcept
00938     {
00939       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00940                            memory_order_seq_cst,
00941                            memory_order_seq_cst);
00942     }
00943 
00944   template<typename _ITp>
00945     inline bool
00946     atomic_compare_exchange_strong(atomic<_ITp>* __a,
00947                    _ITp* __i1, _ITp __i2) noexcept
00948     {
00949       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00950                              memory_order_seq_cst,
00951                              memory_order_seq_cst);
00952     }
00953 
00954   template<typename _ITp>
00955     inline bool
00956     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
00957                    _ITp* __i1, _ITp __i2) noexcept
00958     {
00959       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00960                              memory_order_seq_cst,
00961                              memory_order_seq_cst);
00962     }
00963 
00964   // Function templates for atomic_integral operations only, using
00965   // __atomic_base. Template argument should be constricted to
00966   // intergral types as specified in the standard, excluding address
00967   // types.
00968   template<typename _ITp>
00969     inline _ITp
00970     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00971                   memory_order __m) noexcept
00972     { return __a->fetch_add(__i, __m); }
00973 
00974   template<typename _ITp>
00975     inline _ITp
00976     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00977                   memory_order __m) noexcept
00978     { return __a->fetch_add(__i, __m); }
00979 
00980   template<typename _ITp>
00981     inline _ITp
00982     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00983                   memory_order __m) noexcept
00984     { return __a->fetch_sub(__i, __m); }
00985 
00986   template<typename _ITp>
00987     inline _ITp
00988     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00989                   memory_order __m) noexcept
00990     { return __a->fetch_sub(__i, __m); }
00991 
00992   template<typename _ITp>
00993     inline _ITp
00994     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00995                   memory_order __m) noexcept
00996     { return __a->fetch_and(__i, __m); }
00997 
00998   template<typename _ITp>
00999     inline _ITp
01000     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01001                   memory_order __m) noexcept
01002     { return __a->fetch_and(__i, __m); }
01003 
01004   template<typename _ITp>
01005     inline _ITp
01006     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01007                  memory_order __m) noexcept
01008     { return __a->fetch_or(__i, __m); }
01009 
01010   template<typename _ITp>
01011     inline _ITp
01012     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01013                  memory_order __m) noexcept
01014     { return __a->fetch_or(__i, __m); }
01015 
01016   template<typename _ITp>
01017     inline _ITp
01018     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01019                   memory_order __m) noexcept
01020     { return __a->fetch_xor(__i, __m); }
01021 
01022   template<typename _ITp>
01023     inline _ITp
01024     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01025                   memory_order __m) noexcept
01026     { return __a->fetch_xor(__i, __m); }
01027 
01028   template<typename _ITp>
01029     inline _ITp
01030     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01031     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01032 
01033   template<typename _ITp>
01034     inline _ITp
01035     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01036     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01037 
01038   template<typename _ITp>
01039     inline _ITp
01040     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01041     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01042 
01043   template<typename _ITp>
01044     inline _ITp
01045     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01046     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01047 
01048   template<typename _ITp>
01049     inline _ITp
01050     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01051     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01052 
01053   template<typename _ITp>
01054     inline _ITp
01055     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01056     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01057 
01058   template<typename _ITp>
01059     inline _ITp
01060     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01061     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01062 
01063   template<typename _ITp>
01064     inline _ITp
01065     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01066     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01067 
01068   template<typename _ITp>
01069     inline _ITp
01070     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01071     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01072 
01073   template<typename _ITp>
01074     inline _ITp
01075     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01076     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01077 
01078 
01079   // Partial specializations for pointers.
01080   template<typename _ITp>
01081     inline _ITp*
01082     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01083                   memory_order __m) noexcept
01084     { return __a->fetch_add(__d, __m); }
01085 
01086   template<typename _ITp>
01087     inline _ITp*
01088     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
01089                   memory_order __m) noexcept
01090     { return __a->fetch_add(__d, __m); }
01091 
01092   template<typename _ITp>
01093     inline _ITp*
01094     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01095     { return __a->fetch_add(__d); }
01096 
01097   template<typename _ITp>
01098     inline _ITp*
01099     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01100     { return __a->fetch_add(__d); }
01101 
01102   template<typename _ITp>
01103     inline _ITp*
01104     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01105                   ptrdiff_t __d, memory_order __m) noexcept
01106     { return __a->fetch_sub(__d, __m); }
01107 
01108   template<typename _ITp>
01109     inline _ITp*
01110     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01111                   memory_order __m) noexcept
01112     { return __a->fetch_sub(__d, __m); }
01113 
01114   template<typename _ITp>
01115     inline _ITp*
01116     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01117     { return __a->fetch_sub(__d); }
01118 
01119   template<typename _ITp>
01120     inline _ITp*
01121     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01122     { return __a->fetch_sub(__d); }
01123   // @} group atomics
01124 
01125 _GLIBCXX_END_NAMESPACE_VERSION
01126 } // namespace
01127 
01128 #endif