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