Home | History | Annotate | Download | only in include
      1 // -*- C++ -*- header.
      2 
      3 // Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4 //
      5 // This file is part of the GNU ISO C++ Library.  This library is free
      6 // software; you can redistribute it and/or modify it under the
      7 // terms of the GNU General Public License as published by the
      8 // Free Software Foundation; either version 3, or (at your option)
      9 // any later version.
     10 
     11 // This library is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 
     16 // Under Section 7 of GPL version 3, you are granted additional
     17 // permissions described in the GCC Runtime Library Exception, version
     18 // 3.1, as published by the Free Software Foundation.
     19 
     20 // You should have received a copy of the GNU General Public License and
     21 // a copy of the GCC Runtime Library Exception along with this program;
     22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23 // <http://www.gnu.org/licenses/>.
     24 
     25 /** @file include/atomic
     26  *  This is a Standard C++ Library header.
     27  */
     28 
     29 // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
     30 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
     31 
     32 #ifndef _GLIBCXX_ATOMIC
     33 #define _GLIBCXX_ATOMIC 1
     34 
     35 #pragma GCC system_header
     36 
     37 #ifndef __GXX_EXPERIMENTAL_CXX0X__
     38 # include <bits/c++0x_warning.h>
     39 #endif
     40 
     41 #include <bits/atomic_base.h>
     42 #include <bits/atomic_0.h>
     43 #include <bits/atomic_2.h>
     44 
     45 namespace std _GLIBCXX_VISIBILITY(default)
     46 {
     47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     48 
     49   /**
     50    * @addtogroup atomics
     51    * @{
     52    */
     53 
     54   /// atomic_bool
     55   // NB: No operators or fetch-operations for this type.
     56   struct atomic_bool
     57   {
     58   private:
     59     __atomic_base<bool>	_M_base;
     60 
     61   public:
     62     atomic_bool() = default;
     63     ~atomic_bool() = default;
     64     atomic_bool(const atomic_bool&) = delete;
     65     atomic_bool& operator=(const atomic_bool&) = delete;
     66     atomic_bool& operator=(const atomic_bool&) volatile = delete;
     67 
     68     constexpr atomic_bool(bool __i) : _M_base(__i) { }
     69 
     70     bool
     71     operator=(bool __i)
     72     { return _M_base.operator=(__i); }
     73 
     74     operator bool() const
     75     { return _M_base.load(); }
     76 
     77     operator bool() const volatile
     78     { return _M_base.load(); }
     79 
     80     bool
     81     is_lock_free() const { return _M_base.is_lock_free(); }
     82 
     83     bool
     84     is_lock_free() const volatile { return _M_base.is_lock_free(); }
     85 
     86     void
     87     store(bool __i, memory_order __m = memory_order_seq_cst)
     88     { _M_base.store(__i, __m); }
     89 
     90     void
     91     store(bool __i, memory_order __m = memory_order_seq_cst) volatile
     92     { _M_base.store(__i, __m); }
     93 
     94     bool
     95     load(memory_order __m = memory_order_seq_cst) const
     96     { return _M_base.load(__m); }
     97 
     98     bool
     99     load(memory_order __m = memory_order_seq_cst) const volatile
    100     { return _M_base.load(__m); }
    101 
    102     bool
    103     exchange(bool __i, memory_order __m = memory_order_seq_cst)
    104     { return _M_base.exchange(__i, __m); }
    105 
    106     bool
    107     exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile
    108     { return _M_base.exchange(__i, __m); }
    109 
    110     bool
    111     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    112 			  memory_order __m2)
    113     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    114 
    115     bool
    116     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    117 			  memory_order __m2) volatile
    118     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    119 
    120     bool
    121     compare_exchange_weak(bool& __i1, bool __i2,
    122 			  memory_order __m = memory_order_seq_cst)
    123     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    124 
    125     bool
    126     compare_exchange_weak(bool& __i1, bool __i2,
    127 			  memory_order __m = memory_order_seq_cst) volatile
    128     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    129 
    130     bool
    131     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    132 			    memory_order __m2)
    133     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    134 
    135     bool
    136     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    137 			    memory_order __m2) volatile
    138     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    139 
    140     bool
    141     compare_exchange_strong(bool& __i1, bool __i2,
    142 			    memory_order __m = memory_order_seq_cst)
    143     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    144 
    145     bool
    146     compare_exchange_strong(bool& __i1, bool __i2,
    147 			    memory_order __m = memory_order_seq_cst) volatile
    148     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    149   };
    150 
    151 
    152   /// atomic
    153   /// 29.4.3, Generic atomic type, primary class template.
    154   template<typename _Tp>
    155     struct atomic
    156     {
    157     private:
    158       _Tp _M_i;
    159 
    160     public:
    161       atomic() = default;
    162       ~atomic() = default;
    163       atomic(const atomic&) = delete;
    164       atomic& operator=(const atomic&) = delete;
    165       atomic& operator=(const atomic&) volatile = delete;
    166 
    167       constexpr atomic(_Tp __i) : _M_i(__i) { }
    168 
    169       operator _Tp() const;
    170 
    171       operator _Tp() const volatile;
    172 
    173       _Tp
    174       operator=(_Tp __i) { store(__i); return __i; }
    175 
    176       _Tp
    177       operator=(_Tp __i) volatile { store(__i); return __i; }
    178 
    179       bool
    180       is_lock_free() const;
    181 
    182       bool
    183       is_lock_free() const volatile;
    184 
    185       void
    186       store(_Tp, memory_order = memory_order_seq_cst);
    187 
    188       void
    189       store(_Tp, memory_order = memory_order_seq_cst) volatile;
    190 
    191       _Tp
    192       load(memory_order = memory_order_seq_cst) const;
    193 
    194       _Tp
    195       load(memory_order = memory_order_seq_cst) const volatile;
    196 
    197       _Tp
    198       exchange(_Tp __i, memory_order = memory_order_seq_cst);
    199 
    200       _Tp
    201       exchange(_Tp __i, memory_order = memory_order_seq_cst) volatile;
    202 
    203       bool
    204       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order);
    205 
    206       bool
    207       compare_exchange_weak(_Tp&, _Tp, memory_order, memory_order) volatile;
    208 
    209       bool
    210       compare_exchange_weak(_Tp&, _Tp, memory_order = memory_order_seq_cst);
    211 
    212       bool
    213       compare_exchange_weak(_Tp&, _Tp,
    214 			    memory_order = memory_order_seq_cst) volatile;
    215 
    216       bool
    217       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order);
    218 
    219       bool
    220       compare_exchange_strong(_Tp&, _Tp, memory_order, memory_order) volatile;
    221 
    222       bool
    223       compare_exchange_strong(_Tp&, _Tp, memory_order = memory_order_seq_cst);
    224 
    225       bool
    226       compare_exchange_strong(_Tp&, _Tp,
    227 			      memory_order = memory_order_seq_cst) volatile;
    228     };
    229 
    230 
    231   /// Partial specialization for pointer types.
    232   template<typename _Tp>
    233     struct atomic<_Tp*>
    234     {
    235       typedef _Tp* 			__pointer_type;
    236       typedef __atomic_base<_Tp*>	__base_type;
    237       __base_type			_M_b;
    238 
    239       atomic() = default;
    240       ~atomic() = default;
    241       atomic(const atomic&) = delete;
    242       atomic& operator=(const atomic&) = delete;
    243       atomic& operator=(const atomic&) volatile = delete;
    244 
    245       constexpr atomic(__pointer_type __p) : _M_b(__p) { }
    246 
    247       operator __pointer_type() const
    248       { return __pointer_type(_M_b); }
    249 
    250       operator __pointer_type() const volatile
    251       { return __pointer_type(_M_b); }
    252 
    253       __pointer_type
    254       operator=(__pointer_type __p)
    255       { return _M_b.operator=(__p); }
    256 
    257       __pointer_type
    258       operator=(__pointer_type __p) volatile
    259       { return _M_b.operator=(__p); }
    260 
    261       __pointer_type
    262       operator++(int)
    263       { return _M_b++; }
    264 
    265       __pointer_type
    266       operator++(int) volatile
    267       { return _M_b++; }
    268 
    269       __pointer_type
    270       operator--(int)
    271       { return _M_b--; }
    272 
    273       __pointer_type
    274       operator--(int) volatile
    275       { return _M_b--; }
    276 
    277       __pointer_type
    278       operator++()
    279       { return ++_M_b; }
    280 
    281       __pointer_type
    282       operator++() volatile
    283       { return ++_M_b; }
    284 
    285       __pointer_type
    286       operator--()
    287       { return --_M_b; }
    288 
    289       __pointer_type
    290       operator--() volatile
    291       { return --_M_b; }
    292 
    293       __pointer_type
    294       operator+=(ptrdiff_t __d)
    295       { return _M_b.operator+=(__d); }
    296 
    297       __pointer_type
    298       operator+=(ptrdiff_t __d) volatile
    299       { return _M_b.operator+=(__d); }
    300 
    301       __pointer_type
    302       operator-=(ptrdiff_t __d)
    303       { return _M_b.operator-=(__d); }
    304 
    305       __pointer_type
    306       operator-=(ptrdiff_t __d) volatile
    307       { return _M_b.operator-=(__d); }
    308 
    309       bool
    310       is_lock_free() const
    311       { return _M_b.is_lock_free(); }
    312 
    313       bool
    314       is_lock_free() const volatile
    315       { return _M_b.is_lock_free(); }
    316 
    317       void
    318       store(__pointer_type __p, memory_order __m = memory_order_seq_cst)
    319       { return _M_b.store(__p, __m); }
    320 
    321       void
    322       store(__pointer_type __p,
    323 	    memory_order __m = memory_order_seq_cst) volatile
    324       { return _M_b.store(__p, __m); }
    325 
    326       __pointer_type
    327       load(memory_order __m = memory_order_seq_cst) const
    328       { return _M_b.load(__m); }
    329 
    330       __pointer_type
    331       load(memory_order __m = memory_order_seq_cst) const volatile
    332       { return _M_b.load(__m); }
    333 
    334       __pointer_type
    335       exchange(__pointer_type __p, memory_order __m = memory_order_seq_cst)
    336       { return _M_b.exchange(__p, __m); }
    337 
    338       __pointer_type
    339       exchange(__pointer_type __p,
    340 	       memory_order __m = memory_order_seq_cst) volatile
    341       { return _M_b.exchange(__p, __m); }
    342 
    343       bool
    344       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    345 			    memory_order __m1, memory_order __m2)
    346       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    347 
    348       bool
    349       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    350 			    memory_order __m1, memory_order __m2) volatile
    351       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    352 
    353       bool
    354       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    355 			    memory_order __m = memory_order_seq_cst)
    356       {
    357 	return compare_exchange_weak(__p1, __p2, __m,
    358 				     __calculate_memory_order(__m));
    359       }
    360 
    361       bool
    362       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    363 			    memory_order __m = memory_order_seq_cst) volatile
    364       {
    365 	return compare_exchange_weak(__p1, __p2, __m,
    366 				     __calculate_memory_order(__m));
    367       }
    368 
    369       bool
    370       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    371 			      memory_order __m1, memory_order __m2)
    372       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    373 
    374       bool
    375       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    376 			      memory_order __m1, memory_order __m2) volatile
    377       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    378 
    379       bool
    380       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    381 			      memory_order __m = memory_order_seq_cst)
    382       {
    383 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    384 					    __calculate_memory_order(__m));
    385       }
    386 
    387       bool
    388       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    389 			      memory_order __m = memory_order_seq_cst) volatile
    390       {
    391 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    392 					    __calculate_memory_order(__m));
    393       }
    394 
    395       __pointer_type
    396       fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
    397       { return _M_b.fetch_add(__d, __m); }
    398 
    399       __pointer_type
    400       fetch_add(ptrdiff_t __d,
    401 		memory_order __m = memory_order_seq_cst) volatile
    402       { return _M_b.fetch_add(__d, __m); }
    403 
    404       __pointer_type
    405       fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst)
    406       { return _M_b.fetch_sub(__d, __m); }
    407 
    408       __pointer_type
    409       fetch_sub(ptrdiff_t __d,
    410 		memory_order __m = memory_order_seq_cst) volatile
    411       { return _M_b.fetch_sub(__d, __m); }
    412     };
    413 
    414 
    415   /// Explicit specialization for bool.
    416   template<>
    417     struct atomic<bool> : public atomic_bool
    418     {
    419       typedef bool 			__integral_type;
    420       typedef atomic_bool 		__base_type;
    421 
    422       atomic() = default;
    423       ~atomic() = default;
    424       atomic(const atomic&) = delete;
    425       atomic& operator=(const atomic&) = delete;
    426       atomic& operator=(const atomic&) volatile = delete;
    427 
    428       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    429 
    430       using __base_type::operator __integral_type;
    431       using __base_type::operator=;
    432     };
    433 
    434   /// Explicit specialization for char.
    435   template<>
    436     struct atomic<char> : public atomic_char
    437     {
    438       typedef char 			__integral_type;
    439       typedef atomic_char 		__base_type;
    440 
    441       atomic() = default;
    442       ~atomic() = default;
    443       atomic(const atomic&) = delete;
    444       atomic& operator=(const atomic&) = delete;
    445       atomic& operator=(const atomic&) volatile = delete;
    446 
    447       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    448 
    449       using __base_type::operator __integral_type;
    450       using __base_type::operator=;
    451     };
    452 
    453   /// Explicit specialization for signed char.
    454   template<>
    455     struct atomic<signed char> : public atomic_schar
    456     {
    457       typedef signed char 		__integral_type;
    458       typedef atomic_schar 		__base_type;
    459 
    460       atomic() = default;
    461       ~atomic() = default;
    462       atomic(const atomic&) = delete;
    463       atomic& operator=(const atomic&) = delete;
    464       atomic& operator=(const atomic&) volatile = delete;
    465 
    466       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    467 
    468       using __base_type::operator __integral_type;
    469       using __base_type::operator=;
    470     };
    471 
    472   /// Explicit specialization for unsigned char.
    473   template<>
    474     struct atomic<unsigned char> : public atomic_uchar
    475     {
    476       typedef unsigned char 		__integral_type;
    477       typedef atomic_uchar 		__base_type;
    478 
    479       atomic() = default;
    480       ~atomic() = default;
    481       atomic(const atomic&) = delete;
    482       atomic& operator=(const atomic&) = delete;
    483       atomic& operator=(const atomic&) volatile = delete;
    484 
    485       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    486 
    487       using __base_type::operator __integral_type;
    488       using __base_type::operator=;
    489     };
    490 
    491   /// Explicit specialization for short.
    492   template<>
    493     struct atomic<short> : public atomic_short
    494     {
    495       typedef short 			__integral_type;
    496       typedef atomic_short 		__base_type;
    497 
    498       atomic() = default;
    499       ~atomic() = default;
    500       atomic(const atomic&) = delete;
    501       atomic& operator=(const atomic&) = delete;
    502       atomic& operator=(const atomic&) volatile = delete;
    503 
    504       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    505 
    506       using __base_type::operator __integral_type;
    507       using __base_type::operator=;
    508     };
    509 
    510   /// Explicit specialization for unsigned short.
    511   template<>
    512     struct atomic<unsigned short> : public atomic_ushort
    513     {
    514       typedef unsigned short 	      	__integral_type;
    515       typedef atomic_ushort 		__base_type;
    516 
    517       atomic() = default;
    518       ~atomic() = default;
    519       atomic(const atomic&) = delete;
    520       atomic& operator=(const atomic&) = delete;
    521       atomic& operator=(const atomic&) volatile = delete;
    522 
    523       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    524 
    525       using __base_type::operator __integral_type;
    526       using __base_type::operator=;
    527     };
    528 
    529   /// Explicit specialization for int.
    530   template<>
    531     struct atomic<int> : atomic_int
    532     {
    533       typedef int 			__integral_type;
    534       typedef atomic_int 		__base_type;
    535 
    536       atomic() = default;
    537       ~atomic() = default;
    538       atomic(const atomic&) = delete;
    539       atomic& operator=(const atomic&) = delete;
    540       atomic& operator=(const atomic&) volatile = delete;
    541 
    542       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    543 
    544       using __base_type::operator __integral_type;
    545       using __base_type::operator=;
    546     };
    547 
    548   /// Explicit specialization for unsigned int.
    549   template<>
    550     struct atomic<unsigned int> : public atomic_uint
    551     {
    552       typedef unsigned int		__integral_type;
    553       typedef atomic_uint 		__base_type;
    554 
    555       atomic() = default;
    556       ~atomic() = default;
    557       atomic(const atomic&) = delete;
    558       atomic& operator=(const atomic&) = delete;
    559       atomic& operator=(const atomic&) volatile = delete;
    560 
    561       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    562 
    563       using __base_type::operator __integral_type;
    564       using __base_type::operator=;
    565     };
    566 
    567   /// Explicit specialization for long.
    568   template<>
    569     struct atomic<long> : public atomic_long
    570     {
    571       typedef long 			__integral_type;
    572       typedef atomic_long 		__base_type;
    573 
    574       atomic() = default;
    575       ~atomic() = default;
    576       atomic(const atomic&) = delete;
    577       atomic& operator=(const atomic&) = delete;
    578       atomic& operator=(const atomic&) volatile = delete;
    579 
    580       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    581 
    582       using __base_type::operator __integral_type;
    583       using __base_type::operator=;
    584     };
    585 
    586   /// Explicit specialization for unsigned long.
    587   template<>
    588     struct atomic<unsigned long> : public atomic_ulong
    589     {
    590       typedef unsigned long 		__integral_type;
    591       typedef atomic_ulong 		__base_type;
    592 
    593       atomic() = default;
    594       ~atomic() = default;
    595       atomic(const atomic&) = delete;
    596       atomic& operator=(const atomic&) = delete;
    597       atomic& operator=(const atomic&) volatile = delete;
    598 
    599       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    600 
    601       using __base_type::operator __integral_type;
    602       using __base_type::operator=;
    603     };
    604 
    605   /// Explicit specialization for long long.
    606   template<>
    607     struct atomic<long long> : public atomic_llong
    608     {
    609       typedef long long 		__integral_type;
    610       typedef atomic_llong 		__base_type;
    611 
    612       atomic() = default;
    613       ~atomic() = default;
    614       atomic(const atomic&) = delete;
    615       atomic& operator=(const atomic&) = delete;
    616       atomic& operator=(const atomic&) volatile = delete;
    617 
    618       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    619 
    620       using __base_type::operator __integral_type;
    621       using __base_type::operator=;
    622     };
    623 
    624   /// Explicit specialization for unsigned long long.
    625   template<>
    626     struct atomic<unsigned long long> : public atomic_ullong
    627     {
    628       typedef unsigned long long       	__integral_type;
    629       typedef atomic_ullong 		__base_type;
    630 
    631       atomic() = default;
    632       ~atomic() = default;
    633       atomic(const atomic&) = delete;
    634       atomic& operator=(const atomic&) = delete;
    635       atomic& operator=(const atomic&) volatile = delete;
    636 
    637       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    638 
    639       using __base_type::operator __integral_type;
    640       using __base_type::operator=;
    641     };
    642 
    643   /// Explicit specialization for wchar_t.
    644   template<>
    645     struct atomic<wchar_t> : public atomic_wchar_t
    646     {
    647       typedef wchar_t 			__integral_type;
    648       typedef atomic_wchar_t 		__base_type;
    649 
    650       atomic() = default;
    651       ~atomic() = default;
    652       atomic(const atomic&) = delete;
    653       atomic& operator=(const atomic&) = delete;
    654       atomic& operator=(const atomic&) volatile = delete;
    655 
    656       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    657 
    658       using __base_type::operator __integral_type;
    659       using __base_type::operator=;
    660     };
    661 
    662   /// Explicit specialization for char16_t.
    663   template<>
    664     struct atomic<char16_t> : public atomic_char16_t
    665     {
    666       typedef char16_t 			__integral_type;
    667       typedef atomic_char16_t 		__base_type;
    668 
    669       atomic() = default;
    670       ~atomic() = default;
    671       atomic(const atomic&) = delete;
    672       atomic& operator=(const atomic&) = delete;
    673       atomic& operator=(const atomic&) volatile = delete;
    674 
    675       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    676 
    677       using __base_type::operator __integral_type;
    678       using __base_type::operator=;
    679     };
    680 
    681   /// Explicit specialization for char32_t.
    682   template<>
    683     struct atomic<char32_t> : public atomic_char32_t
    684     {
    685       typedef char32_t 			__integral_type;
    686       typedef atomic_char32_t 		__base_type;
    687 
    688       atomic() = default;
    689       ~atomic() = default;
    690       atomic(const atomic&) = delete;
    691       atomic& operator=(const atomic&) = delete;
    692       atomic& operator=(const atomic&) volatile = delete;
    693 
    694       constexpr atomic(__integral_type __i) : __base_type(__i) { }
    695 
    696       using __base_type::operator __integral_type;
    697       using __base_type::operator=;
    698     };
    699 
    700 
    701   // Function definitions, atomic_flag operations.
    702   inline bool
    703   atomic_flag_test_and_set_explicit(atomic_flag* __a, memory_order __m)
    704   { return __a->test_and_set(__m); }
    705 
    706   inline bool
    707   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
    708 				    memory_order __m)
    709   { return __a->test_and_set(__m); }
    710 
    711   inline void
    712   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m)
    713   { __a->clear(__m); }
    714 
    715   inline void
    716   atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __m)
    717   { __a->clear(__m); }
    718 
    719   inline bool
    720   atomic_flag_test_and_set(atomic_flag* __a)
    721   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
    722 
    723   inline bool
    724   atomic_flag_test_and_set(volatile atomic_flag* __a)
    725   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
    726 
    727   inline void
    728   atomic_flag_clear(atomic_flag* __a)
    729   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
    730 
    731   inline void
    732   atomic_flag_clear(volatile atomic_flag* __a)
    733   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
    734 
    735 
    736   // Function templates generally applicable to atomic types.
    737   template<typename _ITp>
    738     inline bool
    739     atomic_is_lock_free(const atomic<_ITp>* __a)
    740     { return __a->is_lock_free(); }
    741 
    742   template<typename _ITp>
    743     inline bool
    744     atomic_is_lock_free(const volatile atomic<_ITp>* __a)
    745     { return __a->is_lock_free(); }
    746 
    747   template<typename _ITp>
    748     inline void
    749     atomic_init(atomic<_ITp>* __a, _ITp __i);
    750 
    751   template<typename _ITp>
    752     inline void
    753     atomic_init(volatile atomic<_ITp>* __a, _ITp __i);
    754 
    755   template<typename _ITp>
    756     inline void
    757     atomic_store_explicit(atomic<_ITp>* __a, _ITp __i, memory_order __m)
    758     { __a->store(__i, __m); }
    759 
    760   template<typename _ITp>
    761     inline void
    762     atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
    763 			  memory_order __m)
    764     { __a->store(__i, __m); }
    765 
    766   template<typename _ITp>
    767     inline _ITp
    768     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m)
    769     { return __a->load(__m); }
    770 
    771   template<typename _ITp>
    772     inline _ITp
    773     atomic_load_explicit(const volatile atomic<_ITp>* __a,
    774 			 memory_order __m)
    775     { return __a->load(__m); }
    776 
    777   template<typename _ITp>
    778     inline _ITp
    779     atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
    780 			     memory_order __m)
    781     { return __a->exchange(__i, __m); }
    782 
    783   template<typename _ITp>
    784     inline _ITp
    785     atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
    786 			     memory_order __m)
    787     { return __a->exchange(__i, __m); }
    788 
    789   template<typename _ITp>
    790     inline bool
    791     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
    792 					  _ITp* __i1, _ITp __i2,
    793 					  memory_order __m1, memory_order __m2)
    794     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
    795 
    796   template<typename _ITp>
    797     inline bool
    798     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
    799 					  _ITp* __i1, _ITp __i2,
    800 					  memory_order __m1, memory_order __m2)
    801     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
    802 
    803   template<typename _ITp>
    804     inline bool
    805     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
    806 					    _ITp* __i1, _ITp __i2,
    807 					    memory_order __m1,
    808 					    memory_order __m2)
    809     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
    810 
    811   template<typename _ITp>
    812     inline bool
    813     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
    814 					    _ITp* __i1, _ITp __i2,
    815 					    memory_order __m1,
    816 					    memory_order __m2)
    817     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
    818 
    819 
    820   template<typename _ITp>
    821     inline void
    822     atomic_store(atomic<_ITp>* __a, _ITp __i)
    823     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
    824 
    825   template<typename _ITp>
    826     inline void
    827     atomic_store(volatile atomic<_ITp>* __a, _ITp __i)
    828     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
    829 
    830   template<typename _ITp>
    831     inline _ITp
    832     atomic_load(const atomic<_ITp>* __a)
    833     { return atomic_load_explicit(__a, memory_order_seq_cst); }
    834 
    835   template<typename _ITp>
    836     inline _ITp
    837     atomic_load(const volatile atomic<_ITp>* __a)
    838     { return atomic_load_explicit(__a, memory_order_seq_cst); }
    839 
    840   template<typename _ITp>
    841     inline _ITp
    842     atomic_exchange(atomic<_ITp>* __a, _ITp __i)
    843     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
    844 
    845   template<typename _ITp>
    846     inline _ITp
    847     atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i)
    848     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
    849 
    850   template<typename _ITp>
    851     inline bool
    852     atomic_compare_exchange_weak(atomic<_ITp>* __a,
    853 				 _ITp* __i1, _ITp __i2)
    854     {
    855       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
    856 						   memory_order_seq_cst,
    857 						   memory_order_seq_cst);
    858     }
    859 
    860   template<typename _ITp>
    861     inline bool
    862     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
    863 				 _ITp* __i1, _ITp __i2)
    864     {
    865       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
    866 						   memory_order_seq_cst,
    867 						   memory_order_seq_cst);
    868     }
    869 
    870   template<typename _ITp>
    871     inline bool
    872     atomic_compare_exchange_strong(atomic<_ITp>* __a,
    873 				   _ITp* __i1, _ITp __i2)
    874     {
    875       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
    876 						     memory_order_seq_cst,
    877 						     memory_order_seq_cst);
    878     }
    879 
    880   template<typename _ITp>
    881     inline bool
    882     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
    883 				   _ITp* __i1, _ITp __i2)
    884     {
    885       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
    886 						     memory_order_seq_cst,
    887 						     memory_order_seq_cst);
    888     }
    889 
    890   // Function templates for atomic_integral operations only, using
    891   // __atomic_base. Template argument should be constricted to
    892   // intergral types as specified in the standard, excluding address
    893   // types.
    894   template<typename _ITp>
    895     inline _ITp
    896     atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    897 			      memory_order __m)
    898     { return __a->fetch_add(__i, __m); }
    899 
    900   template<typename _ITp>
    901     inline _ITp
    902     atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    903 			      memory_order __m)
    904     { return __a->fetch_add(__i, __m); }
    905 
    906   template<typename _ITp>
    907     inline _ITp
    908     atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    909 			      memory_order __m)
    910     { return __a->fetch_sub(__i, __m); }
    911 
    912   template<typename _ITp>
    913     inline _ITp
    914     atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    915 			      memory_order __m)
    916     { return __a->fetch_sub(__i, __m); }
    917 
    918   template<typename _ITp>
    919     inline _ITp
    920     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    921 			      memory_order __m)
    922     { return __a->fetch_and(__i, __m); }
    923 
    924   template<typename _ITp>
    925     inline _ITp
    926     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    927 			      memory_order __m)
    928     { return __a->fetch_and(__i, __m); }
    929 
    930   template<typename _ITp>
    931     inline _ITp
    932     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    933 			     memory_order __m)
    934     { return __a->fetch_or(__i, __m); }
    935 
    936   template<typename _ITp>
    937     inline _ITp
    938     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    939 			     memory_order __m)
    940     { return __a->fetch_or(__i, __m); }
    941 
    942   template<typename _ITp>
    943     inline _ITp
    944     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
    945 			      memory_order __m)
    946     { return __a->fetch_xor(__i, __m); }
    947 
    948   template<typename _ITp>
    949     inline _ITp
    950     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
    951 			      memory_order __m)
    952     { return __a->fetch_xor(__i, __m); }
    953 
    954   template<typename _ITp>
    955     inline _ITp
    956     atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i)
    957     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
    958 
    959   template<typename _ITp>
    960     inline _ITp
    961     atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i)
    962     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
    963 
    964   template<typename _ITp>
    965     inline _ITp
    966     atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i)
    967     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
    968 
    969   template<typename _ITp>
    970     inline _ITp
    971     atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i)
    972     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
    973 
    974   template<typename _ITp>
    975     inline _ITp
    976     atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i)
    977     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
    978 
    979   template<typename _ITp>
    980     inline _ITp
    981     atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i)
    982     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
    983 
    984   template<typename _ITp>
    985     inline _ITp
    986     atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i)
    987     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
    988 
    989   template<typename _ITp>
    990     inline _ITp
    991     atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i)
    992     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
    993 
    994   template<typename _ITp>
    995     inline _ITp
    996     atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i)
    997     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
    998 
    999   template<typename _ITp>
   1000     inline _ITp
   1001     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i)
   1002     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
   1003 
   1004 
   1005   // Partial specializations for pointers.
   1006   template<typename _ITp>
   1007     inline _ITp*
   1008     atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
   1009 			      memory_order __m)
   1010     { return __a->fetch_add(__d, __m); }
   1011 
   1012   template<typename _ITp>
   1013     inline _ITp*
   1014     atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
   1015 			      memory_order __m)
   1016     { return __a->fetch_add(__d, __m); }
   1017 
   1018   template<typename _ITp>
   1019     inline _ITp*
   1020     atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
   1021     { return __a->fetch_add(__d); }
   1022 
   1023   template<typename _ITp>
   1024     inline _ITp*
   1025     atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d)
   1026     { return __a->fetch_add(__d); }
   1027 
   1028   template<typename _ITp>
   1029     inline _ITp*
   1030     atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
   1031 			      ptrdiff_t __d, memory_order __m)
   1032     { return __a->fetch_sub(__d, __m); }
   1033 
   1034   template<typename _ITp>
   1035     inline _ITp*
   1036     atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
   1037 			      memory_order __m)
   1038     { return __a->fetch_sub(__d, __m); }
   1039 
   1040   template<typename _ITp>
   1041     inline _ITp*
   1042     atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d)
   1043     { return __a->fetch_sub(__d); }
   1044 
   1045   template<typename _ITp>
   1046     inline _ITp*
   1047     atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d)
   1048     { return __a->fetch_sub(__d); }
   1049   // @} group atomics
   1050 
   1051 _GLIBCXX_END_NAMESPACE_VERSION
   1052 } // namespace
   1053 
   1054 #endif
   1055