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