LCOV - code coverage report
Current view: top level - /usr/include/c++/13 - atomic (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 2 2
Test Date: 2024-04-30 13:17:26 Functions: 100.0 % 2 2

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

Generated by: LCOV version 2.0-1