libstdc++
atomic
Go to the documentation of this file.
00001 // -*- C++ -*- header.
00002 
00003 // Copyright (C) 2008, 2009, 2010, 2011, 2012 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   /**
00152    *  @brief Generic atomic type, primary class template.
00153    *
00154    *  @tparam _Tp  Type to be made atomic, must be trivally copyable.
00155    */
00156   template<typename _Tp>
00157     struct atomic
00158     {
00159     private:
00160       _Tp _M_i;
00161 
00162     public:
00163       atomic() noexcept = default;
00164       ~atomic() noexcept = default;
00165       atomic(const atomic&) = delete;
00166       atomic& operator=(const atomic&) = delete;
00167       atomic& operator=(const atomic&) volatile = delete;
00168 
00169       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
00170 
00171       operator _Tp() const noexcept
00172       { return load(); }
00173 
00174       operator _Tp() const volatile noexcept
00175       { return load(); }
00176 
00177       _Tp
00178       operator=(_Tp __i) noexcept 
00179       { store(__i); return __i; }
00180 
00181       _Tp
00182       operator=(_Tp __i) volatile noexcept 
00183       { store(__i); return __i; }
00184 
00185       bool
00186       is_lock_free() const noexcept
00187       { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
00188 
00189       bool
00190       is_lock_free() const volatile noexcept
00191       { return __atomic_is_lock_free(sizeof(_M_i), &_M_i); }
00192 
00193       void
00194       store(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
00195       { __atomic_store(&_M_i, &__i, _m); }
00196 
00197       void
00198       store(_Tp __i, memory_order _m = memory_order_seq_cst) volatile noexcept
00199       { __atomic_store(&_M_i, &__i, _m); }
00200 
00201       _Tp
00202       load(memory_order _m = memory_order_seq_cst) const noexcept
00203       { 
00204         _Tp tmp;
00205     __atomic_load(&_M_i, &tmp, _m); 
00206     return tmp;
00207       }
00208 
00209       _Tp
00210       load(memory_order _m = memory_order_seq_cst) const volatile noexcept
00211       { 
00212         _Tp tmp;
00213     __atomic_load(&_M_i, &tmp, _m); 
00214     return tmp;
00215       }
00216 
00217       _Tp
00218       exchange(_Tp __i, memory_order _m = memory_order_seq_cst) noexcept
00219       { 
00220         _Tp tmp;
00221     __atomic_exchange(&_M_i, &__i, &tmp, _m); 
00222     return tmp;
00223       }
00224 
00225       _Tp
00226       exchange(_Tp __i, 
00227            memory_order _m = memory_order_seq_cst) volatile noexcept
00228       { 
00229         _Tp tmp;
00230     __atomic_exchange(&_M_i, &__i, &tmp, _m); 
00231     return tmp;
00232       }
00233 
00234       bool
00235       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00236                 memory_order __f) noexcept
00237       {
00238     return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
00239       }
00240 
00241       bool
00242       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s, 
00243                 memory_order __f) volatile noexcept
00244       {
00245     return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f); 
00246       }
00247 
00248       bool
00249       compare_exchange_weak(_Tp& __e, _Tp __i,
00250                 memory_order __m = memory_order_seq_cst) noexcept
00251       { return compare_exchange_weak(__e, __i, __m, __m); }
00252 
00253       bool
00254       compare_exchange_weak(_Tp& __e, _Tp __i,
00255              memory_order __m = memory_order_seq_cst) volatile noexcept
00256       { return compare_exchange_weak(__e, __i, __m, __m); }
00257 
00258       bool
00259       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00260                   memory_order __f) noexcept
00261       {
00262     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00263       }
00264 
00265       bool
00266       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s, 
00267                   memory_order __f) volatile noexcept
00268       {
00269     return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f); 
00270       }
00271 
00272       bool
00273       compare_exchange_strong(_Tp& __e, _Tp __i,
00274                    memory_order __m = memory_order_seq_cst) noexcept
00275       { return compare_exchange_strong(__e, __i, __m, __m); }
00276 
00277       bool
00278       compare_exchange_strong(_Tp& __e, _Tp __i,
00279              memory_order __m = memory_order_seq_cst) volatile noexcept
00280       { return compare_exchange_strong(__e, __i, __m, __m); }
00281     };
00282 
00283 
00284   /// Partial specialization for pointer types.
00285   template<typename _Tp>
00286     struct atomic<_Tp*>
00287     {
00288       typedef _Tp*          __pointer_type;
00289       typedef __atomic_base<_Tp*>   __base_type;
00290       __base_type           _M_b;
00291 
00292       atomic() noexcept = default;
00293       ~atomic() noexcept = default;
00294       atomic(const atomic&) = delete;
00295       atomic& operator=(const atomic&) = delete;
00296       atomic& operator=(const atomic&) volatile = delete;
00297 
00298       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
00299 
00300       operator __pointer_type() const noexcept
00301       { return __pointer_type(_M_b); }
00302 
00303       operator __pointer_type() const volatile noexcept
00304       { return __pointer_type(_M_b); }
00305 
00306       __pointer_type
00307       operator=(__pointer_type __p) noexcept
00308       { return _M_b.operator=(__p); }
00309 
00310       __pointer_type
00311       operator=(__pointer_type __p) volatile noexcept
00312       { return _M_b.operator=(__p); }
00313 
00314       __pointer_type
00315       operator++(int) noexcept
00316       { return _M_b++; }
00317 
00318       __pointer_type
00319       operator++(int) volatile noexcept
00320       { return _M_b++; }
00321 
00322       __pointer_type
00323       operator--(int) noexcept
00324       { return _M_b--; }
00325 
00326       __pointer_type
00327       operator--(int) volatile noexcept
00328       { return _M_b--; }
00329 
00330       __pointer_type
00331       operator++() noexcept
00332       { return ++_M_b; }
00333 
00334       __pointer_type
00335       operator++() volatile noexcept
00336       { return ++_M_b; }
00337 
00338       __pointer_type
00339       operator--() noexcept
00340       { return --_M_b; }
00341 
00342       __pointer_type
00343       operator--() volatile noexcept
00344       { return --_M_b; }
00345 
00346       __pointer_type
00347       operator+=(ptrdiff_t __d) noexcept
00348       { return _M_b.operator+=(__d); }
00349 
00350       __pointer_type
00351       operator+=(ptrdiff_t __d) volatile noexcept
00352       { return _M_b.operator+=(__d); }
00353 
00354       __pointer_type
00355       operator-=(ptrdiff_t __d) noexcept
00356       { return _M_b.operator-=(__d); }
00357 
00358       __pointer_type
00359       operator-=(ptrdiff_t __d) volatile noexcept
00360       { return _M_b.operator-=(__d); }
00361 
00362       bool
00363       is_lock_free() const noexcept
00364       { return _M_b.is_lock_free(); }
00365 
00366       bool
00367       is_lock_free() const volatile noexcept
00368       { return _M_b.is_lock_free(); }
00369 
00370       void
00371       store(__pointer_type __p,
00372         memory_order __m = memory_order_seq_cst) noexcept
00373       { return _M_b.store(__p, __m); }
00374 
00375       void
00376       store(__pointer_type __p,
00377         memory_order __m = memory_order_seq_cst) volatile noexcept
00378       { return _M_b.store(__p, __m); }
00379 
00380       __pointer_type
00381       load(memory_order __m = memory_order_seq_cst) const noexcept
00382       { return _M_b.load(__m); }
00383 
00384       __pointer_type
00385       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
00386       { return _M_b.load(__m); }
00387 
00388       __pointer_type
00389       exchange(__pointer_type __p,
00390            memory_order __m = memory_order_seq_cst) noexcept
00391       { return _M_b.exchange(__p, __m); }
00392 
00393       __pointer_type
00394       exchange(__pointer_type __p,
00395            memory_order __m = memory_order_seq_cst) volatile noexcept
00396       { return _M_b.exchange(__p, __m); }
00397 
00398       bool
00399       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00400                 memory_order __m1, memory_order __m2) noexcept
00401       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00402 
00403       bool
00404       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00405                 memory_order __m1,
00406                 memory_order __m2) volatile noexcept
00407       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00408 
00409       bool
00410       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00411                 memory_order __m = memory_order_seq_cst) noexcept
00412       {
00413     return compare_exchange_weak(__p1, __p2, __m,
00414                      __cmpexch_failure_order(__m));
00415       }
00416 
00417       bool
00418       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
00419             memory_order __m = memory_order_seq_cst) volatile noexcept
00420       {
00421     return compare_exchange_weak(__p1, __p2, __m,
00422                      __cmpexch_failure_order(__m));
00423       }
00424 
00425       bool
00426       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00427                   memory_order __m1, memory_order __m2) noexcept
00428       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00429 
00430       bool
00431       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00432                   memory_order __m1,
00433                   memory_order __m2) volatile noexcept
00434       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
00435 
00436       bool
00437       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00438                   memory_order __m = memory_order_seq_cst) noexcept
00439       {
00440     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00441                         __cmpexch_failure_order(__m));
00442       }
00443 
00444       bool
00445       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
00446             memory_order __m = memory_order_seq_cst) volatile noexcept
00447       {
00448     return _M_b.compare_exchange_strong(__p1, __p2, __m,
00449                         __cmpexch_failure_order(__m));
00450       }
00451 
00452       __pointer_type
00453       fetch_add(ptrdiff_t __d,
00454         memory_order __m = memory_order_seq_cst) noexcept
00455       { return _M_b.fetch_add(__d, __m); }
00456 
00457       __pointer_type
00458       fetch_add(ptrdiff_t __d,
00459         memory_order __m = memory_order_seq_cst) volatile noexcept
00460       { return _M_b.fetch_add(__d, __m); }
00461 
00462       __pointer_type
00463       fetch_sub(ptrdiff_t __d,
00464         memory_order __m = memory_order_seq_cst) noexcept
00465       { return _M_b.fetch_sub(__d, __m); }
00466 
00467       __pointer_type
00468       fetch_sub(ptrdiff_t __d,
00469         memory_order __m = memory_order_seq_cst) volatile noexcept
00470       { return _M_b.fetch_sub(__d, __m); }
00471     };
00472 
00473 
00474   /// Explicit specialization for bool.
00475   template<>
00476     struct atomic<bool> : public atomic_bool
00477     {
00478       typedef bool          __integral_type;
00479       typedef atomic_bool       __base_type;
00480 
00481       atomic() noexcept = default;
00482       ~atomic() noexcept = default;
00483       atomic(const atomic&) = delete;
00484       atomic& operator=(const atomic&) = delete;
00485       atomic& operator=(const atomic&) volatile = delete;
00486 
00487       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00488 
00489       using __base_type::operator __integral_type;
00490       using __base_type::operator=;
00491     };
00492 
00493   /// Explicit specialization for char.
00494   template<>
00495     struct atomic<char> : public atomic_char
00496     {
00497       typedef char          __integral_type;
00498       typedef atomic_char       __base_type;
00499 
00500       atomic() noexcept = default;
00501       ~atomic() noexcept = default;
00502       atomic(const atomic&) = delete;
00503       atomic& operator=(const atomic&) = delete;
00504       atomic& operator=(const atomic&) volatile = delete;
00505 
00506       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
00507 
00508       using __base_type::operator __integral_type;
00509       using __base_type::operator=;
00510     };
00511 
00512   /// Explicit specialization for signed char.
00513   template<>
00514     struct atomic<signed char> : public atomic_schar
00515     {
00516       typedef signed char       __integral_type;
00517       typedef atomic_schar      __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 unsigned char.
00532   template<>
00533     struct atomic<unsigned char> : public atomic_uchar
00534     {
00535       typedef unsigned char         __integral_type;
00536       typedef atomic_uchar      __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 short.
00551   template<>
00552     struct atomic<short> : public atomic_short
00553     {
00554       typedef short             __integral_type;
00555       typedef atomic_short      __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 unsigned short.
00570   template<>
00571     struct atomic<unsigned short> : public atomic_ushort
00572     {
00573       typedef unsigned short            __integral_type;
00574       typedef atomic_ushort         __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 int.
00589   template<>
00590     struct atomic<int> : atomic_int
00591     {
00592       typedef int           __integral_type;
00593       typedef atomic_int        __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 unsigned int.
00608   template<>
00609     struct atomic<unsigned int> : public atomic_uint
00610     {
00611       typedef unsigned int      __integral_type;
00612       typedef atomic_uint       __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 long.
00627   template<>
00628     struct atomic<long> : public atomic_long
00629     {
00630       typedef long          __integral_type;
00631       typedef atomic_long       __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 unsigned long.
00646   template<>
00647     struct atomic<unsigned long> : public atomic_ulong
00648     {
00649       typedef unsigned long         __integral_type;
00650       typedef atomic_ulong      __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 long long.
00665   template<>
00666     struct atomic<long long> : public atomic_llong
00667     {
00668       typedef long long         __integral_type;
00669       typedef atomic_llong      __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 unsigned long long.
00684   template<>
00685     struct atomic<unsigned long long> : public atomic_ullong
00686     {
00687       typedef unsigned long long        __integral_type;
00688       typedef atomic_ullong         __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 wchar_t.
00703   template<>
00704     struct atomic<wchar_t> : public atomic_wchar_t
00705     {
00706       typedef wchar_t           __integral_type;
00707       typedef atomic_wchar_t        __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 char16_t.
00722   template<>
00723     struct atomic<char16_t> : public atomic_char16_t
00724     {
00725       typedef char16_t          __integral_type;
00726       typedef atomic_char16_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 char32_t.
00741   template<>
00742     struct atomic<char32_t> : public atomic_char32_t
00743     {
00744       typedef char32_t          __integral_type;
00745       typedef atomic_char32_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 
00760   // Function definitions, atomic_flag operations.
00761   inline bool
00762   atomic_flag_test_and_set_explicit(atomic_flag* __a,
00763                     memory_order __m) noexcept
00764   { return __a->test_and_set(__m); }
00765 
00766   inline bool
00767   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
00768                     memory_order __m) noexcept
00769   { return __a->test_and_set(__m); }
00770 
00771   inline void
00772   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
00773   { __a->clear(__m); }
00774 
00775   inline void
00776   atomic_flag_clear_explicit(volatile atomic_flag* __a,
00777                  memory_order __m) noexcept
00778   { __a->clear(__m); }
00779 
00780   inline bool
00781   atomic_flag_test_and_set(atomic_flag* __a) noexcept
00782   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00783 
00784   inline bool
00785   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
00786   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
00787 
00788   inline void
00789   atomic_flag_clear(atomic_flag* __a) noexcept
00790   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00791 
00792   inline void
00793   atomic_flag_clear(volatile atomic_flag* __a) noexcept
00794   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
00795 
00796 
00797   // Function templates generally applicable to atomic types.
00798   template<typename _ITp>
00799     inline bool
00800     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
00801     { return __a->is_lock_free(); }
00802 
00803   template<typename _ITp>
00804     inline bool
00805     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
00806     { return __a->is_lock_free(); }
00807 
00808   template<typename _ITp>
00809     inline void
00810     atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept;
00811 
00812   template<typename _ITp>
00813     inline void
00814     atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept;
00815 
00816   template<typename _ITp>
00817     inline void
00818     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
00819               memory_order __m) noexcept
00820     { __a->store(__i, __m); }
00821 
00822   template<typename _ITp>
00823     inline void
00824     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00825               memory_order __m) noexcept
00826     { __a->store(__i, __m); }
00827 
00828   template<typename _ITp>
00829     inline _ITp
00830     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
00831     { return __a->load(__m); }
00832 
00833   template<typename _ITp>
00834     inline _ITp
00835     atomic_load_explicit(const volatile atomic<_ITp>* __a,
00836              memory_order __m) noexcept
00837     { return __a->load(__m); }
00838 
00839   template<typename _ITp>
00840     inline _ITp
00841     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
00842                  memory_order __m) noexcept
00843     { return __a->exchange(__i, __m); }
00844 
00845   template<typename _ITp>
00846     inline _ITp
00847     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
00848                  memory_order __m) noexcept
00849     { return __a->exchange(__i, __m); }
00850 
00851   template<typename _ITp>
00852     inline bool
00853     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
00854                       _ITp* __i1, _ITp __i2,
00855                       memory_order __m1,
00856                       memory_order __m2) noexcept
00857     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00858 
00859   template<typename _ITp>
00860     inline bool
00861     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
00862                       _ITp* __i1, _ITp __i2,
00863                       memory_order __m1,
00864                       memory_order __m2) noexcept
00865     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
00866 
00867   template<typename _ITp>
00868     inline bool
00869     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
00870                         _ITp* __i1, _ITp __i2,
00871                         memory_order __m1,
00872                         memory_order __m2) noexcept
00873     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00874 
00875   template<typename _ITp>
00876     inline bool
00877     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
00878                         _ITp* __i1, _ITp __i2,
00879                         memory_order __m1,
00880                         memory_order __m2) noexcept
00881     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
00882 
00883 
00884   template<typename _ITp>
00885     inline void
00886     atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
00887     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00888 
00889   template<typename _ITp>
00890     inline void
00891     atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00892     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
00893 
00894   template<typename _ITp>
00895     inline _ITp
00896     atomic_load(const atomic<_ITp>* __a) noexcept
00897     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00898 
00899   template<typename _ITp>
00900     inline _ITp
00901     atomic_load(const volatile atomic<_ITp>* __a) noexcept
00902     { return atomic_load_explicit(__a, memory_order_seq_cst); }
00903 
00904   template<typename _ITp>
00905     inline _ITp
00906     atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
00907     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00908 
00909   template<typename _ITp>
00910     inline _ITp
00911     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
00912     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
00913 
00914   template<typename _ITp>
00915     inline bool
00916     atomic_compare_exchange_weak(atomic<_ITp>* __a,
00917                  _ITp* __i1, _ITp __i2) noexcept
00918     {
00919       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00920                            memory_order_seq_cst,
00921                            memory_order_seq_cst);
00922     }
00923 
00924   template<typename _ITp>
00925     inline bool
00926     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
00927                  _ITp* __i1, _ITp __i2) noexcept
00928     {
00929       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
00930                            memory_order_seq_cst,
00931                            memory_order_seq_cst);
00932     }
00933 
00934   template<typename _ITp>
00935     inline bool
00936     atomic_compare_exchange_strong(atomic<_ITp>* __a,
00937                    _ITp* __i1, _ITp __i2) noexcept
00938     {
00939       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00940                              memory_order_seq_cst,
00941                              memory_order_seq_cst);
00942     }
00943 
00944   template<typename _ITp>
00945     inline bool
00946     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
00947                    _ITp* __i1, _ITp __i2) noexcept
00948     {
00949       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
00950                              memory_order_seq_cst,
00951                              memory_order_seq_cst);
00952     }
00953 
00954   // Function templates for atomic_integral operations only, using
00955   // __atomic_base. Template argument should be constricted to
00956   // intergral types as specified in the standard, excluding address
00957   // types.
00958   template<typename _ITp>
00959     inline _ITp
00960     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00961                   memory_order __m) noexcept
00962     { return __a->fetch_add(__i, __m); }
00963 
00964   template<typename _ITp>
00965     inline _ITp
00966     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00967                   memory_order __m) noexcept
00968     { return __a->fetch_add(__i, __m); }
00969 
00970   template<typename _ITp>
00971     inline _ITp
00972     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00973                   memory_order __m) noexcept
00974     { return __a->fetch_sub(__i, __m); }
00975 
00976   template<typename _ITp>
00977     inline _ITp
00978     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00979                   memory_order __m) noexcept
00980     { return __a->fetch_sub(__i, __m); }
00981 
00982   template<typename _ITp>
00983     inline _ITp
00984     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00985                   memory_order __m) noexcept
00986     { return __a->fetch_and(__i, __m); }
00987 
00988   template<typename _ITp>
00989     inline _ITp
00990     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
00991                   memory_order __m) noexcept
00992     { return __a->fetch_and(__i, __m); }
00993 
00994   template<typename _ITp>
00995     inline _ITp
00996     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
00997                  memory_order __m) noexcept
00998     { return __a->fetch_or(__i, __m); }
00999 
01000   template<typename _ITp>
01001     inline _ITp
01002     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01003                  memory_order __m) noexcept
01004     { return __a->fetch_or(__i, __m); }
01005 
01006   template<typename _ITp>
01007     inline _ITp
01008     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
01009                   memory_order __m) noexcept
01010     { return __a->fetch_xor(__i, __m); }
01011 
01012   template<typename _ITp>
01013     inline _ITp
01014     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
01015                   memory_order __m) noexcept
01016     { return __a->fetch_xor(__i, __m); }
01017 
01018   template<typename _ITp>
01019     inline _ITp
01020     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01021     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01022 
01023   template<typename _ITp>
01024     inline _ITp
01025     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01026     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
01027 
01028   template<typename _ITp>
01029     inline _ITp
01030     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01031     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01032 
01033   template<typename _ITp>
01034     inline _ITp
01035     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01036     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
01037 
01038   template<typename _ITp>
01039     inline _ITp
01040     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01041     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01042 
01043   template<typename _ITp>
01044     inline _ITp
01045     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01046     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
01047 
01048   template<typename _ITp>
01049     inline _ITp
01050     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01051     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01052 
01053   template<typename _ITp>
01054     inline _ITp
01055     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01056     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
01057 
01058   template<typename _ITp>
01059     inline _ITp
01060     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
01061     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01062 
01063   template<typename _ITp>
01064     inline _ITp
01065     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
01066     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
01067 
01068 
01069   // Partial specializations for pointers.
01070   template<typename _ITp>
01071     inline _ITp*
01072     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01073                   memory_order __m) noexcept
01074     { return __a->fetch_add(__d, __m); }
01075 
01076   template<typename _ITp>
01077     inline _ITp*
01078     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
01079                   memory_order __m) noexcept
01080     { return __a->fetch_add(__d, __m); }
01081 
01082   template<typename _ITp>
01083     inline _ITp*
01084     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01085     { return __a->fetch_add(__d); }
01086 
01087   template<typename _ITp>
01088     inline _ITp*
01089     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01090     { return __a->fetch_add(__d); }
01091 
01092   template<typename _ITp>
01093     inline _ITp*
01094     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
01095                   ptrdiff_t __d, memory_order __m) noexcept
01096     { return __a->fetch_sub(__d, __m); }
01097 
01098   template<typename _ITp>
01099     inline _ITp*
01100     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
01101                   memory_order __m) noexcept
01102     { return __a->fetch_sub(__d, __m); }
01103 
01104   template<typename _ITp>
01105     inline _ITp*
01106     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01107     { return __a->fetch_sub(__d); }
01108 
01109   template<typename _ITp>
01110     inline _ITp*
01111     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
01112     { return __a->fetch_sub(__d); }
01113   // @} group atomics
01114 
01115 _GLIBCXX_END_NAMESPACE_VERSION
01116 } // namespace
01117 
01118 #endif