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 
00820   template<typename _ITp>
00821     inline void
00822     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
00823 
00824   template<typename _ITp>
00825     inline void
00826     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
00827               memory_order __m) noexcept
00828     { __a->store(__i, __m); }
00829 
00830   template<typename _ITp>
00831     inline void
00832     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00833               memory_order __m) noexcept
00834     { __a->store(__i, __m); }
00835 
00836   template<typename _ITp>
00837     inline _ITp
00838     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
00839     { return __a->load(__m); }
00840 
00841   template<typename _ITp>
00842     inline _ITp
00843     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00844              memory_order __m) noexcept
00845     { return __a->load(__m); }
00846 
00847   template<typename _ITp>
00848     inline _ITp
00849     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00850                  memory_order __m) noexcept
00851     { return __a->exchange(__i, __m); }
00852 
00853   template<typename _ITp>
00854     inline _ITp
00855     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00856                  memory_order __m) noexcept
00857     { return __a->exchange(__i, __m); }
00858 
00859   template<typename _ITp>
00860     inline bool
00861     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00862                       _ITp* __i1, _ITp __i2,
00863                       memory_order __m1,
00864                       memory_order __m2) noexcept
00865     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00866 
00867   template<typename _ITp>
00868     inline bool
00869     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00870                       _ITp* __i1, _ITp __i2,
00871                       memory_order __m1,
00872                       memory_order __m2) noexcept
00873     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00874 
00875   template<typename _ITp>
00876     inline bool
00877     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
00878                         _ITp* __i1, _ITp __i2,
00879                         memory_order __m1,
00880                         memory_order __m2) noexcept
00881     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00882 
00883   template<typename _ITp>
00884     inline bool
00885     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
00886                         _ITp* __i1, _ITp __i2,
00887                         memory_order __m1,
00888                         memory_order __m2) noexcept
00889     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00890 
00891 
00892   template<typename _ITp>
00893     inline void
00894     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
00895     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00896 
00897   template<typename _ITp>
00898     inline void
00899     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00900     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00901 
00902   template<typename _ITp>
00903     inline _ITp
00904     atomic_load(const atomic<_ITp>* __a) noexcept
00905     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00906 
00907   template<typename _ITp>
00908     inline _ITp
00909     atomic_load(const volatile atomic<_ITp>* __a) noexcept
00910     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00911 
00912   template<typename _ITp>
00913     inline _ITp
00914     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
00915     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00916 
00917   template<typename _ITp>
00918     inline _ITp
00919     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00920     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00921 
00922   template<typename _ITp>
00923     inline bool
00924     atomic_compare_exchange_weak(atomic<_ITp>* __a,
00925                  _ITp* __i1, _ITp __i2) noexcept
00926     {
00927       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00928                            memory_order_seq_cst,
00929                            memory_order_seq_cst);
00930     }
00931 
00932   template<typename _ITp>
00933     inline bool
00934     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
00935                  _ITp* __i1, _ITp __i2) noexcept
00936     {
00937       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00938                            memory_order_seq_cst,
00939                            memory_order_seq_cst);
00940     }
00941 
00942   template<typename _ITp>
00943     inline bool
00944     atomic_compare_exchange_strong(atomic<_ITp>* __a,
00945                    _ITp* __i1, _ITp __i2) noexcept
00946     {
00947       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00948                              memory_order_seq_cst,
00949                              memory_order_seq_cst);
00950     }
00951 
00952   template<typename _ITp>
00953     inline bool
00954     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
00955                    _ITp* __i1, _ITp __i2) noexcept
00956     {
00957       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00958                              memory_order_seq_cst,
00959                              memory_order_seq_cst);
00960     }
00961 
00962   // Function templates for atomic_integral operations only, using
00963   // __atomic_base. Template argument should be constricted to
00964   // intergral types as specified in the standard, excluding address
00965   // types.
00966   template<typename _ITp>
00967     inline _ITp
00968     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00969                   memory_order __m) noexcept
00970     { return __a->fetch_add(__i, __m); }
00971 
00972   template<typename _ITp>
00973     inline _ITp
00974     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00975                   memory_order __m) noexcept
00976     { return __a->fetch_add(__i, __m); }
00977 
00978   template<typename _ITp>
00979     inline _ITp
00980     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00981                   memory_order __m) noexcept
00982     { return __a->fetch_sub(__i, __m); }
00983 
00984   template<typename _ITp>
00985     inline _ITp
00986     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00987                   memory_order __m) noexcept
00988     { return __a->fetch_sub(__i, __m); }
00989 
00990   template<typename _ITp>
00991     inline _ITp
00992     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00993                   memory_order __m) noexcept
00994     { return __a->fetch_and(__i, __m); }
00995 
00996   template<typename _ITp>
00997     inline _ITp
00998     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00999                   memory_order __m) noexcept
01000     { return __a->fetch_and(__i, __m); }
01001 
01002   template<typename _ITp>
01003     inline _ITp
01004     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01005                  memory_order __m) noexcept
01006     { return __a->fetch_or(__i, __m); }
01007 
01008   template<typename _ITp>
01009     inline _ITp
01010     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01011                  memory_order __m) noexcept
01012     { return __a->fetch_or(__i, __m); }
01013 
01014   template<typename _ITp>
01015     inline _ITp
01016     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01017                   memory_order __m) noexcept
01018     { return __a->fetch_xor(__i, __m); }
01019 
01020   template<typename _ITp>
01021     inline _ITp
01022     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01023                   memory_order __m) noexcept
01024     { return __a->fetch_xor(__i, __m); }
01025 
01026   template<typename _ITp>
01027     inline _ITp
01028     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01029     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01030 
01031   template<typename _ITp>
01032     inline _ITp
01033     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01034     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01035 
01036   template<typename _ITp>
01037     inline _ITp
01038     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01039     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01040 
01041   template<typename _ITp>
01042     inline _ITp
01043     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01044     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01045 
01046   template<typename _ITp>
01047     inline _ITp
01048     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01049     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01050 
01051   template<typename _ITp>
01052     inline _ITp
01053     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01054     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01055 
01056   template<typename _ITp>
01057     inline _ITp
01058     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01059     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01060 
01061   template<typename _ITp>
01062     inline _ITp
01063     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01064     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01065 
01066   template<typename _ITp>
01067     inline _ITp
01068     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01069     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01070 
01071   template<typename _ITp>
01072     inline _ITp
01073     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01074     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01075 
01076 
01077   // Partial specializations for pointers.
01078   template<typename _ITp>
01079     inline _ITp*
01080     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01081                   memory_order __m) noexcept
01082     { return __a->fetch_add(__d, __m); }
01083 
01084   template<typename _ITp>
01085     inline _ITp*
01086     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
01087                   memory_order __m) noexcept
01088     { return __a->fetch_add(__d, __m); }
01089 
01090   template<typename _ITp>
01091     inline _ITp*
01092     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01093     { return __a->fetch_add(__d); }
01094 
01095   template<typename _ITp>
01096     inline _ITp*
01097     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01098     { return __a->fetch_add(__d); }
01099 
01100   template<typename _ITp>
01101     inline _ITp*
01102     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01103                   ptrdiff_t __d, memory_order __m) noexcept
01104     { return __a->fetch_sub(__d, __m); }
01105 
01106   template<typename _ITp>
01107     inline _ITp*
01108     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01109                   memory_order __m) noexcept
01110     { return __a->fetch_sub(__d, __m); }
01111 
01112   template<typename _ITp>
01113     inline _ITp*
01114     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01115     { return __a->fetch_sub(__d); }
01116 
01117   template<typename _ITp>
01118     inline _ITp*
01119     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01120     { return __a->fetch_sub(__d); }
01121   // @} group atomics
01122 
01123 _GLIBCXX_END_NAMESPACE_VERSION
01124 } // namespace
01125 
01126 #endif