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