libstdc++
atomic
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008-2013 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, __m); }
00256 
00257       bool
00258       compare_exchange_weak(_Tp& __e, _Tp __i,
00259              memory_order __m = memory_order_seq_cst) volatile noexcept
00260       { return compare_exchange_weak(__e, __i, __m, __m); }
00261 
00262       bool
00263       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00264                   memory_order __f) noexcept
00265       {
00266     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00267       }
00268 
00269       bool
00270       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00271                   memory_order __f) volatile noexcept
00272       {
00273     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00274       }
00275 
00276       bool
00277       compare_exchange_strong(_Tp& __e, _Tp __i,
00278                    memory_order __m = memory_order_seq_cst) noexcept
00279       { return compare_exchange_strong(__e, __i, __m, __m); }
00280 
00281       bool
00282       compare_exchange_strong(_Tp& __e, _Tp __i,
00283              memory_order __m = memory_order_seq_cst) volatile noexcept
00284       { return compare_exchange_strong(__e, __i, __m, __m); }
00285     };
00286 
00287 
00288   /// Partial specialization for pointer types.
00289   template<typename _Tp>
00290     struct atomic<_Tp*>
00291     {
00292       typedef _Tp*          __pointer_type;
00293       typedef __atomic_base<_Tp*>   __base_type;
00294       __base_type           _M_b;
00295 
00296       atomic() noexcept = default;
00297       ~atomic() noexcept = default;
00298       atomic(const atomic&) = delete;
00299       atomic& operator=(const atomic&) = delete;
00300       atomic& operator=(const atomic&) volatile = delete;
00301 
00302       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
00303 
00304       operator __pointer_type() const noexcept
00305       { return __pointer_type(_M_b); }
00306 
00307       operator __pointer_type() const volatile noexcept
00308       { return __pointer_type(_M_b); }
00309 
00310       __pointer_type
00311       operator=(__pointer_type __p) noexcept
00312       { return _M_b.operator=(__p); }
00313 
00314       __pointer_type
00315       operator=(__pointer_type __p) volatile noexcept
00316       { return _M_b.operator=(__p); }
00317 
00318       __pointer_type
00319       operator++(int) noexcept
00320       { return _M_b++; }
00321 
00322       __pointer_type
00323       operator++(int) volatile noexcept
00324       { return _M_b++; }
00325 
00326       __pointer_type
00327       operator--(int) noexcept
00328       { return _M_b--; }
00329 
00330       __pointer_type
00331       operator--(int) volatile noexcept
00332       { return _M_b--; }
00333 
00334       __pointer_type
00335       operator++() noexcept
00336       { return ++_M_b; }
00337 
00338       __pointer_type
00339       operator++() volatile noexcept
00340       { return ++_M_b; }
00341 
00342       __pointer_type
00343       operator--() noexcept
00344       { return --_M_b; }
00345 
00346       __pointer_type
00347       operator--() volatile noexcept
00348       { return --_M_b; }
00349 
00350       __pointer_type
00351       operator+=(ptrdiff_t __d) noexcept
00352       { return _M_b.operator+=(__d); }
00353 
00354       __pointer_type
00355       operator+=(ptrdiff_t __d) volatile noexcept
00356       { return _M_b.operator+=(__d); }
00357 
00358       __pointer_type
00359       operator-=(ptrdiff_t __d) noexcept
00360       { return _M_b.operator-=(__d); }
00361 
00362       __pointer_type
00363       operator-=(ptrdiff_t __d) volatile noexcept
00364       { return _M_b.operator-=(__d); }
00365 
00366       bool
00367       is_lock_free() const noexcept
00368       { return _M_b.is_lock_free(); }
00369 
00370       bool
00371       is_lock_free() const volatile noexcept
00372       { return _M_b.is_lock_free(); }
00373 
00374       void
00375       store(__pointer_type __p,
00376         memory_order __m = memory_order_seq_cst) noexcept
00377       { return _M_b.store(__p, __m); }
00378 
00379       void
00380       store(__pointer_type __p,
00381         memory_order __m = memory_order_seq_cst) volatile noexcept
00382       { return _M_b.store(__p, __m); }
00383 
00384       __pointer_type
00385       load(memory_order __m = memory_order_seq_cst) const noexcept
00386       { return _M_b.load(__m); }
00387 
00388       __pointer_type
00389       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00390       { return _M_b.load(__m); }
00391 
00392       __pointer_type
00393       exchange(__pointer_type __p,
00394            memory_order __m = memory_order_seq_cst) noexcept
00395       { return _M_b.exchange(__p, __m); }
00396 
00397       __pointer_type
00398       exchange(__pointer_type __p,
00399            memory_order __m = memory_order_seq_cst) volatile noexcept
00400       { return _M_b.exchange(__p, __m); }
00401 
00402       bool
00403       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00404                 memory_order __m1, memory_order __m2) noexcept
00405       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00406 
00407       bool
00408       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00409                 memory_order __m1,
00410                 memory_order __m2) volatile noexcept
00411       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00412 
00413       bool
00414       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00415                 memory_order __m = memory_order_seq_cst) noexcept
00416       {
00417     return compare_exchange_weak(__p1, __p2, __m,
00418                      __cmpexch_failure_order(__m));
00419       }
00420 
00421       bool
00422       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00423             memory_order __m = memory_order_seq_cst) volatile noexcept
00424       {
00425     return compare_exchange_weak(__p1, __p2, __m,
00426                      __cmpexch_failure_order(__m));
00427       }
00428 
00429       bool
00430       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00431                   memory_order __m1, memory_order __m2) noexcept
00432       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00433 
00434       bool
00435       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00436                   memory_order __m1,
00437                   memory_order __m2) volatile noexcept
00438       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00439 
00440       bool
00441       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00442                   memory_order __m = memory_order_seq_cst) noexcept
00443       {
00444     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00445                         __cmpexch_failure_order(__m));
00446       }
00447 
00448       bool
00449       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00450             memory_order __m = memory_order_seq_cst) volatile noexcept
00451       {
00452     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00453                         __cmpexch_failure_order(__m));
00454       }
00455 
00456       __pointer_type
00457       fetch_add(ptrdiff_t __d,
00458         memory_order __m = memory_order_seq_cst) noexcept
00459       { return _M_b.fetch_add(__d, __m); }
00460 
00461       __pointer_type
00462       fetch_add(ptrdiff_t __d,
00463         memory_order __m = memory_order_seq_cst) volatile noexcept
00464       { return _M_b.fetch_add(__d, __m); }
00465 
00466       __pointer_type
00467       fetch_sub(ptrdiff_t __d,
00468         memory_order __m = memory_order_seq_cst) noexcept
00469       { return _M_b.fetch_sub(__d, __m); }
00470 
00471       __pointer_type
00472       fetch_sub(ptrdiff_t __d,
00473         memory_order __m = memory_order_seq_cst) volatile noexcept
00474       { return _M_b.fetch_sub(__d, __m); }
00475     };
00476 
00477 
00478   /// Explicit specialization for bool.
00479   template<>
00480     struct atomic<bool> : public atomic_bool
00481     {
00482       typedef bool          __integral_type;
00483       typedef atomic_bool       __base_type;
00484 
00485       atomic() noexcept = default;
00486       ~atomic() noexcept = default;
00487       atomic(const atomic&) = delete;
00488       atomic& operator=(const atomic&) = delete;
00489       atomic& operator=(const atomic&) volatile = delete;
00490 
00491       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00492 
00493       using __base_type::operator __integral_type;
00494       using __base_type::operator=;
00495     };
00496 
00497   /// Explicit specialization for char.
00498   template<>
00499     struct atomic<char> : public atomic_char
00500     {
00501       typedef char          __integral_type;
00502       typedef atomic_char       __base_type;
00503 
00504       atomic() noexcept = default;
00505       ~atomic() noexcept = default;
00506       atomic(const atomic&) = delete;
00507       atomic& operator=(const atomic&) = delete;
00508       atomic& operator=(const atomic&) volatile = delete;
00509 
00510       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00511 
00512       using __base_type::operator __integral_type;
00513       using __base_type::operator=;
00514     };
00515 
00516   /// Explicit specialization for signed char.
00517   template<>
00518     struct atomic<signed char> : public atomic_schar
00519     {
00520       typedef signed char       __integral_type;
00521       typedef atomic_schar      __base_type;
00522 
00523       atomic() noexcept= default;
00524       ~atomic() noexcept = default;
00525       atomic(const atomic&) = delete;
00526       atomic& operator=(const atomic&) = delete;
00527       atomic& operator=(const atomic&) volatile = delete;
00528 
00529       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00530 
00531       using __base_type::operator __integral_type;
00532       using __base_type::operator=;
00533     };
00534 
00535   /// Explicit specialization for unsigned char.
00536   template<>
00537     struct atomic<unsigned char> : public atomic_uchar
00538     {
00539       typedef unsigned char         __integral_type;
00540       typedef atomic_uchar      __base_type;
00541 
00542       atomic() noexcept= default;
00543       ~atomic() noexcept = default;
00544       atomic(const atomic&) = delete;
00545       atomic& operator=(const atomic&) = delete;
00546       atomic& operator=(const atomic&) volatile = delete;
00547 
00548       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00549 
00550       using __base_type::operator __integral_type;
00551       using __base_type::operator=;
00552     };
00553 
00554   /// Explicit specialization for short.
00555   template<>
00556     struct atomic<short> : public atomic_short
00557     {
00558       typedef short             __integral_type;
00559       typedef atomic_short      __base_type;
00560 
00561       atomic() noexcept = default;
00562       ~atomic() noexcept = default;
00563       atomic(const atomic&) = delete;
00564       atomic& operator=(const atomic&) = delete;
00565       atomic& operator=(const atomic&) volatile = delete;
00566 
00567       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00568 
00569       using __base_type::operator __integral_type;
00570       using __base_type::operator=;
00571     };
00572 
00573   /// Explicit specialization for unsigned short.
00574   template<>
00575     struct atomic<unsigned short> : public atomic_ushort
00576     {
00577       typedef unsigned short            __integral_type;
00578       typedef atomic_ushort         __base_type;
00579 
00580       atomic() noexcept = default;
00581       ~atomic() noexcept = default;
00582       atomic(const atomic&) = delete;
00583       atomic& operator=(const atomic&) = delete;
00584       atomic& operator=(const atomic&) volatile = delete;
00585 
00586       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00587 
00588       using __base_type::operator __integral_type;
00589       using __base_type::operator=;
00590     };
00591 
00592   /// Explicit specialization for int.
00593   template<>
00594     struct atomic<int> : atomic_int
00595     {
00596       typedef int           __integral_type;
00597       typedef atomic_int        __base_type;
00598 
00599       atomic() noexcept = default;
00600       ~atomic() noexcept = default;
00601       atomic(const atomic&) = delete;
00602       atomic& operator=(const atomic&) = delete;
00603       atomic& operator=(const atomic&) volatile = delete;
00604 
00605       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00606 
00607       using __base_type::operator __integral_type;
00608       using __base_type::operator=;
00609     };
00610 
00611   /// Explicit specialization for unsigned int.
00612   template<>
00613     struct atomic<unsigned int> : public atomic_uint
00614     {
00615       typedef unsigned int      __integral_type;
00616       typedef atomic_uint       __base_type;
00617 
00618       atomic() noexcept = default;
00619       ~atomic() noexcept = default;
00620       atomic(const atomic&) = delete;
00621       atomic& operator=(const atomic&) = delete;
00622       atomic& operator=(const atomic&) volatile = delete;
00623 
00624       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00625 
00626       using __base_type::operator __integral_type;
00627       using __base_type::operator=;
00628     };
00629 
00630   /// Explicit specialization for long.
00631   template<>
00632     struct atomic<long> : public atomic_long
00633     {
00634       typedef long          __integral_type;
00635       typedef atomic_long       __base_type;
00636 
00637       atomic() noexcept = default;
00638       ~atomic() noexcept = default;
00639       atomic(const atomic&) = delete;
00640       atomic& operator=(const atomic&) = delete;
00641       atomic& operator=(const atomic&) volatile = delete;
00642 
00643       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00644 
00645       using __base_type::operator __integral_type;
00646       using __base_type::operator=;
00647     };
00648 
00649   /// Explicit specialization for unsigned long.
00650   template<>
00651     struct atomic<unsigned long> : public atomic_ulong
00652     {
00653       typedef unsigned long         __integral_type;
00654       typedef atomic_ulong      __base_type;
00655 
00656       atomic() noexcept = default;
00657       ~atomic() noexcept = default;
00658       atomic(const atomic&) = delete;
00659       atomic& operator=(const atomic&) = delete;
00660       atomic& operator=(const atomic&) volatile = delete;
00661 
00662       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00663 
00664       using __base_type::operator __integral_type;
00665       using __base_type::operator=;
00666     };
00667 
00668   /// Explicit specialization for long long.
00669   template<>
00670     struct atomic<long long> : public atomic_llong
00671     {
00672       typedef long long         __integral_type;
00673       typedef atomic_llong      __base_type;
00674 
00675       atomic() noexcept = default;
00676       ~atomic() noexcept = default;
00677       atomic(const atomic&) = delete;
00678       atomic& operator=(const atomic&) = delete;
00679       atomic& operator=(const atomic&) volatile = delete;
00680 
00681       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00682 
00683       using __base_type::operator __integral_type;
00684       using __base_type::operator=;
00685     };
00686 
00687   /// Explicit specialization for unsigned long long.
00688   template<>
00689     struct atomic<unsigned long long> : public atomic_ullong
00690     {
00691       typedef unsigned long long        __integral_type;
00692       typedef atomic_ullong         __base_type;
00693 
00694       atomic() noexcept = default;
00695       ~atomic() noexcept = default;
00696       atomic(const atomic&) = delete;
00697       atomic& operator=(const atomic&) = delete;
00698       atomic& operator=(const atomic&) volatile = delete;
00699 
00700       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00701 
00702       using __base_type::operator __integral_type;
00703       using __base_type::operator=;
00704     };
00705 
00706   /// Explicit specialization for wchar_t.
00707   template<>
00708     struct atomic<wchar_t> : public atomic_wchar_t
00709     {
00710       typedef wchar_t           __integral_type;
00711       typedef atomic_wchar_t        __base_type;
00712 
00713       atomic() noexcept = default;
00714       ~atomic() noexcept = default;
00715       atomic(const atomic&) = delete;
00716       atomic& operator=(const atomic&) = delete;
00717       atomic& operator=(const atomic&) volatile = delete;
00718 
00719       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00720 
00721       using __base_type::operator __integral_type;
00722       using __base_type::operator=;
00723     };
00724 
00725   /// Explicit specialization for char16_t.
00726   template<>
00727     struct atomic<char16_t> : public atomic_char16_t
00728     {
00729       typedef char16_t          __integral_type;
00730       typedef atomic_char16_t       __base_type;
00731 
00732       atomic() noexcept = default;
00733       ~atomic() noexcept = default;
00734       atomic(const atomic&) = delete;
00735       atomic& operator=(const atomic&) = delete;
00736       atomic& operator=(const atomic&) volatile = delete;
00737 
00738       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00739 
00740       using __base_type::operator __integral_type;
00741       using __base_type::operator=;
00742     };
00743 
00744   /// Explicit specialization for char32_t.
00745   template<>
00746     struct atomic<char32_t> : public atomic_char32_t
00747     {
00748       typedef char32_t          __integral_type;
00749       typedef atomic_char32_t       __base_type;
00750 
00751       atomic() noexcept = default;
00752       ~atomic() noexcept = default;
00753       atomic(const atomic&) = delete;
00754       atomic& operator=(const atomic&) = delete;
00755       atomic& operator=(const atomic&) volatile = delete;
00756 
00757       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00758 
00759       using __base_type::operator __integral_type;
00760       using __base_type::operator=;
00761     };
00762 
00763 
00764   // Function definitions, atomic_flag operations.
00765   inline bool
00766   atomic_flag_test_and_set_explicit(atomic_flag* __a,
00767                     memory_order __m) noexcept
00768   { return __a->test_and_set(__m); }
00769 
00770   inline bool
00771   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
00772                     memory_order __m) noexcept
00773   { return __a->test_and_set(__m); }
00774 
00775   inline void
00776   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
00777   { __a->clear(__m); }
00778 
00779   inline void
00780   atomic_flag_clear_explicit(volatile atomic_flag* __a,
00781                  memory_order __m) noexcept
00782   { __a->clear(__m); }
00783 
00784   inline bool
00785   atomic_flag_test_and_set(atomic_flag* __a) noexcept
00786   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00787 
00788   inline bool
00789   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
00790   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00791 
00792   inline void
00793   atomic_flag_clear(atomic_flag* __a) noexcept
00794   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00795 
00796   inline void
00797   atomic_flag_clear(volatile atomic_flag* __a) noexcept
00798   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00799 
00800 
00801   // Function templates generally applicable to atomic types.
00802   template<typename _ITp>
00803     inline bool
00804     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
00805     { return __a->is_lock_free(); }
00806 
00807   template<typename _ITp>
00808     inline bool
00809     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
00810     { return __a->is_lock_free(); }
00811 
00812   template<typename _ITp>
00813     inline void
00814     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
00815 
00816   template<typename _ITp>
00817     inline void
00818     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
00819 
00820   template<typename _ITp>
00821     inline void
00822     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
00823               memory_order __m) noexcept
00824     { __a->store(__i, __m); }
00825 
00826   template<typename _ITp>
00827     inline void
00828     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00829               memory_order __m) noexcept
00830     { __a->store(__i, __m); }
00831 
00832   template<typename _ITp>
00833     inline _ITp
00834     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
00835     { return __a->load(__m); }
00836 
00837   template<typename _ITp>
00838     inline _ITp
00839     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00840              memory_order __m) noexcept
00841     { return __a->load(__m); }
00842 
00843   template<typename _ITp>
00844     inline _ITp
00845     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00846                  memory_order __m) noexcept
00847     { return __a->exchange(__i, __m); }
00848 
00849   template<typename _ITp>
00850     inline _ITp
00851     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00852                  memory_order __m) noexcept
00853     { return __a->exchange(__i, __m); }
00854 
00855   template<typename _ITp>
00856     inline bool
00857     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00858                       _ITp* __i1, _ITp __i2,
00859                       memory_order __m1,
00860                       memory_order __m2) noexcept
00861     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00862 
00863   template<typename _ITp>
00864     inline bool
00865     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00866                       _ITp* __i1, _ITp __i2,
00867                       memory_order __m1,
00868                       memory_order __m2) noexcept
00869     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00870 
00871   template<typename _ITp>
00872     inline bool
00873     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
00874                         _ITp* __i1, _ITp __i2,
00875                         memory_order __m1,
00876                         memory_order __m2) noexcept
00877     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00878 
00879   template<typename _ITp>
00880     inline bool
00881     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
00882                         _ITp* __i1, _ITp __i2,
00883                         memory_order __m1,
00884                         memory_order __m2) noexcept
00885     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00886 
00887 
00888   template<typename _ITp>
00889     inline void
00890     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
00891     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00892 
00893   template<typename _ITp>
00894     inline void
00895     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00896     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00897 
00898   template<typename _ITp>
00899     inline _ITp
00900     atomic_load(const atomic<_ITp>* __a) noexcept
00901     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00902 
00903   template<typename _ITp>
00904     inline _ITp
00905     atomic_load(const volatile atomic<_ITp>* __a) noexcept
00906     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00907 
00908   template<typename _ITp>
00909     inline _ITp
00910     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
00911     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00912 
00913   template<typename _ITp>
00914     inline _ITp
00915     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00916     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00917 
00918   template<typename _ITp>
00919     inline bool
00920     atomic_compare_exchange_weak(atomic<_ITp>* __a,
00921                  _ITp* __i1, _ITp __i2) noexcept
00922     {
00923       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00924                            memory_order_seq_cst,
00925                            memory_order_seq_cst);
00926     }
00927 
00928   template<typename _ITp>
00929     inline bool
00930     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
00931                  _ITp* __i1, _ITp __i2) noexcept
00932     {
00933       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00934                            memory_order_seq_cst,
00935                            memory_order_seq_cst);
00936     }
00937 
00938   template<typename _ITp>
00939     inline bool
00940     atomic_compare_exchange_strong(atomic<_ITp>* __a,
00941                    _ITp* __i1, _ITp __i2) noexcept
00942     {
00943       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00944                              memory_order_seq_cst,
00945                              memory_order_seq_cst);
00946     }
00947 
00948   template<typename _ITp>
00949     inline bool
00950     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
00951                    _ITp* __i1, _ITp __i2) noexcept
00952     {
00953       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00954                              memory_order_seq_cst,
00955                              memory_order_seq_cst);
00956     }
00957 
00958   // Function templates for atomic_integral operations only, using
00959   // __atomic_base. Template argument should be constricted to
00960   // intergral types as specified in the standard, excluding address
00961   // types.
00962   template<typename _ITp>
00963     inline _ITp
00964     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00965                   memory_order __m) noexcept
00966     { return __a->fetch_add(__i, __m); }
00967 
00968   template<typename _ITp>
00969     inline _ITp
00970     atomic_fetch_add_explicit(volatile __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_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00977                   memory_order __m) noexcept
00978     { return __a->fetch_sub(__i, __m); }
00979 
00980   template<typename _ITp>
00981     inline _ITp
00982     atomic_fetch_sub_explicit(volatile __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_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00989                   memory_order __m) noexcept
00990     { return __a->fetch_and(__i, __m); }
00991 
00992   template<typename _ITp>
00993     inline _ITp
00994     atomic_fetch_and_explicit(volatile __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_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01001                  memory_order __m) noexcept
01002     { return __a->fetch_or(__i, __m); }
01003 
01004   template<typename _ITp>
01005     inline _ITp
01006     atomic_fetch_or_explicit(volatile __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_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01013                   memory_order __m) noexcept
01014     { return __a->fetch_xor(__i, __m); }
01015 
01016   template<typename _ITp>
01017     inline _ITp
01018     atomic_fetch_xor_explicit(volatile __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_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01025     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01026 
01027   template<typename _ITp>
01028     inline _ITp
01029     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01030     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01031 
01032   template<typename _ITp>
01033     inline _ITp
01034     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01035     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01036 
01037   template<typename _ITp>
01038     inline _ITp
01039     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01040     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01041 
01042   template<typename _ITp>
01043     inline _ITp
01044     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01045     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01046 
01047   template<typename _ITp>
01048     inline _ITp
01049     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01050     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01051 
01052   template<typename _ITp>
01053     inline _ITp
01054     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01055     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01056 
01057   template<typename _ITp>
01058     inline _ITp
01059     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01060     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01061 
01062   template<typename _ITp>
01063     inline _ITp
01064     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01065     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01066 
01067   template<typename _ITp>
01068     inline _ITp
01069     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01070     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01071 
01072 
01073   // Partial specializations for pointers.
01074   template<typename _ITp>
01075     inline _ITp*
01076     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01077                   memory_order __m) noexcept
01078     { return __a->fetch_add(__d, __m); }
01079 
01080   template<typename _ITp>
01081     inline _ITp*
01082     atomic_fetch_add_explicit(volatile 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(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01089     { return __a->fetch_add(__d); }
01090 
01091   template<typename _ITp>
01092     inline _ITp*
01093     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01094     { return __a->fetch_add(__d); }
01095 
01096   template<typename _ITp>
01097     inline _ITp*
01098     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01099                   ptrdiff_t __d, memory_order __m) noexcept
01100     { return __a->fetch_sub(__d, __m); }
01101 
01102   template<typename _ITp>
01103     inline _ITp*
01104     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01105                   memory_order __m) noexcept
01106     { return __a->fetch_sub(__d, __m); }
01107 
01108   template<typename _ITp>
01109     inline _ITp*
01110     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01111     { return __a->fetch_sub(__d); }
01112 
01113   template<typename _ITp>
01114     inline _ITp*
01115     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01116     { return __a->fetch_sub(__d); }
01117   // @} group atomics
01118 
01119 _GLIBCXX_END_NAMESPACE_VERSION
01120 } // namespace
01121 
01122 #endif