LCOV - code coverage report
Current view: top level - /usr/include/c++/14 - atomic (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 2 2
Test Date: 2026-02-27 05:14:50 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       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        15872 :       load(memory_order __m = memory_order_seq_cst) const noexcept
     582        31744 :       { 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
        

Generated by: LCOV version 2.0-1