libstdc++
atomic
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008-2015 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 #else
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   template<typename _Tp>
00053     struct atomic;
00054 
00055   /// atomic<bool>
00056   // NB: No operators or fetch-operations for this type.
00057   template<>
00058   struct atomic<bool>
00059   {
00060   private:
00061     __atomic_base<bool> _M_base;
00062 
00063   public:
00064     atomic() noexcept = default;
00065     ~atomic() noexcept = default;
00066     atomic(const atomic&) = delete;
00067     atomic& operator=(const atomic&) = delete;
00068     atomic& operator=(const atomic&) volatile = delete;
00069 
00070     constexpr atomic(bool __i) noexcept : _M_base(__i) { }
00071 
00072     bool
00073     operator=(bool __i) noexcept
00074     { return _M_base.operator=(__i); }
00075 
00076     bool
00077     operator=(bool __i) volatile noexcept
00078     { return _M_base.operator=(__i); }
00079 
00080     operator bool() const noexcept
00081     { return _M_base.load(); }
00082 
00083     operator bool() const volatile noexcept
00084     { return _M_base.load(); }
00085 
00086     bool
00087     is_lock_free() const noexcept { return _M_base.is_lock_free(); }
00088 
00089     bool
00090     is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
00091 
00092     void
00093     store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
00094     { _M_base.store(__i, __m); }
00095 
00096     void
00097     store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
00098     { _M_base.store(__i, __m); }
00099 
00100     bool
00101     load(memory_order __m = memory_order_seq_cst) const noexcept
00102     { return _M_base.load(__m); }
00103 
00104     bool
00105     load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00106     { return _M_base.load(__m); }
00107 
00108     bool
00109     exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
00110     { return _M_base.exchange(__i, __m); }
00111 
00112     bool
00113     exchange(bool __i,
00114              memory_order __m = memory_order_seq_cst) volatile noexcept
00115     { return _M_base.exchange(__i, __m); }
00116 
00117     bool
00118     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00119                           memory_order __m2) noexcept
00120     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00121 
00122     bool
00123     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00124                           memory_order __m2) volatile noexcept
00125     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00126 
00127     bool
00128     compare_exchange_weak(bool& __i1, bool __i2,
00129                           memory_order __m = memory_order_seq_cst) noexcept
00130     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00131 
00132     bool
00133     compare_exchange_weak(bool& __i1, bool __i2,
00134                      memory_order __m = memory_order_seq_cst) volatile noexcept
00135     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00136 
00137     bool
00138     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00139                             memory_order __m2) noexcept
00140     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00141 
00142     bool
00143     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00144                             memory_order __m2) volatile noexcept
00145     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00146 
00147     bool
00148     compare_exchange_strong(bool& __i1, bool __i2,
00149                             memory_order __m = memory_order_seq_cst) noexcept
00150     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00151 
00152     bool
00153     compare_exchange_strong(bool& __i1, bool __i2,
00154                     memory_order __m = memory_order_seq_cst) volatile noexcept
00155     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00156   };
00157 
00158 
00159   /**
00160    *  @brief Generic atomic type, primary class template.
00161    *
00162    *  @tparam _Tp  Type to be made atomic, must be trivally copyable.
00163    */
00164   template<typename _Tp>
00165     struct atomic
00166     {
00167     private:
00168       // Align 1/2/4/8/16-byte types to at least their size.
00169       static constexpr int _S_min_alignment
00170         = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
00171         ? 0 : sizeof(_Tp);
00172 
00173       static constexpr int _S_alignment
00174         = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
00175 
00176       alignas(_S_alignment) _Tp _M_i;
00177 
00178       static_assert(__is_trivially_copyable(_Tp),
00179                     "std::atomic requires a trivially copyable type");
00180 
00181       static_assert(sizeof(_Tp) > 0,
00182                     "Incomplete or zero-sized types are not supported");
00183 
00184     public:
00185       atomic() noexcept = default;
00186       ~atomic() noexcept = default;
00187       atomic(const atomic&) = delete;
00188       atomic& operator=(const atomic&) = delete;
00189       atomic& operator=(const atomic&) volatile = delete;
00190 
00191       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
00192 
00193       operator _Tp() const noexcept
00194       { return load(); }
00195 
00196       operator _Tp() const volatile noexcept
00197       { return load(); }
00198 
00199       _Tp
00200       operator=(_Tp __i) noexcept 
00201       { store(__i); return __i; }
00202 
00203       _Tp
00204       operator=(_Tp __i) volatile noexcept 
00205       { store(__i); return __i; }
00206 
00207       bool
00208       is_lock_free() const noexcept
00209       {
00210         // Produce a fake, minimally aligned pointer.
00211         return __atomic_is_lock_free(sizeof(_M_i),
00212             reinterpret_cast<void *>(-__alignof(_M_i)));
00213       }
00214 
00215       bool
00216       is_lock_free() const volatile noexcept
00217       {
00218         // Produce a fake, minimally aligned pointer.
00219         return __atomic_is_lock_free(sizeof(_M_i),
00220             reinterpret_cast<void *>(-__alignof(_M_i)));
00221       }
00222 
00223       void
00224       store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
00225       { __atomic_store(&_M_i, &__i, __m); }
00226 
00227       void
00228       store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
00229       { __atomic_store(&_M_i, &__i, __m); }
00230 
00231       _Tp
00232       load(memory_order __m = memory_order_seq_cst) const noexcept
00233       { 
00234         _Tp tmp;
00235         __atomic_load(&_M_i, &tmp, __m);
00236         return tmp;
00237       }
00238 
00239       _Tp
00240       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00241       { 
00242         _Tp tmp;
00243         __atomic_load(&_M_i, &tmp, __m);
00244         return tmp;
00245       }
00246 
00247       _Tp
00248       exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
00249       { 
00250         _Tp tmp;
00251         __atomic_exchange(&_M_i, &__i, &tmp, __m);
00252         return tmp;
00253       }
00254 
00255       _Tp
00256       exchange(_Tp __i, 
00257                memory_order __m = memory_order_seq_cst) volatile noexcept
00258       { 
00259         _Tp tmp;
00260         __atomic_exchange(&_M_i, &__i, &tmp, __m);
00261         return tmp;
00262       }
00263 
00264       bool
00265       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00266                             memory_order __f) noexcept
00267       {
00268         return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
00269       }
00270 
00271       bool
00272       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00273                             memory_order __f) volatile noexcept
00274       {
00275         return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
00276       }
00277 
00278       bool
00279       compare_exchange_weak(_Tp& __e, _Tp __i,
00280                             memory_order __m = memory_order_seq_cst) noexcept
00281       { return compare_exchange_weak(__e, __i, __m,
00282                                      __cmpexch_failure_order(__m)); }
00283 
00284       bool
00285       compare_exchange_weak(_Tp& __e, _Tp __i,
00286                      memory_order __m = memory_order_seq_cst) volatile noexcept
00287       { return compare_exchange_weak(__e, __i, __m,
00288                                      __cmpexch_failure_order(__m)); }
00289 
00290       bool
00291       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00292                               memory_order __f) noexcept
00293       {
00294         return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
00295       }
00296 
00297       bool
00298       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00299                               memory_order __f) volatile noexcept
00300       {
00301         return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
00302       }
00303 
00304       bool
00305       compare_exchange_strong(_Tp& __e, _Tp __i,
00306                                memory_order __m = memory_order_seq_cst) noexcept
00307       { return compare_exchange_strong(__e, __i, __m,
00308                                        __cmpexch_failure_order(__m)); }
00309 
00310       bool
00311       compare_exchange_strong(_Tp& __e, _Tp __i,
00312                      memory_order __m = memory_order_seq_cst) volatile noexcept
00313       { return compare_exchange_strong(__e, __i, __m,
00314                                        __cmpexch_failure_order(__m)); }
00315     };
00316 
00317 
00318   /// Partial specialization for pointer types.
00319   template<typename _Tp>
00320     struct atomic<_Tp*>
00321     {
00322       typedef _Tp*                      __pointer_type;
00323       typedef __atomic_base<_Tp*>       __base_type;
00324       __base_type                       _M_b;
00325 
00326       atomic() noexcept = default;
00327       ~atomic() noexcept = default;
00328       atomic(const atomic&) = delete;
00329       atomic& operator=(const atomic&) = delete;
00330       atomic& operator=(const atomic&) volatile = delete;
00331 
00332       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
00333 
00334       operator __pointer_type() const noexcept
00335       { return __pointer_type(_M_b); }
00336 
00337       operator __pointer_type() const volatile noexcept
00338       { return __pointer_type(_M_b); }
00339 
00340       __pointer_type
00341       operator=(__pointer_type __p) noexcept
00342       { return _M_b.operator=(__p); }
00343 
00344       __pointer_type
00345       operator=(__pointer_type __p) volatile noexcept
00346       { return _M_b.operator=(__p); }
00347 
00348       __pointer_type
00349       operator++(int) noexcept
00350       { return _M_b++; }
00351 
00352       __pointer_type
00353       operator++(int) volatile noexcept
00354       { return _M_b++; }
00355 
00356       __pointer_type
00357       operator--(int) noexcept
00358       { return _M_b--; }
00359 
00360       __pointer_type
00361       operator--(int) volatile noexcept
00362       { return _M_b--; }
00363 
00364       __pointer_type
00365       operator++() noexcept
00366       { return ++_M_b; }
00367 
00368       __pointer_type
00369       operator++() volatile noexcept
00370       { return ++_M_b; }
00371 
00372       __pointer_type
00373       operator--() noexcept
00374       { return --_M_b; }
00375 
00376       __pointer_type
00377       operator--() volatile noexcept
00378       { return --_M_b; }
00379 
00380       __pointer_type
00381       operator+=(ptrdiff_t __d) noexcept
00382       { return _M_b.operator+=(__d); }
00383 
00384       __pointer_type
00385       operator+=(ptrdiff_t __d) volatile noexcept
00386       { return _M_b.operator+=(__d); }
00387 
00388       __pointer_type
00389       operator-=(ptrdiff_t __d) noexcept
00390       { return _M_b.operator-=(__d); }
00391 
00392       __pointer_type
00393       operator-=(ptrdiff_t __d) volatile noexcept
00394       { return _M_b.operator-=(__d); }
00395 
00396       bool
00397       is_lock_free() const noexcept
00398       { return _M_b.is_lock_free(); }
00399 
00400       bool
00401       is_lock_free() const volatile noexcept
00402       { return _M_b.is_lock_free(); }
00403 
00404       void
00405       store(__pointer_type __p,
00406             memory_order __m = memory_order_seq_cst) noexcept
00407       { return _M_b.store(__p, __m); }
00408 
00409       void
00410       store(__pointer_type __p,
00411             memory_order __m = memory_order_seq_cst) volatile noexcept
00412       { return _M_b.store(__p, __m); }
00413 
00414       __pointer_type
00415       load(memory_order __m = memory_order_seq_cst) const noexcept
00416       { return _M_b.load(__m); }
00417 
00418       __pointer_type
00419       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00420       { return _M_b.load(__m); }
00421 
00422       __pointer_type
00423       exchange(__pointer_type __p,
00424                memory_order __m = memory_order_seq_cst) noexcept
00425       { return _M_b.exchange(__p, __m); }
00426 
00427       __pointer_type
00428       exchange(__pointer_type __p,
00429                memory_order __m = memory_order_seq_cst) volatile noexcept
00430       { return _M_b.exchange(__p, __m); }
00431 
00432       bool
00433       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00434                             memory_order __m1, memory_order __m2) noexcept
00435       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00436 
00437       bool
00438       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00439                             memory_order __m1,
00440                             memory_order __m2) volatile noexcept
00441       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00442 
00443       bool
00444       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00445                             memory_order __m = memory_order_seq_cst) noexcept
00446       {
00447         return compare_exchange_weak(__p1, __p2, __m,
00448                                      __cmpexch_failure_order(__m));
00449       }
00450 
00451       bool
00452       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00453                     memory_order __m = memory_order_seq_cst) volatile noexcept
00454       {
00455         return compare_exchange_weak(__p1, __p2, __m,
00456                                      __cmpexch_failure_order(__m));
00457       }
00458 
00459       bool
00460       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00461                               memory_order __m1, memory_order __m2) noexcept
00462       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00463 
00464       bool
00465       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00466                               memory_order __m1,
00467                               memory_order __m2) volatile noexcept
00468       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00469 
00470       bool
00471       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00472                               memory_order __m = memory_order_seq_cst) noexcept
00473       {
00474         return _M_b.compare_exchange_strong(__p1, __p2, __m,
00475                                             __cmpexch_failure_order(__m));
00476       }
00477 
00478       bool
00479       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00480                     memory_order __m = memory_order_seq_cst) volatile noexcept
00481       {
00482         return _M_b.compare_exchange_strong(__p1, __p2, __m,
00483                                             __cmpexch_failure_order(__m));
00484       }
00485 
00486       __pointer_type
00487       fetch_add(ptrdiff_t __d,
00488                 memory_order __m = memory_order_seq_cst) noexcept
00489       { return _M_b.fetch_add(__d, __m); }
00490 
00491       __pointer_type
00492       fetch_add(ptrdiff_t __d,
00493                 memory_order __m = memory_order_seq_cst) volatile noexcept
00494       { return _M_b.fetch_add(__d, __m); }
00495 
00496       __pointer_type
00497       fetch_sub(ptrdiff_t __d,
00498                 memory_order __m = memory_order_seq_cst) noexcept
00499       { return _M_b.fetch_sub(__d, __m); }
00500 
00501       __pointer_type
00502       fetch_sub(ptrdiff_t __d,
00503                 memory_order __m = memory_order_seq_cst) volatile noexcept
00504       { return _M_b.fetch_sub(__d, __m); }
00505     };
00506 
00507 
00508   /// Explicit specialization for char.
00509   template<>
00510     struct atomic<char> : __atomic_base<char>
00511     {
00512       typedef char                      __integral_type;
00513       typedef __atomic_base<char>       __base_type;
00514 
00515       atomic() noexcept = default;
00516       ~atomic() noexcept = default;
00517       atomic(const atomic&) = delete;
00518       atomic& operator=(const atomic&) = delete;
00519       atomic& operator=(const atomic&) volatile = delete;
00520 
00521       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00522 
00523       using __base_type::operator __integral_type;
00524       using __base_type::operator=;
00525     };
00526 
00527   /// Explicit specialization for signed char.
00528   template<>
00529     struct atomic<signed char> : __atomic_base<signed char>
00530     {
00531       typedef signed char               __integral_type;
00532       typedef __atomic_base<signed char>        __base_type;
00533 
00534       atomic() noexcept= default;
00535       ~atomic() noexcept = default;
00536       atomic(const atomic&) = delete;
00537       atomic& operator=(const atomic&) = delete;
00538       atomic& operator=(const atomic&) volatile = delete;
00539 
00540       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00541 
00542       using __base_type::operator __integral_type;
00543       using __base_type::operator=;
00544     };
00545 
00546   /// Explicit specialization for unsigned char.
00547   template<>
00548     struct atomic<unsigned char> : __atomic_base<unsigned char>
00549     {
00550       typedef unsigned char             __integral_type;
00551       typedef __atomic_base<unsigned char>      __base_type;
00552 
00553       atomic() noexcept= default;
00554       ~atomic() noexcept = default;
00555       atomic(const atomic&) = delete;
00556       atomic& operator=(const atomic&) = delete;
00557       atomic& operator=(const atomic&) volatile = delete;
00558 
00559       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00560 
00561       using __base_type::operator __integral_type;
00562       using __base_type::operator=;
00563     };
00564 
00565   /// Explicit specialization for short.
00566   template<>
00567     struct atomic<short> : __atomic_base<short>
00568     {
00569       typedef short                     __integral_type;
00570       typedef __atomic_base<short>              __base_type;
00571 
00572       atomic() noexcept = default;
00573       ~atomic() noexcept = default;
00574       atomic(const atomic&) = delete;
00575       atomic& operator=(const atomic&) = delete;
00576       atomic& operator=(const atomic&) volatile = delete;
00577 
00578       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00579 
00580       using __base_type::operator __integral_type;
00581       using __base_type::operator=;
00582     };
00583 
00584   /// Explicit specialization for unsigned short.
00585   template<>
00586     struct atomic<unsigned short> : __atomic_base<unsigned short>
00587     {
00588       typedef unsigned short            __integral_type;
00589       typedef __atomic_base<unsigned short>             __base_type;
00590 
00591       atomic() noexcept = default;
00592       ~atomic() noexcept = default;
00593       atomic(const atomic&) = delete;
00594       atomic& operator=(const atomic&) = delete;
00595       atomic& operator=(const atomic&) volatile = delete;
00596 
00597       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00598 
00599       using __base_type::operator __integral_type;
00600       using __base_type::operator=;
00601     };
00602 
00603   /// Explicit specialization for int.
00604   template<>
00605     struct atomic<int> : __atomic_base<int>
00606     {
00607       typedef int                       __integral_type;
00608       typedef __atomic_base<int>                __base_type;
00609 
00610       atomic() noexcept = default;
00611       ~atomic() noexcept = default;
00612       atomic(const atomic&) = delete;
00613       atomic& operator=(const atomic&) = delete;
00614       atomic& operator=(const atomic&) volatile = delete;
00615 
00616       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00617 
00618       using __base_type::operator __integral_type;
00619       using __base_type::operator=;
00620     };
00621 
00622   /// Explicit specialization for unsigned int.
00623   template<>
00624     struct atomic<unsigned int> : __atomic_base<unsigned int>
00625     {
00626       typedef unsigned int              __integral_type;
00627       typedef __atomic_base<unsigned int>       __base_type;
00628 
00629       atomic() noexcept = default;
00630       ~atomic() noexcept = default;
00631       atomic(const atomic&) = delete;
00632       atomic& operator=(const atomic&) = delete;
00633       atomic& operator=(const atomic&) volatile = delete;
00634 
00635       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00636 
00637       using __base_type::operator __integral_type;
00638       using __base_type::operator=;
00639     };
00640 
00641   /// Explicit specialization for long.
00642   template<>
00643     struct atomic<long> : __atomic_base<long>
00644     {
00645       typedef long                      __integral_type;
00646       typedef __atomic_base<long>       __base_type;
00647 
00648       atomic() noexcept = default;
00649       ~atomic() noexcept = default;
00650       atomic(const atomic&) = delete;
00651       atomic& operator=(const atomic&) = delete;
00652       atomic& operator=(const atomic&) volatile = delete;
00653 
00654       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00655 
00656       using __base_type::operator __integral_type;
00657       using __base_type::operator=;
00658     };
00659 
00660   /// Explicit specialization for unsigned long.
00661   template<>
00662     struct atomic<unsigned long> : __atomic_base<unsigned long>
00663     {
00664       typedef unsigned long             __integral_type;
00665       typedef __atomic_base<unsigned long>      __base_type;
00666 
00667       atomic() noexcept = default;
00668       ~atomic() noexcept = default;
00669       atomic(const atomic&) = delete;
00670       atomic& operator=(const atomic&) = delete;
00671       atomic& operator=(const atomic&) volatile = delete;
00672 
00673       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00674 
00675       using __base_type::operator __integral_type;
00676       using __base_type::operator=;
00677     };
00678 
00679   /// Explicit specialization for long long.
00680   template<>
00681     struct atomic<long long> : __atomic_base<long long>
00682     {
00683       typedef long long                 __integral_type;
00684       typedef __atomic_base<long long>          __base_type;
00685 
00686       atomic() noexcept = default;
00687       ~atomic() noexcept = default;
00688       atomic(const atomic&) = delete;
00689       atomic& operator=(const atomic&) = delete;
00690       atomic& operator=(const atomic&) volatile = delete;
00691 
00692       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00693 
00694       using __base_type::operator __integral_type;
00695       using __base_type::operator=;
00696     };
00697 
00698   /// Explicit specialization for unsigned long long.
00699   template<>
00700     struct atomic<unsigned long long> : __atomic_base<unsigned long long>
00701     {
00702       typedef unsigned long long        __integral_type;
00703       typedef __atomic_base<unsigned long long>         __base_type;
00704 
00705       atomic() noexcept = default;
00706       ~atomic() noexcept = default;
00707       atomic(const atomic&) = delete;
00708       atomic& operator=(const atomic&) = delete;
00709       atomic& operator=(const atomic&) volatile = delete;
00710 
00711       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00712 
00713       using __base_type::operator __integral_type;
00714       using __base_type::operator=;
00715     };
00716 
00717   /// Explicit specialization for wchar_t.
00718   template<>
00719     struct atomic<wchar_t> : __atomic_base<wchar_t>
00720     {
00721       typedef wchar_t                   __integral_type;
00722       typedef __atomic_base<wchar_t>    __base_type;
00723 
00724       atomic() noexcept = default;
00725       ~atomic() noexcept = default;
00726       atomic(const atomic&) = delete;
00727       atomic& operator=(const atomic&) = delete;
00728       atomic& operator=(const atomic&) volatile = delete;
00729 
00730       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00731 
00732       using __base_type::operator __integral_type;
00733       using __base_type::operator=;
00734     };
00735 
00736   /// Explicit specialization for char16_t.
00737   template<>
00738     struct atomic<char16_t> : __atomic_base<char16_t>
00739     {
00740       typedef char16_t                  __integral_type;
00741       typedef __atomic_base<char16_t>   __base_type;
00742 
00743       atomic() noexcept = default;
00744       ~atomic() noexcept = default;
00745       atomic(const atomic&) = delete;
00746       atomic& operator=(const atomic&) = delete;
00747       atomic& operator=(const atomic&) volatile = delete;
00748 
00749       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00750 
00751       using __base_type::operator __integral_type;
00752       using __base_type::operator=;
00753     };
00754 
00755   /// Explicit specialization for char32_t.
00756   template<>
00757     struct atomic<char32_t> : __atomic_base<char32_t>
00758     {
00759       typedef char32_t                  __integral_type;
00760       typedef __atomic_base<char32_t>   __base_type;
00761 
00762       atomic() noexcept = default;
00763       ~atomic() noexcept = default;
00764       atomic(const atomic&) = delete;
00765       atomic& operator=(const atomic&) = delete;
00766       atomic& operator=(const atomic&) volatile = delete;
00767 
00768       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00769 
00770       using __base_type::operator __integral_type;
00771       using __base_type::operator=;
00772     };
00773 
00774 
00775   /// atomic_bool
00776   typedef atomic<bool>                  atomic_bool;
00777 
00778   /// atomic_char
00779   typedef atomic<char>                  atomic_char;
00780 
00781   /// atomic_schar
00782   typedef atomic<signed char>           atomic_schar;
00783 
00784   /// atomic_uchar
00785   typedef atomic<unsigned char>         atomic_uchar;
00786 
00787   /// atomic_short
00788   typedef atomic<short>                 atomic_short;
00789 
00790   /// atomic_ushort
00791   typedef atomic<unsigned short>        atomic_ushort;
00792 
00793   /// atomic_int
00794   typedef atomic<int>                   atomic_int;
00795 
00796   /// atomic_uint
00797   typedef atomic<unsigned int>          atomic_uint;
00798 
00799   /// atomic_long
00800   typedef atomic<long>                  atomic_long;
00801 
00802   /// atomic_ulong
00803   typedef atomic<unsigned long>         atomic_ulong;
00804 
00805   /// atomic_llong
00806   typedef atomic<long long>             atomic_llong;
00807 
00808   /// atomic_ullong
00809   typedef atomic<unsigned long long>    atomic_ullong;
00810 
00811   /// atomic_wchar_t
00812   typedef atomic<wchar_t>               atomic_wchar_t;
00813 
00814   /// atomic_char16_t
00815   typedef atomic<char16_t>              atomic_char16_t;
00816 
00817   /// atomic_char32_t
00818   typedef atomic<char32_t>              atomic_char32_t;
00819 
00820 
00821   /// atomic_int_least8_t
00822   typedef atomic<int_least8_t>          atomic_int_least8_t;
00823 
00824   /// atomic_uint_least8_t
00825   typedef atomic<uint_least8_t>         atomic_uint_least8_t;
00826 
00827   /// atomic_int_least16_t
00828   typedef atomic<int_least16_t>         atomic_int_least16_t;
00829 
00830   /// atomic_uint_least16_t
00831   typedef atomic<uint_least16_t>        atomic_uint_least16_t;
00832 
00833   /// atomic_int_least32_t
00834   typedef atomic<int_least32_t>         atomic_int_least32_t;
00835 
00836   /// atomic_uint_least32_t
00837   typedef atomic<uint_least32_t>        atomic_uint_least32_t;
00838 
00839   /// atomic_int_least64_t
00840   typedef atomic<int_least64_t>         atomic_int_least64_t;
00841 
00842   /// atomic_uint_least64_t
00843   typedef atomic<uint_least64_t>        atomic_uint_least64_t;
00844 
00845 
00846   /// atomic_int_fast8_t
00847   typedef atomic<int_fast8_t>           atomic_int_fast8_t;
00848 
00849   /// atomic_uint_fast8_t
00850   typedef atomic<uint_fast8_t>          atomic_uint_fast8_t;
00851 
00852   /// atomic_int_fast16_t
00853   typedef atomic<int_fast16_t>          atomic_int_fast16_t;
00854 
00855   /// atomic_uint_fast16_t
00856   typedef atomic<uint_fast16_t>         atomic_uint_fast16_t;
00857 
00858   /// atomic_int_fast32_t
00859   typedef atomic<int_fast32_t>          atomic_int_fast32_t;
00860 
00861   /// atomic_uint_fast32_t
00862   typedef atomic<uint_fast32_t>         atomic_uint_fast32_t;
00863 
00864   /// atomic_int_fast64_t
00865   typedef atomic<int_fast64_t>          atomic_int_fast64_t;
00866 
00867   /// atomic_uint_fast64_t
00868   typedef atomic<uint_fast64_t>         atomic_uint_fast64_t;
00869 
00870 
00871   /// atomic_intptr_t
00872   typedef atomic<intptr_t>              atomic_intptr_t;
00873 
00874   /// atomic_uintptr_t
00875   typedef atomic<uintptr_t>             atomic_uintptr_t;
00876 
00877   /// atomic_size_t
00878   typedef atomic<size_t>                atomic_size_t;
00879 
00880   /// atomic_intmax_t
00881   typedef atomic<intmax_t>              atomic_intmax_t;
00882 
00883   /// atomic_uintmax_t
00884   typedef atomic<uintmax_t>             atomic_uintmax_t;
00885 
00886   /// atomic_ptrdiff_t
00887   typedef atomic<ptrdiff_t>             atomic_ptrdiff_t;
00888 
00889 
00890   // Function definitions, atomic_flag operations.
00891   inline bool
00892   atomic_flag_test_and_set_explicit(atomic_flag* __a,
00893                                     memory_order __m) noexcept
00894   { return __a->test_and_set(__m); }
00895 
00896   inline bool
00897   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
00898                                     memory_order __m) noexcept
00899   { return __a->test_and_set(__m); }
00900 
00901   inline void
00902   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
00903   { __a->clear(__m); }
00904 
00905   inline void
00906   atomic_flag_clear_explicit(volatile atomic_flag* __a,
00907                              memory_order __m) noexcept
00908   { __a->clear(__m); }
00909 
00910   inline bool
00911   atomic_flag_test_and_set(atomic_flag* __a) noexcept
00912   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00913 
00914   inline bool
00915   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
00916   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00917 
00918   inline void
00919   atomic_flag_clear(atomic_flag* __a) noexcept
00920   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00921 
00922   inline void
00923   atomic_flag_clear(volatile atomic_flag* __a) noexcept
00924   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00925 
00926 
00927   // Function templates generally applicable to atomic types.
00928   template<typename _ITp>
00929     inline bool
00930     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
00931     { return __a->is_lock_free(); }
00932 
00933   template<typename _ITp>
00934     inline bool
00935     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
00936     { return __a->is_lock_free(); }
00937 
00938   template<typename _ITp>
00939     inline void
00940     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
00941     { __a->store(__i, memory_order_relaxed); }
00942 
00943   template<typename _ITp>
00944     inline void
00945     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00946     { __a->store(__i, memory_order_relaxed); }
00947 
00948   template<typename _ITp>
00949     inline void
00950     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
00951                           memory_order __m) noexcept
00952     { __a->store(__i, __m); }
00953 
00954   template<typename _ITp>
00955     inline void
00956     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00957                           memory_order __m) noexcept
00958     { __a->store(__i, __m); }
00959 
00960   template<typename _ITp>
00961     inline _ITp
00962     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
00963     { return __a->load(__m); }
00964 
00965   template<typename _ITp>
00966     inline _ITp
00967     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00968                          memory_order __m) noexcept
00969     { return __a->load(__m); }
00970 
00971   template<typename _ITp>
00972     inline _ITp
00973     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00974                              memory_order __m) noexcept
00975     { return __a->exchange(__i, __m); }
00976 
00977   template<typename _ITp>
00978     inline _ITp
00979     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00980                              memory_order __m) noexcept
00981     { return __a->exchange(__i, __m); }
00982 
00983   template<typename _ITp>
00984     inline bool
00985     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00986                                           _ITp* __i1, _ITp __i2,
00987                                           memory_order __m1,
00988                                           memory_order __m2) noexcept
00989     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00990 
00991   template<typename _ITp>
00992     inline bool
00993     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00994                                           _ITp* __i1, _ITp __i2,
00995                                           memory_order __m1,
00996                                           memory_order __m2) noexcept
00997     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00998 
00999   template<typename _ITp>
01000     inline bool
01001     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
01002                                             _ITp* __i1, _ITp __i2,
01003                                             memory_order __m1,
01004                                             memory_order __m2) noexcept
01005     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
01006 
01007   template<typename _ITp>
01008     inline bool
01009     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
01010                                             _ITp* __i1, _ITp __i2,
01011                                             memory_order __m1,
01012                                             memory_order __m2) noexcept
01013     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
01014 
01015 
01016   template<typename _ITp>
01017     inline void
01018     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
01019     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
01020 
01021   template<typename _ITp>
01022     inline void
01023     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
01024     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
01025 
01026   template<typename _ITp>
01027     inline _ITp
01028     atomic_load(const atomic<_ITp>* __a) noexcept
01029     { return atomic_load_explicit(__a, memory_order_seq_cst); }
01030 
01031   template<typename _ITp>
01032     inline _ITp
01033     atomic_load(const volatile atomic<_ITp>* __a) noexcept
01034     { return atomic_load_explicit(__a, memory_order_seq_cst); }
01035 
01036   template<typename _ITp>
01037     inline _ITp
01038     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
01039     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
01040 
01041   template<typename _ITp>
01042     inline _ITp
01043     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
01044     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
01045 
01046   template<typename _ITp>
01047     inline bool
01048     atomic_compare_exchange_weak(atomic<_ITp>* __a,
01049                                  _ITp* __i1, _ITp __i2) noexcept
01050     {
01051       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
01052                                                    memory_order_seq_cst,
01053                                                    memory_order_seq_cst);
01054     }
01055 
01056   template<typename _ITp>
01057     inline bool
01058     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
01059                                  _ITp* __i1, _ITp __i2) noexcept
01060     {
01061       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
01062                                                    memory_order_seq_cst,
01063                                                    memory_order_seq_cst);
01064     }
01065 
01066   template<typename _ITp>
01067     inline bool
01068     atomic_compare_exchange_strong(atomic<_ITp>* __a,
01069                                    _ITp* __i1, _ITp __i2) noexcept
01070     {
01071       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
01072                                                      memory_order_seq_cst,
01073                                                      memory_order_seq_cst);
01074     }
01075 
01076   template<typename _ITp>
01077     inline bool
01078     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
01079                                    _ITp* __i1, _ITp __i2) noexcept
01080     {
01081       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
01082                                                      memory_order_seq_cst,
01083                                                      memory_order_seq_cst);
01084     }
01085 
01086   // Function templates for atomic_integral operations only, using
01087   // __atomic_base. Template argument should be constricted to
01088   // intergral types as specified in the standard, excluding address
01089   // types.
01090   template<typename _ITp>
01091     inline _ITp
01092     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01093                               memory_order __m) noexcept
01094     { return __a->fetch_add(__i, __m); }
01095 
01096   template<typename _ITp>
01097     inline _ITp
01098     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01099                               memory_order __m) noexcept
01100     { return __a->fetch_add(__i, __m); }
01101 
01102   template<typename _ITp>
01103     inline _ITp
01104     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01105                               memory_order __m) noexcept
01106     { return __a->fetch_sub(__i, __m); }
01107 
01108   template<typename _ITp>
01109     inline _ITp
01110     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01111                               memory_order __m) noexcept
01112     { return __a->fetch_sub(__i, __m); }
01113 
01114   template<typename _ITp>
01115     inline _ITp
01116     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01117                               memory_order __m) noexcept
01118     { return __a->fetch_and(__i, __m); }
01119 
01120   template<typename _ITp>
01121     inline _ITp
01122     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01123                               memory_order __m) noexcept
01124     { return __a->fetch_and(__i, __m); }
01125 
01126   template<typename _ITp>
01127     inline _ITp
01128     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01129                              memory_order __m) noexcept
01130     { return __a->fetch_or(__i, __m); }
01131 
01132   template<typename _ITp>
01133     inline _ITp
01134     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01135                              memory_order __m) noexcept
01136     { return __a->fetch_or(__i, __m); }
01137 
01138   template<typename _ITp>
01139     inline _ITp
01140     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01141                               memory_order __m) noexcept
01142     { return __a->fetch_xor(__i, __m); }
01143 
01144   template<typename _ITp>
01145     inline _ITp
01146     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01147                               memory_order __m) noexcept
01148     { return __a->fetch_xor(__i, __m); }
01149 
01150   template<typename _ITp>
01151     inline _ITp
01152     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01153     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01154 
01155   template<typename _ITp>
01156     inline _ITp
01157     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01158     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01159 
01160   template<typename _ITp>
01161     inline _ITp
01162     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01163     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01164 
01165   template<typename _ITp>
01166     inline _ITp
01167     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01168     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01169 
01170   template<typename _ITp>
01171     inline _ITp
01172     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01173     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01174 
01175   template<typename _ITp>
01176     inline _ITp
01177     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01178     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01179 
01180   template<typename _ITp>
01181     inline _ITp
01182     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01183     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01184 
01185   template<typename _ITp>
01186     inline _ITp
01187     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01188     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01189 
01190   template<typename _ITp>
01191     inline _ITp
01192     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01193     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01194 
01195   template<typename _ITp>
01196     inline _ITp
01197     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01198     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01199 
01200 
01201   // Partial specializations for pointers.
01202   template<typename _ITp>
01203     inline _ITp*
01204     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01205                               memory_order __m) noexcept
01206     { return __a->fetch_add(__d, __m); }
01207 
01208   template<typename _ITp>
01209     inline _ITp*
01210     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
01211                               memory_order __m) noexcept
01212     { return __a->fetch_add(__d, __m); }
01213 
01214   template<typename _ITp>
01215     inline _ITp*
01216     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01217     { return __a->fetch_add(__d); }
01218 
01219   template<typename _ITp>
01220     inline _ITp*
01221     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01222     { return __a->fetch_add(__d); }
01223 
01224   template<typename _ITp>
01225     inline _ITp*
01226     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01227                               ptrdiff_t __d, memory_order __m) noexcept
01228     { return __a->fetch_sub(__d, __m); }
01229 
01230   template<typename _ITp>
01231     inline _ITp*
01232     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01233                               memory_order __m) noexcept
01234     { return __a->fetch_sub(__d, __m); }
01235 
01236   template<typename _ITp>
01237     inline _ITp*
01238     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01239     { return __a->fetch_sub(__d); }
01240 
01241   template<typename _ITp>
01242     inline _ITp*
01243     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01244     { return __a->fetch_sub(__d); }
01245   // @} group atomics
01246 
01247 _GLIBCXX_END_NAMESPACE_VERSION
01248 } // namespace
01249 
01250 #endif // C++11
01251 
01252 #endif // _GLIBCXX_ATOMIC