Home | History | Annotate | Line # | Download | only in std
      1 // -*- C++ -*- header.
      2 
      3 // Copyright (C) 2008-2024 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 #if __cplusplus < 201103L
     38 # include <bits/c++0x_warning.h>
     39 #else
     40 
     41 #define __glibcxx_want_atomic_is_always_lock_free
     42 #define __glibcxx_want_atomic_flag_test
     43 #define __glibcxx_want_atomic_float
     44 #define __glibcxx_want_atomic_ref
     45 #define __glibcxx_want_atomic_lock_free_type_aliases
     46 #define __glibcxx_want_atomic_value_initialization
     47 #define __glibcxx_want_atomic_wait
     48 #include <bits/version.h>
     49 
     50 #include <bits/atomic_base.h>
     51 
     52 namespace std _GLIBCXX_VISIBILITY(default)
     53 {
     54 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     55 
     56   /**
     57    * @addtogroup atomics
     58    * @{
     59    */
     60 
     61   template<typename _Tp>
     62     struct atomic;
     63 
     64   /// atomic<bool>
     65   // NB: No operators or fetch-operations for this type.
     66   template<>
     67   struct atomic<bool>
     68   {
     69     using value_type = bool;
     70 
     71   private:
     72     __atomic_base<bool>	_M_base;
     73 
     74   public:
     75     atomic() noexcept = default;
     76     ~atomic() noexcept = default;
     77     atomic(const atomic&) = delete;
     78     atomic& operator=(const atomic&) = delete;
     79     atomic& operator=(const atomic&) volatile = delete;
     80 
     81     constexpr atomic(bool __i) noexcept : _M_base(__i) { }
     82 
     83     bool
     84     operator=(bool __i) noexcept
     85     { return _M_base.operator=(__i); }
     86 
     87     bool
     88     operator=(bool __i) volatile noexcept
     89     { return _M_base.operator=(__i); }
     90 
     91     operator bool() const noexcept
     92     { return _M_base.load(); }
     93 
     94     operator bool() const volatile noexcept
     95     { return _M_base.load(); }
     96 
     97     bool
     98     is_lock_free() const noexcept { return _M_base.is_lock_free(); }
     99 
    100     bool
    101     is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
    102 
    103 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    104     static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
    105 #endif
    106 
    107     void
    108     store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
    109     { _M_base.store(__i, __m); }
    110 
    111     void
    112     store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
    113     { _M_base.store(__i, __m); }
    114 
    115     bool
    116     load(memory_order __m = memory_order_seq_cst) const noexcept
    117     { return _M_base.load(__m); }
    118 
    119     bool
    120     load(memory_order __m = memory_order_seq_cst) const volatile noexcept
    121     { return _M_base.load(__m); }
    122 
    123     bool
    124     exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
    125     { return _M_base.exchange(__i, __m); }
    126 
    127     bool
    128     exchange(bool __i,
    129 	     memory_order __m = memory_order_seq_cst) volatile noexcept
    130     { return _M_base.exchange(__i, __m); }
    131 
    132     bool
    133     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    134 			  memory_order __m2) noexcept
    135     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    136 
    137     bool
    138     compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
    139 			  memory_order __m2) volatile noexcept
    140     { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
    141 
    142     bool
    143     compare_exchange_weak(bool& __i1, bool __i2,
    144 			  memory_order __m = memory_order_seq_cst) noexcept
    145     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    146 
    147     bool
    148     compare_exchange_weak(bool& __i1, bool __i2,
    149 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    150     { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
    151 
    152     bool
    153     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    154 			    memory_order __m2) noexcept
    155     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    156 
    157     bool
    158     compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
    159 			    memory_order __m2) volatile noexcept
    160     { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
    161 
    162     bool
    163     compare_exchange_strong(bool& __i1, bool __i2,
    164 			    memory_order __m = memory_order_seq_cst) noexcept
    165     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    166 
    167     bool
    168     compare_exchange_strong(bool& __i1, bool __i2,
    169 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    170     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
    171 
    172 #if __cpp_lib_atomic_wait
    173     void
    174     wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
    175     { _M_base.wait(__old, __m); }
    176 
    177     // TODO add const volatile overload
    178 
    179     void
    180     notify_one() noexcept
    181     { _M_base.notify_one(); }
    182 
    183     void
    184     notify_all() noexcept
    185     { _M_base.notify_all(); }
    186 #endif // __cpp_lib_atomic_wait
    187   };
    188 
    189 /// @cond undocumented
    190 #if __cpp_lib_atomic_value_initialization
    191 # define _GLIBCXX20_INIT(I) = I
    192 #else
    193 # define _GLIBCXX20_INIT(I)
    194 #endif
    195 /// @endcond
    196 
    197   /**
    198    *  @brief Generic atomic type, primary class template.
    199    *
    200    *  @tparam _Tp  Type to be made atomic, must be trivially copyable.
    201    */
    202   template<typename _Tp>
    203     struct atomic
    204     {
    205       using value_type = _Tp;
    206 
    207     private:
    208       // Align 1/2/4/8/16-byte types to at least their size.
    209       static constexpr int _S_min_alignment
    210 	= (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
    211 	? 0 : sizeof(_Tp);
    212 
    213       static constexpr int _S_alignment
    214         = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
    215 
    216       alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
    217 
    218       static_assert(__is_trivially_copyable(_Tp),
    219 		    "std::atomic requires a trivially copyable type");
    220 
    221       static_assert(sizeof(_Tp) > 0,
    222 		    "Incomplete or zero-sized types are not supported");
    223 
    224 #if __cplusplus > 201703L
    225       static_assert(is_copy_constructible_v<_Tp>);
    226       static_assert(is_move_constructible_v<_Tp>);
    227       static_assert(is_copy_assignable_v<_Tp>);
    228       static_assert(is_move_assignable_v<_Tp>);
    229 #endif
    230 
    231     public:
    232       atomic() = default;
    233       ~atomic() noexcept = default;
    234       atomic(const atomic&) = delete;
    235       atomic& operator=(const atomic&) = delete;
    236       atomic& operator=(const atomic&) volatile = delete;
    237 
    238       constexpr atomic(_Tp __i) noexcept : _M_i(__i)
    239       {
    240 #if __cplusplus >= 201402L && __has_builtin(__builtin_clear_padding)
    241 	if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>())
    242 	  __builtin_clear_padding(std::__addressof(_M_i));
    243 #endif
    244       }
    245 
    246       operator _Tp() const noexcept
    247       { return load(); }
    248 
    249       operator _Tp() const volatile noexcept
    250       { return load(); }
    251 
    252       _Tp
    253       operator=(_Tp __i) noexcept
    254       { store(__i); return __i; }
    255 
    256       _Tp
    257       operator=(_Tp __i) volatile noexcept
    258       { store(__i); return __i; }
    259 
    260       bool
    261       is_lock_free() const noexcept
    262       {
    263 	// Produce a fake, minimally aligned pointer.
    264 	return __atomic_is_lock_free(sizeof(_M_i),
    265 	    reinterpret_cast<void *>(-_S_alignment));
    266       }
    267 
    268       bool
    269       is_lock_free() const volatile noexcept
    270       {
    271 	// Produce a fake, minimally aligned pointer.
    272 	return __atomic_is_lock_free(sizeof(_M_i),
    273 	    reinterpret_cast<void *>(-_S_alignment));
    274       }
    275 
    276 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    277       static constexpr bool is_always_lock_free
    278 	= __atomic_always_lock_free(sizeof(_M_i), 0);
    279 #endif
    280 
    281       void
    282       store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
    283       {
    284 	__atomic_store(std::__addressof(_M_i),
    285 		       __atomic_impl::__clear_padding(__i),
    286 		       int(__m));
    287       }
    288 
    289       void
    290       store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
    291       {
    292 	__atomic_store(std::__addressof(_M_i),
    293 		       __atomic_impl::__clear_padding(__i),
    294 		       int(__m));
    295       }
    296 
    297       _Tp
    298       load(memory_order __m = memory_order_seq_cst) const noexcept
    299       {
    300 	alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
    301 	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
    302 	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
    303 	return *__ptr;
    304       }
    305 
    306       _Tp
    307       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
    308       {
    309         alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
    310 	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
    311 	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
    312 	return *__ptr;
    313       }
    314 
    315       _Tp
    316       exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
    317       {
    318         alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
    319 	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
    320 	__atomic_exchange(std::__addressof(_M_i),
    321 			  __atomic_impl::__clear_padding(__i),
    322 			  __ptr, int(__m));
    323 	return *__ptr;
    324       }
    325 
    326       _Tp
    327       exchange(_Tp __i,
    328 	       memory_order __m = memory_order_seq_cst) volatile noexcept
    329       {
    330         alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
    331 	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
    332 	__atomic_exchange(std::__addressof(_M_i),
    333 			  __atomic_impl::__clear_padding(__i),
    334 			  __ptr, int(__m));
    335 	return *__ptr;
    336       }
    337 
    338       bool
    339       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
    340 			    memory_order __f) noexcept
    341       {
    342 	return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
    343 						 __s, __f);
    344       }
    345 
    346       bool
    347       compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
    348 			    memory_order __f) volatile noexcept
    349       {
    350 	return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
    351 						 __s, __f);
    352       }
    353 
    354       bool
    355       compare_exchange_weak(_Tp& __e, _Tp __i,
    356 			    memory_order __m = memory_order_seq_cst) noexcept
    357       { return compare_exchange_weak(__e, __i, __m,
    358                                      __cmpexch_failure_order(__m)); }
    359 
    360       bool
    361       compare_exchange_weak(_Tp& __e, _Tp __i,
    362 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    363       { return compare_exchange_weak(__e, __i, __m,
    364                                      __cmpexch_failure_order(__m)); }
    365 
    366       bool
    367       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
    368 			      memory_order __f) noexcept
    369       {
    370 	return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
    371 						 __s, __f);
    372       }
    373 
    374       bool
    375       compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
    376 			      memory_order __f) volatile noexcept
    377       {
    378 	return __atomic_impl::__compare_exchange(_M_i, __e, __i, false,
    379 						 __s, __f);
    380       }
    381 
    382       bool
    383       compare_exchange_strong(_Tp& __e, _Tp __i,
    384 			       memory_order __m = memory_order_seq_cst) noexcept
    385       { return compare_exchange_strong(__e, __i, __m,
    386                                        __cmpexch_failure_order(__m)); }
    387 
    388       bool
    389       compare_exchange_strong(_Tp& __e, _Tp __i,
    390 		     memory_order __m = memory_order_seq_cst) volatile noexcept
    391       { return compare_exchange_strong(__e, __i, __m,
    392                                        __cmpexch_failure_order(__m)); }
    393 
    394 #if __cpp_lib_atomic_wait // C++ >= 20
    395       void
    396       wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
    397       {
    398 	std::__atomic_wait_address_v(&_M_i, __old,
    399 			   [__m, this] { return this->load(__m); });
    400       }
    401 
    402       // TODO add const volatile overload
    403 
    404       void
    405       notify_one() noexcept
    406       { std::__atomic_notify_address(&_M_i, false); }
    407 
    408       void
    409       notify_all() noexcept
    410       { std::__atomic_notify_address(&_M_i, true); }
    411 #endif // __cpp_lib_atomic_wait
    412 
    413     };
    414 #undef _GLIBCXX20_INIT
    415 
    416   /// Partial specialization for pointer types.
    417   template<typename _Tp>
    418     struct atomic<_Tp*>
    419     {
    420       using value_type = _Tp*;
    421       using difference_type = ptrdiff_t;
    422 
    423       typedef _Tp* 			__pointer_type;
    424       typedef __atomic_base<_Tp*>	__base_type;
    425       __base_type			_M_b;
    426 
    427       atomic() noexcept = default;
    428       ~atomic() noexcept = default;
    429       atomic(const atomic&) = delete;
    430       atomic& operator=(const atomic&) = delete;
    431       atomic& operator=(const atomic&) volatile = delete;
    432 
    433       constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
    434 
    435       operator __pointer_type() const noexcept
    436       { return __pointer_type(_M_b); }
    437 
    438       operator __pointer_type() const volatile noexcept
    439       { return __pointer_type(_M_b); }
    440 
    441       __pointer_type
    442       operator=(__pointer_type __p) noexcept
    443       { return _M_b.operator=(__p); }
    444 
    445       __pointer_type
    446       operator=(__pointer_type __p) volatile noexcept
    447       { return _M_b.operator=(__p); }
    448 
    449       __pointer_type
    450       operator++(int) noexcept
    451       {
    452 #if __cplusplus >= 201703L
    453 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    454 #endif
    455 	return _M_b++;
    456       }
    457 
    458       __pointer_type
    459       operator++(int) volatile noexcept
    460       {
    461 #if __cplusplus >= 201703L
    462 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    463 #endif
    464 	return _M_b++;
    465       }
    466 
    467       __pointer_type
    468       operator--(int) noexcept
    469       {
    470 #if __cplusplus >= 201703L
    471 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    472 #endif
    473 	return _M_b--;
    474       }
    475 
    476       __pointer_type
    477       operator--(int) volatile noexcept
    478       {
    479 #if __cplusplus >= 201703L
    480 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    481 #endif
    482 	return _M_b--;
    483       }
    484 
    485       __pointer_type
    486       operator++() noexcept
    487       {
    488 #if __cplusplus >= 201703L
    489 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    490 #endif
    491 	return ++_M_b;
    492       }
    493 
    494       __pointer_type
    495       operator++() volatile noexcept
    496       {
    497 #if __cplusplus >= 201703L
    498 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    499 #endif
    500 	return ++_M_b;
    501       }
    502 
    503       __pointer_type
    504       operator--() noexcept
    505       {
    506 #if __cplusplus >= 201703L
    507 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    508 #endif
    509 	return --_M_b;
    510       }
    511 
    512       __pointer_type
    513       operator--() volatile noexcept
    514       {
    515 #if __cplusplus >= 201703L
    516 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    517 #endif
    518 	return --_M_b;
    519       }
    520 
    521       __pointer_type
    522       operator+=(ptrdiff_t __d) noexcept
    523       {
    524 #if __cplusplus >= 201703L
    525 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    526 #endif
    527 	return _M_b.operator+=(__d);
    528       }
    529 
    530       __pointer_type
    531       operator+=(ptrdiff_t __d) volatile noexcept
    532       {
    533 #if __cplusplus >= 201703L
    534 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    535 #endif
    536 	return _M_b.operator+=(__d);
    537       }
    538 
    539       __pointer_type
    540       operator-=(ptrdiff_t __d) noexcept
    541       {
    542 #if __cplusplus >= 201703L
    543 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    544 #endif
    545 	return _M_b.operator-=(__d);
    546       }
    547 
    548       __pointer_type
    549       operator-=(ptrdiff_t __d) volatile noexcept
    550       {
    551 #if __cplusplus >= 201703L
    552 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    553 #endif
    554 	return _M_b.operator-=(__d);
    555       }
    556 
    557       bool
    558       is_lock_free() const noexcept
    559       { return _M_b.is_lock_free(); }
    560 
    561       bool
    562       is_lock_free() const volatile noexcept
    563       { return _M_b.is_lock_free(); }
    564 
    565 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    566       static constexpr bool is_always_lock_free
    567 	= ATOMIC_POINTER_LOCK_FREE == 2;
    568 #endif
    569 
    570       void
    571       store(__pointer_type __p,
    572 	    memory_order __m = memory_order_seq_cst) noexcept
    573       { return _M_b.store(__p, __m); }
    574 
    575       void
    576       store(__pointer_type __p,
    577 	    memory_order __m = memory_order_seq_cst) volatile noexcept
    578       { return _M_b.store(__p, __m); }
    579 
    580       __pointer_type
    581       load(memory_order __m = memory_order_seq_cst) const noexcept
    582       { return _M_b.load(__m); }
    583 
    584       __pointer_type
    585       load(memory_order __m = memory_order_seq_cst) const volatile noexcept
    586       { return _M_b.load(__m); }
    587 
    588       __pointer_type
    589       exchange(__pointer_type __p,
    590 	       memory_order __m = memory_order_seq_cst) noexcept
    591       { return _M_b.exchange(__p, __m); }
    592 
    593       __pointer_type
    594       exchange(__pointer_type __p,
    595 	       memory_order __m = memory_order_seq_cst) volatile noexcept
    596       { return _M_b.exchange(__p, __m); }
    597 
    598       bool
    599       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    600 			    memory_order __m1, memory_order __m2) noexcept
    601       { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
    602 
    603       bool
    604       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    605 			    memory_order __m1,
    606 			    memory_order __m2) volatile noexcept
    607       { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
    608 
    609       bool
    610       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    611 			    memory_order __m = memory_order_seq_cst) noexcept
    612       {
    613 	return compare_exchange_weak(__p1, __p2, __m,
    614 				     __cmpexch_failure_order(__m));
    615       }
    616 
    617       bool
    618       compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
    619 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    620       {
    621 	return compare_exchange_weak(__p1, __p2, __m,
    622 				     __cmpexch_failure_order(__m));
    623       }
    624 
    625       bool
    626       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    627 			      memory_order __m1, memory_order __m2) noexcept
    628       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    629 
    630       bool
    631       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    632 			      memory_order __m1,
    633 			      memory_order __m2) volatile noexcept
    634       { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
    635 
    636       bool
    637       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    638 			      memory_order __m = memory_order_seq_cst) noexcept
    639       {
    640 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    641 					    __cmpexch_failure_order(__m));
    642       }
    643 
    644       bool
    645       compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
    646 		    memory_order __m = memory_order_seq_cst) volatile noexcept
    647       {
    648 	return _M_b.compare_exchange_strong(__p1, __p2, __m,
    649 					    __cmpexch_failure_order(__m));
    650       }
    651 
    652 #if __cpp_lib_atomic_wait
    653     void
    654     wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
    655     { _M_b.wait(__old, __m); }
    656 
    657     // TODO add const volatile overload
    658 
    659     void
    660     notify_one() noexcept
    661     { _M_b.notify_one(); }
    662 
    663     void
    664     notify_all() noexcept
    665     { _M_b.notify_all(); }
    666 #endif // __cpp_lib_atomic_wait
    667 
    668       __pointer_type
    669       fetch_add(ptrdiff_t __d,
    670 		memory_order __m = memory_order_seq_cst) noexcept
    671       {
    672 #if __cplusplus >= 201703L
    673 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    674 #endif
    675 	return _M_b.fetch_add(__d, __m);
    676       }
    677 
    678       __pointer_type
    679       fetch_add(ptrdiff_t __d,
    680 		memory_order __m = memory_order_seq_cst) volatile noexcept
    681       {
    682 #if __cplusplus >= 201703L
    683 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    684 #endif
    685 	return _M_b.fetch_add(__d, __m);
    686       }
    687 
    688       __pointer_type
    689       fetch_sub(ptrdiff_t __d,
    690 		memory_order __m = memory_order_seq_cst) noexcept
    691       {
    692 #if __cplusplus >= 201703L
    693 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    694 #endif
    695 	return _M_b.fetch_sub(__d, __m);
    696       }
    697 
    698       __pointer_type
    699       fetch_sub(ptrdiff_t __d,
    700 		memory_order __m = memory_order_seq_cst) volatile noexcept
    701       {
    702 #if __cplusplus >= 201703L
    703 	static_assert( is_object<_Tp>::value, "pointer to object type" );
    704 #endif
    705 	return _M_b.fetch_sub(__d, __m);
    706       }
    707     };
    708 
    709 
    710   /// Explicit specialization for char.
    711   template<>
    712     struct atomic<char> : __atomic_base<char>
    713     {
    714       typedef char 			__integral_type;
    715       typedef __atomic_base<char> 	__base_type;
    716 
    717       atomic() noexcept = default;
    718       ~atomic() noexcept = default;
    719       atomic(const atomic&) = delete;
    720       atomic& operator=(const atomic&) = delete;
    721       atomic& operator=(const atomic&) volatile = delete;
    722 
    723       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    724 
    725       using __base_type::operator __integral_type;
    726       using __base_type::operator=;
    727 
    728 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    729       static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
    730 #endif
    731     };
    732 
    733   /// Explicit specialization for signed char.
    734   template<>
    735     struct atomic<signed char> : __atomic_base<signed char>
    736     {
    737       typedef signed char 		__integral_type;
    738       typedef __atomic_base<signed char> 	__base_type;
    739 
    740       atomic() noexcept= default;
    741       ~atomic() noexcept = default;
    742       atomic(const atomic&) = delete;
    743       atomic& operator=(const atomic&) = delete;
    744       atomic& operator=(const atomic&) volatile = delete;
    745 
    746       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    747 
    748       using __base_type::operator __integral_type;
    749       using __base_type::operator=;
    750 
    751 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    752       static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
    753 #endif
    754     };
    755 
    756   /// Explicit specialization for unsigned char.
    757   template<>
    758     struct atomic<unsigned char> : __atomic_base<unsigned char>
    759     {
    760       typedef unsigned char 		__integral_type;
    761       typedef __atomic_base<unsigned char> 	__base_type;
    762 
    763       atomic() noexcept= default;
    764       ~atomic() noexcept = default;
    765       atomic(const atomic&) = delete;
    766       atomic& operator=(const atomic&) = delete;
    767       atomic& operator=(const atomic&) volatile = delete;
    768 
    769       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    770 
    771       using __base_type::operator __integral_type;
    772       using __base_type::operator=;
    773 
    774 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    775       static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
    776 #endif
    777     };
    778 
    779   /// Explicit specialization for short.
    780   template<>
    781     struct atomic<short> : __atomic_base<short>
    782     {
    783       typedef short 			__integral_type;
    784       typedef __atomic_base<short> 		__base_type;
    785 
    786       atomic() noexcept = default;
    787       ~atomic() noexcept = default;
    788       atomic(const atomic&) = delete;
    789       atomic& operator=(const atomic&) = delete;
    790       atomic& operator=(const atomic&) volatile = delete;
    791 
    792       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    793 
    794       using __base_type::operator __integral_type;
    795       using __base_type::operator=;
    796 
    797 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    798       static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
    799 #endif
    800     };
    801 
    802   /// Explicit specialization for unsigned short.
    803   template<>
    804     struct atomic<unsigned short> : __atomic_base<unsigned short>
    805     {
    806       typedef unsigned short 	      	__integral_type;
    807       typedef __atomic_base<unsigned short> 		__base_type;
    808 
    809       atomic() noexcept = default;
    810       ~atomic() noexcept = default;
    811       atomic(const atomic&) = delete;
    812       atomic& operator=(const atomic&) = delete;
    813       atomic& operator=(const atomic&) volatile = delete;
    814 
    815       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    816 
    817       using __base_type::operator __integral_type;
    818       using __base_type::operator=;
    819 
    820 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    821       static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
    822 #endif
    823     };
    824 
    825   /// Explicit specialization for int.
    826   template<>
    827     struct atomic<int> : __atomic_base<int>
    828     {
    829       typedef int 			__integral_type;
    830       typedef __atomic_base<int> 		__base_type;
    831 
    832       atomic() noexcept = default;
    833       ~atomic() noexcept = default;
    834       atomic(const atomic&) = delete;
    835       atomic& operator=(const atomic&) = delete;
    836       atomic& operator=(const atomic&) volatile = delete;
    837 
    838       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    839 
    840       using __base_type::operator __integral_type;
    841       using __base_type::operator=;
    842 
    843 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    844       static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
    845 #endif
    846     };
    847 
    848   /// Explicit specialization for unsigned int.
    849   template<>
    850     struct atomic<unsigned int> : __atomic_base<unsigned int>
    851     {
    852       typedef unsigned int		__integral_type;
    853       typedef __atomic_base<unsigned int> 	__base_type;
    854 
    855       atomic() noexcept = default;
    856       ~atomic() noexcept = default;
    857       atomic(const atomic&) = delete;
    858       atomic& operator=(const atomic&) = delete;
    859       atomic& operator=(const atomic&) volatile = delete;
    860 
    861       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    862 
    863       using __base_type::operator __integral_type;
    864       using __base_type::operator=;
    865 
    866 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    867       static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
    868 #endif
    869     };
    870 
    871   /// Explicit specialization for long.
    872   template<>
    873     struct atomic<long> : __atomic_base<long>
    874     {
    875       typedef long 			__integral_type;
    876       typedef __atomic_base<long> 	__base_type;
    877 
    878       atomic() noexcept = default;
    879       ~atomic() noexcept = default;
    880       atomic(const atomic&) = delete;
    881       atomic& operator=(const atomic&) = delete;
    882       atomic& operator=(const atomic&) volatile = delete;
    883 
    884       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    885 
    886       using __base_type::operator __integral_type;
    887       using __base_type::operator=;
    888 
    889 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    890       static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
    891 #endif
    892     };
    893 
    894   /// Explicit specialization for unsigned long.
    895   template<>
    896     struct atomic<unsigned long> : __atomic_base<unsigned long>
    897     {
    898       typedef unsigned long 		__integral_type;
    899       typedef __atomic_base<unsigned long> 	__base_type;
    900 
    901       atomic() noexcept = default;
    902       ~atomic() noexcept = default;
    903       atomic(const atomic&) = delete;
    904       atomic& operator=(const atomic&) = delete;
    905       atomic& operator=(const atomic&) volatile = delete;
    906 
    907       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    908 
    909       using __base_type::operator __integral_type;
    910       using __base_type::operator=;
    911 
    912 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    913       static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
    914 #endif
    915     };
    916 
    917   /// Explicit specialization for long long.
    918   template<>
    919     struct atomic<long long> : __atomic_base<long long>
    920     {
    921       typedef long long 		__integral_type;
    922       typedef __atomic_base<long long> 		__base_type;
    923 
    924       atomic() noexcept = default;
    925       ~atomic() noexcept = default;
    926       atomic(const atomic&) = delete;
    927       atomic& operator=(const atomic&) = delete;
    928       atomic& operator=(const atomic&) volatile = delete;
    929 
    930       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    931 
    932       using __base_type::operator __integral_type;
    933       using __base_type::operator=;
    934 
    935 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    936       static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
    937 #endif
    938     };
    939 
    940   /// Explicit specialization for unsigned long long.
    941   template<>
    942     struct atomic<unsigned long long> : __atomic_base<unsigned long long>
    943     {
    944       typedef unsigned long long       	__integral_type;
    945       typedef __atomic_base<unsigned long long> 	__base_type;
    946 
    947       atomic() noexcept = default;
    948       ~atomic() noexcept = default;
    949       atomic(const atomic&) = delete;
    950       atomic& operator=(const atomic&) = delete;
    951       atomic& operator=(const atomic&) volatile = delete;
    952 
    953       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    954 
    955       using __base_type::operator __integral_type;
    956       using __base_type::operator=;
    957 
    958 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    959       static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
    960 #endif
    961     };
    962 
    963   /// Explicit specialization for wchar_t.
    964   template<>
    965     struct atomic<wchar_t> : __atomic_base<wchar_t>
    966     {
    967       typedef wchar_t 			__integral_type;
    968       typedef __atomic_base<wchar_t> 	__base_type;
    969 
    970       atomic() noexcept = default;
    971       ~atomic() noexcept = default;
    972       atomic(const atomic&) = delete;
    973       atomic& operator=(const atomic&) = delete;
    974       atomic& operator=(const atomic&) volatile = delete;
    975 
    976       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
    977 
    978       using __base_type::operator __integral_type;
    979       using __base_type::operator=;
    980 
    981 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
    982       static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
    983 #endif
    984     };
    985 
    986 #ifdef _GLIBCXX_USE_CHAR8_T
    987   /// Explicit specialization for char8_t.
    988   template<>
    989     struct atomic<char8_t> : __atomic_base<char8_t>
    990     {
    991       typedef char8_t 			__integral_type;
    992       typedef __atomic_base<char8_t> 	__base_type;
    993 
    994       atomic() noexcept = default;
    995       ~atomic() noexcept = default;
    996       atomic(const atomic&) = delete;
    997       atomic& operator=(const atomic&) = delete;
    998       atomic& operator=(const atomic&) volatile = delete;
    999 
   1000       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
   1001 
   1002       using __base_type::operator __integral_type;
   1003       using __base_type::operator=;
   1004 
   1005 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
   1006       static constexpr bool is_always_lock_free
   1007 	= ATOMIC_CHAR8_T_LOCK_FREE == 2;
   1008 #endif
   1009     };
   1010 #endif
   1011 
   1012   /// Explicit specialization for char16_t.
   1013   template<>
   1014     struct atomic<char16_t> : __atomic_base<char16_t>
   1015     {
   1016       typedef char16_t 			__integral_type;
   1017       typedef __atomic_base<char16_t> 	__base_type;
   1018 
   1019       atomic() noexcept = default;
   1020       ~atomic() noexcept = default;
   1021       atomic(const atomic&) = delete;
   1022       atomic& operator=(const atomic&) = delete;
   1023       atomic& operator=(const atomic&) volatile = delete;
   1024 
   1025       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
   1026 
   1027       using __base_type::operator __integral_type;
   1028       using __base_type::operator=;
   1029 
   1030 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
   1031       static constexpr bool is_always_lock_free
   1032 	= ATOMIC_CHAR16_T_LOCK_FREE == 2;
   1033 #endif
   1034     };
   1035 
   1036   /// Explicit specialization for char32_t.
   1037   template<>
   1038     struct atomic<char32_t> : __atomic_base<char32_t>
   1039     {
   1040       typedef char32_t 			__integral_type;
   1041       typedef __atomic_base<char32_t> 	__base_type;
   1042 
   1043       atomic() noexcept = default;
   1044       ~atomic() noexcept = default;
   1045       atomic(const atomic&) = delete;
   1046       atomic& operator=(const atomic&) = delete;
   1047       atomic& operator=(const atomic&) volatile = delete;
   1048 
   1049       constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
   1050 
   1051       using __base_type::operator __integral_type;
   1052       using __base_type::operator=;
   1053 
   1054 #ifdef __cpp_lib_atomic_is_always_lock_free // C++ >= 17
   1055       static constexpr bool is_always_lock_free
   1056 	= ATOMIC_CHAR32_T_LOCK_FREE == 2;
   1057 #endif
   1058     };
   1059 
   1060 
   1061   /// atomic_bool
   1062   typedef atomic<bool>			atomic_bool;
   1063 
   1064   /// atomic_char
   1065   typedef atomic<char>			atomic_char;
   1066 
   1067   /// atomic_schar
   1068   typedef atomic<signed char>		atomic_schar;
   1069 
   1070   /// atomic_uchar
   1071   typedef atomic<unsigned char>		atomic_uchar;
   1072 
   1073   /// atomic_short
   1074   typedef atomic<short>			atomic_short;
   1075 
   1076   /// atomic_ushort
   1077   typedef atomic<unsigned short>	atomic_ushort;
   1078 
   1079   /// atomic_int
   1080   typedef atomic<int>			atomic_int;
   1081 
   1082   /// atomic_uint
   1083   typedef atomic<unsigned int>		atomic_uint;
   1084 
   1085   /// atomic_long
   1086   typedef atomic<long>			atomic_long;
   1087 
   1088   /// atomic_ulong
   1089   typedef atomic<unsigned long>		atomic_ulong;
   1090 
   1091   /// atomic_llong
   1092   typedef atomic<long long>		atomic_llong;
   1093 
   1094   /// atomic_ullong
   1095   typedef atomic<unsigned long long>	atomic_ullong;
   1096 
   1097   /// atomic_wchar_t
   1098   typedef atomic<wchar_t>		atomic_wchar_t;
   1099 
   1100 #ifdef _GLIBCXX_USE_CHAR8_T
   1101   /// atomic_char8_t
   1102   typedef atomic<char8_t>		atomic_char8_t;
   1103 #endif
   1104 
   1105   /// atomic_char16_t
   1106   typedef atomic<char16_t>		atomic_char16_t;
   1107 
   1108   /// atomic_char32_t
   1109   typedef atomic<char32_t>		atomic_char32_t;
   1110 
   1111 #ifdef _GLIBCXX_USE_C99_STDINT
   1112   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1113   // 2441. Exact-width atomic typedefs should be provided
   1114 
   1115   /// atomic_int8_t
   1116   typedef atomic<int8_t>		atomic_int8_t;
   1117 
   1118   /// atomic_uint8_t
   1119   typedef atomic<uint8_t>		atomic_uint8_t;
   1120 
   1121   /// atomic_int16_t
   1122   typedef atomic<int16_t>		atomic_int16_t;
   1123 
   1124   /// atomic_uint16_t
   1125   typedef atomic<uint16_t>		atomic_uint16_t;
   1126 
   1127   /// atomic_int32_t
   1128   typedef atomic<int32_t>		atomic_int32_t;
   1129 
   1130   /// atomic_uint32_t
   1131   typedef atomic<uint32_t>		atomic_uint32_t;
   1132 
   1133   /// atomic_int64_t
   1134   typedef atomic<int64_t>		atomic_int64_t;
   1135 
   1136   /// atomic_uint64_t
   1137   typedef atomic<uint64_t>		atomic_uint64_t;
   1138 #endif
   1139 
   1140   /// atomic_int_least8_t
   1141   typedef atomic<int_least8_t>		atomic_int_least8_t;
   1142 
   1143   /// atomic_uint_least8_t
   1144   typedef atomic<uint_least8_t>		atomic_uint_least8_t;
   1145 
   1146   /// atomic_int_least16_t
   1147   typedef atomic<int_least16_t>		atomic_int_least16_t;
   1148 
   1149   /// atomic_uint_least16_t
   1150   typedef atomic<uint_least16_t>	atomic_uint_least16_t;
   1151 
   1152   /// atomic_int_least32_t
   1153   typedef atomic<int_least32_t>		atomic_int_least32_t;
   1154 
   1155   /// atomic_uint_least32_t
   1156   typedef atomic<uint_least32_t>	atomic_uint_least32_t;
   1157 
   1158   /// atomic_int_least64_t
   1159   typedef atomic<int_least64_t>		atomic_int_least64_t;
   1160 
   1161   /// atomic_uint_least64_t
   1162   typedef atomic<uint_least64_t>	atomic_uint_least64_t;
   1163 
   1164 
   1165   /// atomic_int_fast8_t
   1166   typedef atomic<int_fast8_t>		atomic_int_fast8_t;
   1167 
   1168   /// atomic_uint_fast8_t
   1169   typedef atomic<uint_fast8_t>		atomic_uint_fast8_t;
   1170 
   1171   /// atomic_int_fast16_t
   1172   typedef atomic<int_fast16_t>		atomic_int_fast16_t;
   1173 
   1174   /// atomic_uint_fast16_t
   1175   typedef atomic<uint_fast16_t>		atomic_uint_fast16_t;
   1176 
   1177   /// atomic_int_fast32_t
   1178   typedef atomic<int_fast32_t>		atomic_int_fast32_t;
   1179 
   1180   /// atomic_uint_fast32_t
   1181   typedef atomic<uint_fast32_t>		atomic_uint_fast32_t;
   1182 
   1183   /// atomic_int_fast64_t
   1184   typedef atomic<int_fast64_t>		atomic_int_fast64_t;
   1185 
   1186   /// atomic_uint_fast64_t
   1187   typedef atomic<uint_fast64_t>		atomic_uint_fast64_t;
   1188 
   1189 
   1190   /// atomic_intptr_t
   1191   typedef atomic<intptr_t>		atomic_intptr_t;
   1192 
   1193   /// atomic_uintptr_t
   1194   typedef atomic<uintptr_t>		atomic_uintptr_t;
   1195 
   1196   /// atomic_size_t
   1197   typedef atomic<size_t>		atomic_size_t;
   1198 
   1199   /// atomic_ptrdiff_t
   1200   typedef atomic<ptrdiff_t>		atomic_ptrdiff_t;
   1201 
   1202   /// atomic_intmax_t
   1203   typedef atomic<intmax_t>		atomic_intmax_t;
   1204 
   1205   /// atomic_uintmax_t
   1206   typedef atomic<uintmax_t>		atomic_uintmax_t;
   1207 
   1208   // Function definitions, atomic_flag operations.
   1209   inline bool
   1210   atomic_flag_test_and_set_explicit(atomic_flag* __a,
   1211 				    memory_order __m) noexcept
   1212   { return __a->test_and_set(__m); }
   1213 
   1214   inline bool
   1215   atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
   1216 				    memory_order __m) noexcept
   1217   { return __a->test_and_set(__m); }
   1218 
   1219 #if __cpp_lib_atomic_flag_test
   1220   inline bool
   1221   atomic_flag_test(const atomic_flag* __a) noexcept
   1222   { return __a->test(); }
   1223 
   1224   inline bool
   1225   atomic_flag_test(const volatile atomic_flag* __a) noexcept
   1226   { return __a->test(); }
   1227 
   1228   inline bool
   1229   atomic_flag_test_explicit(const atomic_flag* __a,
   1230 			    memory_order __m) noexcept
   1231   { return __a->test(__m); }
   1232 
   1233   inline bool
   1234   atomic_flag_test_explicit(const volatile atomic_flag* __a,
   1235 			    memory_order __m) noexcept
   1236   { return __a->test(__m); }
   1237 #endif
   1238 
   1239   inline void
   1240   atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
   1241   { __a->clear(__m); }
   1242 
   1243   inline void
   1244   atomic_flag_clear_explicit(volatile atomic_flag* __a,
   1245 			     memory_order __m) noexcept
   1246   { __a->clear(__m); }
   1247 
   1248   inline bool
   1249   atomic_flag_test_and_set(atomic_flag* __a) noexcept
   1250   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
   1251 
   1252   inline bool
   1253   atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
   1254   { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
   1255 
   1256   inline void
   1257   atomic_flag_clear(atomic_flag* __a) noexcept
   1258   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
   1259 
   1260   inline void
   1261   atomic_flag_clear(volatile atomic_flag* __a) noexcept
   1262   { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
   1263 
   1264 #if __cpp_lib_atomic_wait
   1265   inline void
   1266   atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
   1267   { __a->wait(__old); }
   1268 
   1269   inline void
   1270   atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
   1271                                 memory_order __m) noexcept
   1272   { __a->wait(__old, __m); }
   1273 
   1274   inline void
   1275   atomic_flag_notify_one(atomic_flag* __a) noexcept
   1276   { __a->notify_one(); }
   1277 
   1278   inline void
   1279   atomic_flag_notify_all(atomic_flag* __a) noexcept
   1280   { __a->notify_all(); }
   1281 #endif // __cpp_lib_atomic_wait
   1282 
   1283   /// @cond undocumented
   1284   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   1285   // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
   1286   template<typename _Tp>
   1287     using __atomic_val_t = __type_identity_t<_Tp>;
   1288   template<typename _Tp>
   1289     using __atomic_diff_t = typename atomic<_Tp>::difference_type;
   1290   /// @endcond
   1291 
   1292   // [atomics.nonmembers] Non-member functions.
   1293   // Function templates generally applicable to atomic types.
   1294   template<typename _ITp>
   1295     inline bool
   1296     atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
   1297     { return __a->is_lock_free(); }
   1298 
   1299   template<typename _ITp>
   1300     inline bool
   1301     atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
   1302     { return __a->is_lock_free(); }
   1303 
   1304   template<typename _ITp>
   1305     inline void
   1306     atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
   1307     { __a->store(__i, memory_order_relaxed); }
   1308 
   1309   template<typename _ITp>
   1310     inline void
   1311     atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
   1312     { __a->store(__i, memory_order_relaxed); }
   1313 
   1314   template<typename _ITp>
   1315     inline void
   1316     atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
   1317 			  memory_order __m) noexcept
   1318     { __a->store(__i, __m); }
   1319 
   1320   template<typename _ITp>
   1321     inline void
   1322     atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
   1323 			  memory_order __m) noexcept
   1324     { __a->store(__i, __m); }
   1325 
   1326   template<typename _ITp>
   1327     inline _ITp
   1328     atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
   1329     { return __a->load(__m); }
   1330 
   1331   template<typename _ITp>
   1332     inline _ITp
   1333     atomic_load_explicit(const volatile atomic<_ITp>* __a,
   1334 			 memory_order __m) noexcept
   1335     { return __a->load(__m); }
   1336 
   1337   template<typename _ITp>
   1338     inline _ITp
   1339     atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
   1340 			     memory_order __m) noexcept
   1341     { return __a->exchange(__i, __m); }
   1342 
   1343   template<typename _ITp>
   1344     inline _ITp
   1345     atomic_exchange_explicit(volatile atomic<_ITp>* __a,
   1346 			     __atomic_val_t<_ITp> __i,
   1347 			     memory_order __m) noexcept
   1348     { return __a->exchange(__i, __m); }
   1349 
   1350   template<typename _ITp>
   1351     inline bool
   1352     atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
   1353 					  __atomic_val_t<_ITp>* __i1,
   1354 					  __atomic_val_t<_ITp> __i2,
   1355 					  memory_order __m1,
   1356 					  memory_order __m2) noexcept
   1357     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
   1358 
   1359   template<typename _ITp>
   1360     inline bool
   1361     atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
   1362 					  __atomic_val_t<_ITp>* __i1,
   1363 					  __atomic_val_t<_ITp> __i2,
   1364 					  memory_order __m1,
   1365 					  memory_order __m2) noexcept
   1366     { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
   1367 
   1368   template<typename _ITp>
   1369     inline bool
   1370     atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
   1371 					    __atomic_val_t<_ITp>* __i1,
   1372 					    __atomic_val_t<_ITp> __i2,
   1373 					    memory_order __m1,
   1374 					    memory_order __m2) noexcept
   1375     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
   1376 
   1377   template<typename _ITp>
   1378     inline bool
   1379     atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
   1380 					    __atomic_val_t<_ITp>* __i1,
   1381 					    __atomic_val_t<_ITp> __i2,
   1382 					    memory_order __m1,
   1383 					    memory_order __m2) noexcept
   1384     { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
   1385 
   1386 
   1387   template<typename _ITp>
   1388     inline void
   1389     atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
   1390     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
   1391 
   1392   template<typename _ITp>
   1393     inline void
   1394     atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
   1395     { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
   1396 
   1397   template<typename _ITp>
   1398     inline _ITp
   1399     atomic_load(const atomic<_ITp>* __a) noexcept
   1400     { return atomic_load_explicit(__a, memory_order_seq_cst); }
   1401 
   1402   template<typename _ITp>
   1403     inline _ITp
   1404     atomic_load(const volatile atomic<_ITp>* __a) noexcept
   1405     { return atomic_load_explicit(__a, memory_order_seq_cst); }
   1406 
   1407   template<typename _ITp>
   1408     inline _ITp
   1409     atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
   1410     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
   1411 
   1412   template<typename _ITp>
   1413     inline _ITp
   1414     atomic_exchange(volatile atomic<_ITp>* __a,
   1415 		    __atomic_val_t<_ITp> __i) noexcept
   1416     { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
   1417 
   1418   template<typename _ITp>
   1419     inline bool
   1420     atomic_compare_exchange_weak(atomic<_ITp>* __a,
   1421 				 __atomic_val_t<_ITp>* __i1,
   1422 				 __atomic_val_t<_ITp> __i2) noexcept
   1423     {
   1424       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
   1425 						   memory_order_seq_cst,
   1426 						   memory_order_seq_cst);
   1427     }
   1428 
   1429   template<typename _ITp>
   1430     inline bool
   1431     atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
   1432 				 __atomic_val_t<_ITp>* __i1,
   1433 				 __atomic_val_t<_ITp> __i2) noexcept
   1434     {
   1435       return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
   1436 						   memory_order_seq_cst,
   1437 						   memory_order_seq_cst);
   1438     }
   1439 
   1440   template<typename _ITp>
   1441     inline bool
   1442     atomic_compare_exchange_strong(atomic<_ITp>* __a,
   1443 				   __atomic_val_t<_ITp>* __i1,
   1444 				   __atomic_val_t<_ITp> __i2) noexcept
   1445     {
   1446       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
   1447 						     memory_order_seq_cst,
   1448 						     memory_order_seq_cst);
   1449     }
   1450 
   1451   template<typename _ITp>
   1452     inline bool
   1453     atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
   1454 				   __atomic_val_t<_ITp>* __i1,
   1455 				   __atomic_val_t<_ITp> __i2) noexcept
   1456     {
   1457       return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
   1458 						     memory_order_seq_cst,
   1459 						     memory_order_seq_cst);
   1460     }
   1461 
   1462 
   1463 #if __cpp_lib_atomic_wait
   1464   template<typename _Tp>
   1465     inline void
   1466     atomic_wait(const atomic<_Tp>* __a,
   1467 	        typename std::atomic<_Tp>::value_type __old) noexcept
   1468     { __a->wait(__old); }
   1469 
   1470   template<typename _Tp>
   1471     inline void
   1472     atomic_wait_explicit(const atomic<_Tp>* __a,
   1473 			 typename std::atomic<_Tp>::value_type __old,
   1474 			 std::memory_order __m) noexcept
   1475     { __a->wait(__old, __m); }
   1476 
   1477   template<typename _Tp>
   1478     inline void
   1479     atomic_notify_one(atomic<_Tp>* __a) noexcept
   1480     { __a->notify_one(); }
   1481 
   1482   template<typename _Tp>
   1483     inline void
   1484     atomic_notify_all(atomic<_Tp>* __a) noexcept
   1485     { __a->notify_all(); }
   1486 #endif // __cpp_lib_atomic_wait
   1487 
   1488   // Function templates for atomic_integral and atomic_pointer operations only.
   1489   // Some operations (and, or, xor) are only available for atomic integrals,
   1490   // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
   1491 
   1492   template<typename _ITp>
   1493     inline _ITp
   1494     atomic_fetch_add_explicit(atomic<_ITp>* __a,
   1495 			      __atomic_diff_t<_ITp> __i,
   1496 			      memory_order __m) noexcept
   1497     { return __a->fetch_add(__i, __m); }
   1498 
   1499   template<typename _ITp>
   1500     inline _ITp
   1501     atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
   1502 			      __atomic_diff_t<_ITp> __i,
   1503 			      memory_order __m) noexcept
   1504     { return __a->fetch_add(__i, __m); }
   1505 
   1506   template<typename _ITp>
   1507     inline _ITp
   1508     atomic_fetch_sub_explicit(atomic<_ITp>* __a,
   1509 			      __atomic_diff_t<_ITp> __i,
   1510 			      memory_order __m) noexcept
   1511     { return __a->fetch_sub(__i, __m); }
   1512 
   1513   template<typename _ITp>
   1514     inline _ITp
   1515     atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
   1516 			      __atomic_diff_t<_ITp> __i,
   1517 			      memory_order __m) noexcept
   1518     { return __a->fetch_sub(__i, __m); }
   1519 
   1520   template<typename _ITp>
   1521     inline _ITp
   1522     atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
   1523 			      __atomic_val_t<_ITp> __i,
   1524 			      memory_order __m) noexcept
   1525     { return __a->fetch_and(__i, __m); }
   1526 
   1527   template<typename _ITp>
   1528     inline _ITp
   1529     atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
   1530 			      __atomic_val_t<_ITp> __i,
   1531 			      memory_order __m) noexcept
   1532     { return __a->fetch_and(__i, __m); }
   1533 
   1534   template<typename _ITp>
   1535     inline _ITp
   1536     atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
   1537 			     __atomic_val_t<_ITp> __i,
   1538 			     memory_order __m) noexcept
   1539     { return __a->fetch_or(__i, __m); }
   1540 
   1541   template<typename _ITp>
   1542     inline _ITp
   1543     atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
   1544 			     __atomic_val_t<_ITp> __i,
   1545 			     memory_order __m) noexcept
   1546     { return __a->fetch_or(__i, __m); }
   1547 
   1548   template<typename _ITp>
   1549     inline _ITp
   1550     atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
   1551 			      __atomic_val_t<_ITp> __i,
   1552 			      memory_order __m) noexcept
   1553     { return __a->fetch_xor(__i, __m); }
   1554 
   1555   template<typename _ITp>
   1556     inline _ITp
   1557     atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
   1558 			      __atomic_val_t<_ITp> __i,
   1559 			      memory_order __m) noexcept
   1560     { return __a->fetch_xor(__i, __m); }
   1561 
   1562   template<typename _ITp>
   1563     inline _ITp
   1564     atomic_fetch_add(atomic<_ITp>* __a,
   1565 		     __atomic_diff_t<_ITp> __i) noexcept
   1566     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
   1567 
   1568   template<typename _ITp>
   1569     inline _ITp
   1570     atomic_fetch_add(volatile atomic<_ITp>* __a,
   1571 		     __atomic_diff_t<_ITp> __i) noexcept
   1572     { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
   1573 
   1574   template<typename _ITp>
   1575     inline _ITp
   1576     atomic_fetch_sub(atomic<_ITp>* __a,
   1577 		     __atomic_diff_t<_ITp> __i) noexcept
   1578     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
   1579 
   1580   template<typename _ITp>
   1581     inline _ITp
   1582     atomic_fetch_sub(volatile atomic<_ITp>* __a,
   1583 		     __atomic_diff_t<_ITp> __i) noexcept
   1584     { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
   1585 
   1586   template<typename _ITp>
   1587     inline _ITp
   1588     atomic_fetch_and(__atomic_base<_ITp>* __a,
   1589 		     __atomic_val_t<_ITp> __i) noexcept
   1590     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
   1591 
   1592   template<typename _ITp>
   1593     inline _ITp
   1594     atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
   1595 		     __atomic_val_t<_ITp> __i) noexcept
   1596     { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
   1597 
   1598   template<typename _ITp>
   1599     inline _ITp
   1600     atomic_fetch_or(__atomic_base<_ITp>* __a,
   1601 		    __atomic_val_t<_ITp> __i) noexcept
   1602     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
   1603 
   1604   template<typename _ITp>
   1605     inline _ITp
   1606     atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
   1607 		    __atomic_val_t<_ITp> __i) noexcept
   1608     { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
   1609 
   1610   template<typename _ITp>
   1611     inline _ITp
   1612     atomic_fetch_xor(__atomic_base<_ITp>* __a,
   1613 		     __atomic_val_t<_ITp> __i) noexcept
   1614     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
   1615 
   1616   template<typename _ITp>
   1617     inline _ITp
   1618     atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
   1619 		     __atomic_val_t<_ITp> __i) noexcept
   1620     { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
   1621 
   1622 #ifdef __cpp_lib_atomic_float
   1623   template<>
   1624     struct atomic<float> : __atomic_float<float>
   1625     {
   1626       atomic() noexcept = default;
   1627 
   1628       constexpr
   1629       atomic(float __fp) noexcept : __atomic_float<float>(__fp)
   1630       { }
   1631 
   1632       atomic& operator=(const atomic&) volatile = delete;
   1633       atomic& operator=(const atomic&) = delete;
   1634 
   1635       using __atomic_float<float>::operator=;
   1636     };
   1637 
   1638   template<>
   1639     struct atomic<double> : __atomic_float<double>
   1640     {
   1641       atomic() noexcept = default;
   1642 
   1643       constexpr
   1644       atomic(double __fp) noexcept : __atomic_float<double>(__fp)
   1645       { }
   1646 
   1647       atomic& operator=(const atomic&) volatile = delete;
   1648       atomic& operator=(const atomic&) = delete;
   1649 
   1650       using __atomic_float<double>::operator=;
   1651     };
   1652 
   1653   template<>
   1654     struct atomic<long double> : __atomic_float<long double>
   1655     {
   1656       atomic() noexcept = default;
   1657 
   1658       constexpr
   1659       atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
   1660       { }
   1661 
   1662       atomic& operator=(const atomic&) volatile = delete;
   1663       atomic& operator=(const atomic&) = delete;
   1664 
   1665       using __atomic_float<long double>::operator=;
   1666     };
   1667 
   1668 #ifdef __STDCPP_FLOAT16_T__
   1669   template<>
   1670     struct atomic<_Float16> : __atomic_float<_Float16>
   1671     {
   1672       atomic() noexcept = default;
   1673 
   1674       constexpr
   1675       atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp)
   1676       { }
   1677 
   1678       atomic& operator=(const atomic&) volatile = delete;
   1679       atomic& operator=(const atomic&) = delete;
   1680 
   1681       using __atomic_float<_Float16>::operator=;
   1682     };
   1683 #endif
   1684 
   1685 #ifdef __STDCPP_FLOAT32_T__
   1686   template<>
   1687     struct atomic<_Float32> : __atomic_float<_Float32>
   1688     {
   1689       atomic() noexcept = default;
   1690 
   1691       constexpr
   1692       atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp)
   1693       { }
   1694 
   1695       atomic& operator=(const atomic&) volatile = delete;
   1696       atomic& operator=(const atomic&) = delete;
   1697 
   1698       using __atomic_float<_Float32>::operator=;
   1699     };
   1700 #endif
   1701 
   1702 #ifdef __STDCPP_FLOAT64_T__
   1703   template<>
   1704     struct atomic<_Float64> : __atomic_float<_Float64>
   1705     {
   1706       atomic() noexcept = default;
   1707 
   1708       constexpr
   1709       atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp)
   1710       { }
   1711 
   1712       atomic& operator=(const atomic&) volatile = delete;
   1713       atomic& operator=(const atomic&) = delete;
   1714 
   1715       using __atomic_float<_Float64>::operator=;
   1716     };
   1717 #endif
   1718 
   1719 #ifdef __STDCPP_FLOAT128_T__
   1720   template<>
   1721     struct atomic<_Float128> : __atomic_float<_Float128>
   1722     {
   1723       atomic() noexcept = default;
   1724 
   1725       constexpr
   1726       atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp)
   1727       { }
   1728 
   1729       atomic& operator=(const atomic&) volatile = delete;
   1730       atomic& operator=(const atomic&) = delete;
   1731 
   1732       using __atomic_float<_Float128>::operator=;
   1733     };
   1734 #endif
   1735 
   1736 #ifdef __STDCPP_BFLOAT16_T__
   1737   template<>
   1738     struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
   1739     {
   1740       atomic() noexcept = default;
   1741 
   1742       constexpr
   1743       atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
   1744       { }
   1745 
   1746       atomic& operator=(const atomic&) volatile = delete;
   1747       atomic& operator=(const atomic&) = delete;
   1748 
   1749       using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
   1750     };
   1751 #endif
   1752 #endif // __cpp_lib_atomic_float
   1753 
   1754 #ifdef __cpp_lib_atomic_ref
   1755   /// Class template to provide atomic operations on a non-atomic variable.
   1756   template<typename _Tp>
   1757     struct atomic_ref : __atomic_ref<_Tp>
   1758     {
   1759       explicit
   1760       atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
   1761       { }
   1762 
   1763       atomic_ref& operator=(const atomic_ref&) = delete;
   1764 
   1765       atomic_ref(const atomic_ref&) = default;
   1766 
   1767       using __atomic_ref<_Tp>::operator=;
   1768     };
   1769 #endif // __cpp_lib_atomic_ref
   1770 
   1771 #ifdef __cpp_lib_atomic_lock_free_type_aliases
   1772 # ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
   1773   using atomic_signed_lock_free
   1774     = atomic<make_signed_t<__detail::__platform_wait_t>>;
   1775   using atomic_unsigned_lock_free
   1776     = atomic<make_unsigned_t<__detail::__platform_wait_t>>;
   1777 # elif ATOMIC_INT_LOCK_FREE == 2
   1778   using atomic_signed_lock_free = atomic<signed int>;
   1779   using atomic_unsigned_lock_free = atomic<unsigned int>;
   1780 # elif ATOMIC_LONG_LOCK_FREE == 2
   1781   using atomic_signed_lock_free = atomic<signed long>;
   1782   using atomic_unsigned_lock_free = atomic<unsigned long>;
   1783 # elif ATOMIC_CHAR_LOCK_FREE == 2
   1784   using atomic_signed_lock_free = atomic<signed char>;
   1785   using atomic_unsigned_lock_free = atomic<unsigned char>;
   1786 # else
   1787 # error "libstdc++ bug: no lock-free atomics but they were emitted in <version>"
   1788 # endif
   1789 #endif
   1790 
   1791   /// @} group atomics
   1792 
   1793 _GLIBCXX_END_NAMESPACE_VERSION
   1794 } // namespace
   1795 
   1796 #endif // C++11
   1797 
   1798 #endif // _GLIBCXX_ATOMIC
   1799