xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/std/atomic (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg// -*- C++ -*- header.
21debfc3dSmrg
3*8feb0f0bSmrg// Copyright (C) 2008-2020 Free Software Foundation, Inc.
41debfc3dSmrg//
51debfc3dSmrg// This file is part of the GNU ISO C++ Library.  This library is free
61debfc3dSmrg// software; you can redistribute it and/or modify it under the
71debfc3dSmrg// terms of the GNU General Public License as published by the
81debfc3dSmrg// Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg// any later version.
101debfc3dSmrg
111debfc3dSmrg// This library is distributed in the hope that it will be useful,
121debfc3dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141debfc3dSmrg// GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg// Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg// permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg// 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg// You should have received a copy of the GNU General Public License and
211debfc3dSmrg// a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
231debfc3dSmrg// <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg/** @file include/atomic
261debfc3dSmrg *  This is a Standard C++ Library header.
271debfc3dSmrg */
281debfc3dSmrg
291debfc3dSmrg// Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
301debfc3dSmrg// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
311debfc3dSmrg
321debfc3dSmrg#ifndef _GLIBCXX_ATOMIC
331debfc3dSmrg#define _GLIBCXX_ATOMIC 1
341debfc3dSmrg
351debfc3dSmrg#pragma GCC system_header
361debfc3dSmrg
371debfc3dSmrg#if __cplusplus < 201103L
381debfc3dSmrg# include <bits/c++0x_warning.h>
391debfc3dSmrg#else
401debfc3dSmrg
411debfc3dSmrg#include <bits/atomic_base.h>
421debfc3dSmrg
431debfc3dSmrgnamespace std _GLIBCXX_VISIBILITY(default)
441debfc3dSmrg{
451debfc3dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
461debfc3dSmrg
471debfc3dSmrg  /**
481debfc3dSmrg   * @addtogroup atomics
491debfc3dSmrg   * @{
501debfc3dSmrg   */
511debfc3dSmrg
52c0a68be4Smrg#if __cplusplus >= 201703L
531debfc3dSmrg# define __cpp_lib_atomic_is_always_lock_free 201603
541debfc3dSmrg#endif
551debfc3dSmrg
561debfc3dSmrg  template<typename _Tp>
571debfc3dSmrg    struct atomic;
581debfc3dSmrg
591debfc3dSmrg  /// atomic<bool>
601debfc3dSmrg  // NB: No operators or fetch-operations for this type.
611debfc3dSmrg  template<>
621debfc3dSmrg  struct atomic<bool>
631debfc3dSmrg  {
64c0a68be4Smrg    using value_type = bool;
65c0a68be4Smrg
661debfc3dSmrg  private:
671debfc3dSmrg    __atomic_base<bool>	_M_base;
681debfc3dSmrg
691debfc3dSmrg  public:
701debfc3dSmrg    atomic() noexcept = default;
711debfc3dSmrg    ~atomic() noexcept = default;
721debfc3dSmrg    atomic(const atomic&) = delete;
731debfc3dSmrg    atomic& operator=(const atomic&) = delete;
741debfc3dSmrg    atomic& operator=(const atomic&) volatile = delete;
751debfc3dSmrg
761debfc3dSmrg    constexpr atomic(bool __i) noexcept : _M_base(__i) { }
771debfc3dSmrg
781debfc3dSmrg    bool
791debfc3dSmrg    operator=(bool __i) noexcept
801debfc3dSmrg    { return _M_base.operator=(__i); }
811debfc3dSmrg
821debfc3dSmrg    bool
831debfc3dSmrg    operator=(bool __i) volatile noexcept
841debfc3dSmrg    { return _M_base.operator=(__i); }
851debfc3dSmrg
861debfc3dSmrg    operator bool() const noexcept
871debfc3dSmrg    { return _M_base.load(); }
881debfc3dSmrg
891debfc3dSmrg    operator bool() const volatile noexcept
901debfc3dSmrg    { return _M_base.load(); }
911debfc3dSmrg
921debfc3dSmrg    bool
931debfc3dSmrg    is_lock_free() const noexcept { return _M_base.is_lock_free(); }
941debfc3dSmrg
951debfc3dSmrg    bool
961debfc3dSmrg    is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
971debfc3dSmrg
98c0a68be4Smrg#if __cplusplus >= 201703L
991debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
1001debfc3dSmrg#endif
1011debfc3dSmrg
1021debfc3dSmrg    void
1031debfc3dSmrg    store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
1041debfc3dSmrg    { _M_base.store(__i, __m); }
1051debfc3dSmrg
1061debfc3dSmrg    void
1071debfc3dSmrg    store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
1081debfc3dSmrg    { _M_base.store(__i, __m); }
1091debfc3dSmrg
1101debfc3dSmrg    bool
1111debfc3dSmrg    load(memory_order __m = memory_order_seq_cst) const noexcept
1121debfc3dSmrg    { return _M_base.load(__m); }
1131debfc3dSmrg
1141debfc3dSmrg    bool
1151debfc3dSmrg    load(memory_order __m = memory_order_seq_cst) const volatile noexcept
1161debfc3dSmrg    { return _M_base.load(__m); }
1171debfc3dSmrg
1181debfc3dSmrg    bool
1191debfc3dSmrg    exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
1201debfc3dSmrg    { return _M_base.exchange(__i, __m); }
1211debfc3dSmrg
1221debfc3dSmrg    bool
1231debfc3dSmrg    exchange(bool __i,
1241debfc3dSmrg	     memory_order __m = memory_order_seq_cst) volatile noexcept
1251debfc3dSmrg    { return _M_base.exchange(__i, __m); }
1261debfc3dSmrg
1271debfc3dSmrg    bool
1281debfc3dSmrg    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
1291debfc3dSmrg			  memory_order __m2) noexcept
1301debfc3dSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
1311debfc3dSmrg
1321debfc3dSmrg    bool
1331debfc3dSmrg    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
1341debfc3dSmrg			  memory_order __m2) volatile noexcept
1351debfc3dSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
1361debfc3dSmrg
1371debfc3dSmrg    bool
1381debfc3dSmrg    compare_exchange_weak(bool& __i1, bool __i2,
1391debfc3dSmrg			  memory_order __m = memory_order_seq_cst) noexcept
1401debfc3dSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
1411debfc3dSmrg
1421debfc3dSmrg    bool
1431debfc3dSmrg    compare_exchange_weak(bool& __i1, bool __i2,
1441debfc3dSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
1451debfc3dSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
1461debfc3dSmrg
1471debfc3dSmrg    bool
1481debfc3dSmrg    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
1491debfc3dSmrg			    memory_order __m2) noexcept
1501debfc3dSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
1511debfc3dSmrg
1521debfc3dSmrg    bool
1531debfc3dSmrg    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
1541debfc3dSmrg			    memory_order __m2) volatile noexcept
1551debfc3dSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
1561debfc3dSmrg
1571debfc3dSmrg    bool
1581debfc3dSmrg    compare_exchange_strong(bool& __i1, bool __i2,
1591debfc3dSmrg			    memory_order __m = memory_order_seq_cst) noexcept
1601debfc3dSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
1611debfc3dSmrg
1621debfc3dSmrg    bool
1631debfc3dSmrg    compare_exchange_strong(bool& __i1, bool __i2,
1641debfc3dSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
1651debfc3dSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
1661debfc3dSmrg  };
1671debfc3dSmrg
168*8feb0f0bSmrg#if __cplusplus <= 201703L
169*8feb0f0bSmrg# define _GLIBCXX20_INIT(I)
170*8feb0f0bSmrg#else
171*8feb0f0bSmrg# define _GLIBCXX20_INIT(I) = I
172*8feb0f0bSmrg#endif
1731debfc3dSmrg
1741debfc3dSmrg  /**
1751debfc3dSmrg   *  @brief Generic atomic type, primary class template.
1761debfc3dSmrg   *
177*8feb0f0bSmrg   *  @tparam _Tp  Type to be made atomic, must be trivially copyable.
1781debfc3dSmrg   */
1791debfc3dSmrg  template<typename _Tp>
1801debfc3dSmrg    struct atomic
1811debfc3dSmrg    {
182c0a68be4Smrg      using value_type = _Tp;
183c0a68be4Smrg
1841debfc3dSmrg    private:
1851debfc3dSmrg      // Align 1/2/4/8/16-byte types to at least their size.
1861debfc3dSmrg      static constexpr int _S_min_alignment
1871debfc3dSmrg	= (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
1881debfc3dSmrg	? 0 : sizeof(_Tp);
1891debfc3dSmrg
1901debfc3dSmrg      static constexpr int _S_alignment
1911debfc3dSmrg        = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
1921debfc3dSmrg
193*8feb0f0bSmrg      alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
1941debfc3dSmrg
1951debfc3dSmrg      static_assert(__is_trivially_copyable(_Tp),
1961debfc3dSmrg		    "std::atomic requires a trivially copyable type");
1971debfc3dSmrg
1981debfc3dSmrg      static_assert(sizeof(_Tp) > 0,
1991debfc3dSmrg		    "Incomplete or zero-sized types are not supported");
2001debfc3dSmrg
201*8feb0f0bSmrg#if __cplusplus > 201703L
202*8feb0f0bSmrg      static_assert(is_copy_constructible_v<_Tp>);
203*8feb0f0bSmrg      static_assert(is_move_constructible_v<_Tp>);
204*8feb0f0bSmrg      static_assert(is_copy_assignable_v<_Tp>);
205*8feb0f0bSmrg      static_assert(is_move_assignable_v<_Tp>);
206*8feb0f0bSmrg#endif
207*8feb0f0bSmrg
2081debfc3dSmrg    public:
209*8feb0f0bSmrg      atomic() = default;
2101debfc3dSmrg      ~atomic() noexcept = default;
2111debfc3dSmrg      atomic(const atomic&) = delete;
2121debfc3dSmrg      atomic& operator=(const atomic&) = delete;
2131debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
2141debfc3dSmrg
2151debfc3dSmrg      constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
2161debfc3dSmrg
2171debfc3dSmrg      operator _Tp() const noexcept
2181debfc3dSmrg      { return load(); }
2191debfc3dSmrg
2201debfc3dSmrg      operator _Tp() const volatile noexcept
2211debfc3dSmrg      { return load(); }
2221debfc3dSmrg
2231debfc3dSmrg      _Tp
2241debfc3dSmrg      operator=(_Tp __i) noexcept
2251debfc3dSmrg      { store(__i); return __i; }
2261debfc3dSmrg
2271debfc3dSmrg      _Tp
2281debfc3dSmrg      operator=(_Tp __i) volatile noexcept
2291debfc3dSmrg      { store(__i); return __i; }
2301debfc3dSmrg
2311debfc3dSmrg      bool
2321debfc3dSmrg      is_lock_free() const noexcept
2331debfc3dSmrg      {
2341debfc3dSmrg	// Produce a fake, minimally aligned pointer.
2351debfc3dSmrg	return __atomic_is_lock_free(sizeof(_M_i),
236c0a68be4Smrg	    reinterpret_cast<void *>(-_S_alignment));
2371debfc3dSmrg      }
2381debfc3dSmrg
2391debfc3dSmrg      bool
2401debfc3dSmrg      is_lock_free() const volatile noexcept
2411debfc3dSmrg      {
2421debfc3dSmrg	// Produce a fake, minimally aligned pointer.
2431debfc3dSmrg	return __atomic_is_lock_free(sizeof(_M_i),
244c0a68be4Smrg	    reinterpret_cast<void *>(-_S_alignment));
2451debfc3dSmrg      }
2461debfc3dSmrg
247c0a68be4Smrg#if __cplusplus >= 201703L
2481debfc3dSmrg      static constexpr bool is_always_lock_free
2491debfc3dSmrg	= __atomic_always_lock_free(sizeof(_M_i), 0);
2501debfc3dSmrg#endif
2511debfc3dSmrg
2521debfc3dSmrg      void
2531debfc3dSmrg      store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
254c0a68be4Smrg      { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); }
2551debfc3dSmrg
2561debfc3dSmrg      void
2571debfc3dSmrg      store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
258c0a68be4Smrg      { __atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m)); }
2591debfc3dSmrg
2601debfc3dSmrg      _Tp
2611debfc3dSmrg      load(memory_order __m = memory_order_seq_cst) const noexcept
2621debfc3dSmrg      {
2631debfc3dSmrg	alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2641debfc3dSmrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
265c0a68be4Smrg	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2661debfc3dSmrg	return *__ptr;
2671debfc3dSmrg      }
2681debfc3dSmrg
2691debfc3dSmrg      _Tp
2701debfc3dSmrg      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
2711debfc3dSmrg      {
2721debfc3dSmrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2731debfc3dSmrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
274c0a68be4Smrg	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2751debfc3dSmrg	return *__ptr;
2761debfc3dSmrg      }
2771debfc3dSmrg
2781debfc3dSmrg      _Tp
2791debfc3dSmrg      exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
2801debfc3dSmrg      {
2811debfc3dSmrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2821debfc3dSmrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
2831debfc3dSmrg	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
284c0a68be4Smrg			  __ptr, int(__m));
2851debfc3dSmrg	return *__ptr;
2861debfc3dSmrg      }
2871debfc3dSmrg
2881debfc3dSmrg      _Tp
2891debfc3dSmrg      exchange(_Tp __i,
2901debfc3dSmrg	       memory_order __m = memory_order_seq_cst) volatile noexcept
2911debfc3dSmrg      {
2921debfc3dSmrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2931debfc3dSmrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
2941debfc3dSmrg	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
295c0a68be4Smrg			  __ptr, int(__m));
2961debfc3dSmrg	return *__ptr;
2971debfc3dSmrg      }
2981debfc3dSmrg
2991debfc3dSmrg      bool
3001debfc3dSmrg      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
3011debfc3dSmrg			    memory_order __f) noexcept
3021debfc3dSmrg      {
3031debfc3dSmrg	return __atomic_compare_exchange(std::__addressof(_M_i),
3041debfc3dSmrg					 std::__addressof(__e),
3051debfc3dSmrg					 std::__addressof(__i),
306c0a68be4Smrg					 true, int(__s), int(__f));
3071debfc3dSmrg      }
3081debfc3dSmrg
3091debfc3dSmrg      bool
3101debfc3dSmrg      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
3111debfc3dSmrg			    memory_order __f) volatile noexcept
3121debfc3dSmrg      {
3131debfc3dSmrg	return __atomic_compare_exchange(std::__addressof(_M_i),
3141debfc3dSmrg					 std::__addressof(__e),
3151debfc3dSmrg					 std::__addressof(__i),
316c0a68be4Smrg					 true, int(__s), int(__f));
3171debfc3dSmrg      }
3181debfc3dSmrg
3191debfc3dSmrg      bool
3201debfc3dSmrg      compare_exchange_weak(_Tp& __e, _Tp __i,
3211debfc3dSmrg			    memory_order __m = memory_order_seq_cst) noexcept
3221debfc3dSmrg      { return compare_exchange_weak(__e, __i, __m,
3231debfc3dSmrg                                     __cmpexch_failure_order(__m)); }
3241debfc3dSmrg
3251debfc3dSmrg      bool
3261debfc3dSmrg      compare_exchange_weak(_Tp& __e, _Tp __i,
3271debfc3dSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
3281debfc3dSmrg      { return compare_exchange_weak(__e, __i, __m,
3291debfc3dSmrg                                     __cmpexch_failure_order(__m)); }
3301debfc3dSmrg
3311debfc3dSmrg      bool
3321debfc3dSmrg      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
3331debfc3dSmrg			      memory_order __f) noexcept
3341debfc3dSmrg      {
3351debfc3dSmrg	return __atomic_compare_exchange(std::__addressof(_M_i),
3361debfc3dSmrg					 std::__addressof(__e),
3371debfc3dSmrg					 std::__addressof(__i),
338c0a68be4Smrg					 false, int(__s), int(__f));
3391debfc3dSmrg      }
3401debfc3dSmrg
3411debfc3dSmrg      bool
3421debfc3dSmrg      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
3431debfc3dSmrg			      memory_order __f) volatile noexcept
3441debfc3dSmrg      {
3451debfc3dSmrg	return __atomic_compare_exchange(std::__addressof(_M_i),
3461debfc3dSmrg					 std::__addressof(__e),
3471debfc3dSmrg					 std::__addressof(__i),
348c0a68be4Smrg					 false, int(__s), int(__f));
3491debfc3dSmrg      }
3501debfc3dSmrg
3511debfc3dSmrg      bool
3521debfc3dSmrg      compare_exchange_strong(_Tp& __e, _Tp __i,
3531debfc3dSmrg			       memory_order __m = memory_order_seq_cst) noexcept
3541debfc3dSmrg      { return compare_exchange_strong(__e, __i, __m,
3551debfc3dSmrg                                       __cmpexch_failure_order(__m)); }
3561debfc3dSmrg
3571debfc3dSmrg      bool
3581debfc3dSmrg      compare_exchange_strong(_Tp& __e, _Tp __i,
3591debfc3dSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
3601debfc3dSmrg      { return compare_exchange_strong(__e, __i, __m,
3611debfc3dSmrg                                       __cmpexch_failure_order(__m)); }
3621debfc3dSmrg    };
363*8feb0f0bSmrg#undef _GLIBCXX20_INIT
3641debfc3dSmrg
3651debfc3dSmrg  /// Partial specialization for pointer types.
3661debfc3dSmrg  template<typename _Tp>
3671debfc3dSmrg    struct atomic<_Tp*>
3681debfc3dSmrg    {
369c0a68be4Smrg      using value_type = _Tp*;
370c0a68be4Smrg      using difference_type = ptrdiff_t;
371c0a68be4Smrg
3721debfc3dSmrg      typedef _Tp* 			__pointer_type;
3731debfc3dSmrg      typedef __atomic_base<_Tp*>	__base_type;
3741debfc3dSmrg      __base_type			_M_b;
3751debfc3dSmrg
3761debfc3dSmrg      atomic() noexcept = default;
3771debfc3dSmrg      ~atomic() noexcept = default;
3781debfc3dSmrg      atomic(const atomic&) = delete;
3791debfc3dSmrg      atomic& operator=(const atomic&) = delete;
3801debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
3811debfc3dSmrg
3821debfc3dSmrg      constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
3831debfc3dSmrg
3841debfc3dSmrg      operator __pointer_type() const noexcept
3851debfc3dSmrg      { return __pointer_type(_M_b); }
3861debfc3dSmrg
3871debfc3dSmrg      operator __pointer_type() const volatile noexcept
3881debfc3dSmrg      { return __pointer_type(_M_b); }
3891debfc3dSmrg
3901debfc3dSmrg      __pointer_type
3911debfc3dSmrg      operator=(__pointer_type __p) noexcept
3921debfc3dSmrg      { return _M_b.operator=(__p); }
3931debfc3dSmrg
3941debfc3dSmrg      __pointer_type
3951debfc3dSmrg      operator=(__pointer_type __p) volatile noexcept
3961debfc3dSmrg      { return _M_b.operator=(__p); }
3971debfc3dSmrg
3981debfc3dSmrg      __pointer_type
3991debfc3dSmrg      operator++(int) noexcept
400c0a68be4Smrg      {
401c0a68be4Smrg#if __cplusplus >= 201703L
402c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
403c0a68be4Smrg#endif
404c0a68be4Smrg	return _M_b++;
405c0a68be4Smrg      }
4061debfc3dSmrg
4071debfc3dSmrg      __pointer_type
4081debfc3dSmrg      operator++(int) volatile noexcept
409c0a68be4Smrg      {
410c0a68be4Smrg#if __cplusplus >= 201703L
411c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
412c0a68be4Smrg#endif
413c0a68be4Smrg	return _M_b++;
414c0a68be4Smrg      }
4151debfc3dSmrg
4161debfc3dSmrg      __pointer_type
4171debfc3dSmrg      operator--(int) noexcept
418c0a68be4Smrg      {
419c0a68be4Smrg#if __cplusplus >= 201703L
420c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
421c0a68be4Smrg#endif
422c0a68be4Smrg	return _M_b--;
423c0a68be4Smrg      }
4241debfc3dSmrg
4251debfc3dSmrg      __pointer_type
4261debfc3dSmrg      operator--(int) volatile noexcept
427c0a68be4Smrg      {
428c0a68be4Smrg#if __cplusplus >= 201703L
429c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
430c0a68be4Smrg#endif
431c0a68be4Smrg	return _M_b--;
432c0a68be4Smrg      }
4331debfc3dSmrg
4341debfc3dSmrg      __pointer_type
4351debfc3dSmrg      operator++() noexcept
436c0a68be4Smrg      {
437c0a68be4Smrg#if __cplusplus >= 201703L
438c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
439c0a68be4Smrg#endif
440c0a68be4Smrg	return ++_M_b;
441c0a68be4Smrg      }
4421debfc3dSmrg
4431debfc3dSmrg      __pointer_type
4441debfc3dSmrg      operator++() volatile noexcept
445c0a68be4Smrg      {
446c0a68be4Smrg#if __cplusplus >= 201703L
447c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
448c0a68be4Smrg#endif
449c0a68be4Smrg	return ++_M_b;
450c0a68be4Smrg      }
4511debfc3dSmrg
4521debfc3dSmrg      __pointer_type
4531debfc3dSmrg      operator--() noexcept
454c0a68be4Smrg      {
455c0a68be4Smrg#if __cplusplus >= 201703L
456c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
457c0a68be4Smrg#endif
458c0a68be4Smrg	return --_M_b;
459c0a68be4Smrg      }
4601debfc3dSmrg
4611debfc3dSmrg      __pointer_type
4621debfc3dSmrg      operator--() volatile noexcept
463c0a68be4Smrg      {
464c0a68be4Smrg#if __cplusplus >= 201703L
465c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
466c0a68be4Smrg#endif
467c0a68be4Smrg	return --_M_b;
468c0a68be4Smrg      }
4691debfc3dSmrg
4701debfc3dSmrg      __pointer_type
4711debfc3dSmrg      operator+=(ptrdiff_t __d) noexcept
472c0a68be4Smrg      {
473c0a68be4Smrg#if __cplusplus >= 201703L
474c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
475c0a68be4Smrg#endif
476c0a68be4Smrg	return _M_b.operator+=(__d);
477c0a68be4Smrg      }
4781debfc3dSmrg
4791debfc3dSmrg      __pointer_type
4801debfc3dSmrg      operator+=(ptrdiff_t __d) volatile noexcept
481c0a68be4Smrg      {
482c0a68be4Smrg#if __cplusplus >= 201703L
483c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
484c0a68be4Smrg#endif
485c0a68be4Smrg	return _M_b.operator+=(__d);
486c0a68be4Smrg      }
4871debfc3dSmrg
4881debfc3dSmrg      __pointer_type
4891debfc3dSmrg      operator-=(ptrdiff_t __d) noexcept
490c0a68be4Smrg      {
491c0a68be4Smrg#if __cplusplus >= 201703L
492c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
493c0a68be4Smrg#endif
494c0a68be4Smrg	return _M_b.operator-=(__d);
495c0a68be4Smrg      }
4961debfc3dSmrg
4971debfc3dSmrg      __pointer_type
4981debfc3dSmrg      operator-=(ptrdiff_t __d) volatile noexcept
499c0a68be4Smrg      {
500c0a68be4Smrg#if __cplusplus >= 201703L
501c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
502c0a68be4Smrg#endif
503c0a68be4Smrg	return _M_b.operator-=(__d);
504c0a68be4Smrg      }
5051debfc3dSmrg
5061debfc3dSmrg      bool
5071debfc3dSmrg      is_lock_free() const noexcept
5081debfc3dSmrg      { return _M_b.is_lock_free(); }
5091debfc3dSmrg
5101debfc3dSmrg      bool
5111debfc3dSmrg      is_lock_free() const volatile noexcept
5121debfc3dSmrg      { return _M_b.is_lock_free(); }
5131debfc3dSmrg
514c0a68be4Smrg#if __cplusplus >= 201703L
5151debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2;
5161debfc3dSmrg#endif
5171debfc3dSmrg
5181debfc3dSmrg      void
5191debfc3dSmrg      store(__pointer_type __p,
5201debfc3dSmrg	    memory_order __m = memory_order_seq_cst) noexcept
5211debfc3dSmrg      { return _M_b.store(__p, __m); }
5221debfc3dSmrg
5231debfc3dSmrg      void
5241debfc3dSmrg      store(__pointer_type __p,
5251debfc3dSmrg	    memory_order __m = memory_order_seq_cst) volatile noexcept
5261debfc3dSmrg      { return _M_b.store(__p, __m); }
5271debfc3dSmrg
5281debfc3dSmrg      __pointer_type
5291debfc3dSmrg      load(memory_order __m = memory_order_seq_cst) const noexcept
5301debfc3dSmrg      { return _M_b.load(__m); }
5311debfc3dSmrg
5321debfc3dSmrg      __pointer_type
5331debfc3dSmrg      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
5341debfc3dSmrg      { return _M_b.load(__m); }
5351debfc3dSmrg
5361debfc3dSmrg      __pointer_type
5371debfc3dSmrg      exchange(__pointer_type __p,
5381debfc3dSmrg	       memory_order __m = memory_order_seq_cst) noexcept
5391debfc3dSmrg      { return _M_b.exchange(__p, __m); }
5401debfc3dSmrg
5411debfc3dSmrg      __pointer_type
5421debfc3dSmrg      exchange(__pointer_type __p,
5431debfc3dSmrg	       memory_order __m = memory_order_seq_cst) volatile noexcept
5441debfc3dSmrg      { return _M_b.exchange(__p, __m); }
5451debfc3dSmrg
5461debfc3dSmrg      bool
5471debfc3dSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
5481debfc3dSmrg			    memory_order __m1, memory_order __m2) noexcept
5491debfc3dSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
5501debfc3dSmrg
5511debfc3dSmrg      bool
5521debfc3dSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
5531debfc3dSmrg			    memory_order __m1,
5541debfc3dSmrg			    memory_order __m2) volatile noexcept
5551debfc3dSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
5561debfc3dSmrg
5571debfc3dSmrg      bool
5581debfc3dSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
5591debfc3dSmrg			    memory_order __m = memory_order_seq_cst) noexcept
5601debfc3dSmrg      {
5611debfc3dSmrg	return compare_exchange_weak(__p1, __p2, __m,
5621debfc3dSmrg				     __cmpexch_failure_order(__m));
5631debfc3dSmrg      }
5641debfc3dSmrg
5651debfc3dSmrg      bool
5661debfc3dSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
5671debfc3dSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
5681debfc3dSmrg      {
5691debfc3dSmrg	return compare_exchange_weak(__p1, __p2, __m,
5701debfc3dSmrg				     __cmpexch_failure_order(__m));
5711debfc3dSmrg      }
5721debfc3dSmrg
5731debfc3dSmrg      bool
5741debfc3dSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
5751debfc3dSmrg			      memory_order __m1, memory_order __m2) noexcept
5761debfc3dSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
5771debfc3dSmrg
5781debfc3dSmrg      bool
5791debfc3dSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
5801debfc3dSmrg			      memory_order __m1,
5811debfc3dSmrg			      memory_order __m2) volatile noexcept
5821debfc3dSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
5831debfc3dSmrg
5841debfc3dSmrg      bool
5851debfc3dSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
5861debfc3dSmrg			      memory_order __m = memory_order_seq_cst) noexcept
5871debfc3dSmrg      {
5881debfc3dSmrg	return _M_b.compare_exchange_strong(__p1, __p2, __m,
5891debfc3dSmrg					    __cmpexch_failure_order(__m));
5901debfc3dSmrg      }
5911debfc3dSmrg
5921debfc3dSmrg      bool
5931debfc3dSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
5941debfc3dSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
5951debfc3dSmrg      {
5961debfc3dSmrg	return _M_b.compare_exchange_strong(__p1, __p2, __m,
5971debfc3dSmrg					    __cmpexch_failure_order(__m));
5981debfc3dSmrg      }
5991debfc3dSmrg
6001debfc3dSmrg      __pointer_type
6011debfc3dSmrg      fetch_add(ptrdiff_t __d,
6021debfc3dSmrg		memory_order __m = memory_order_seq_cst) noexcept
603c0a68be4Smrg      {
604c0a68be4Smrg#if __cplusplus >= 201703L
605c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
606c0a68be4Smrg#endif
607c0a68be4Smrg	return _M_b.fetch_add(__d, __m);
608c0a68be4Smrg      }
6091debfc3dSmrg
6101debfc3dSmrg      __pointer_type
6111debfc3dSmrg      fetch_add(ptrdiff_t __d,
6121debfc3dSmrg		memory_order __m = memory_order_seq_cst) volatile noexcept
613c0a68be4Smrg      {
614c0a68be4Smrg#if __cplusplus >= 201703L
615c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
616c0a68be4Smrg#endif
617c0a68be4Smrg	return _M_b.fetch_add(__d, __m);
618c0a68be4Smrg      }
6191debfc3dSmrg
6201debfc3dSmrg      __pointer_type
6211debfc3dSmrg      fetch_sub(ptrdiff_t __d,
6221debfc3dSmrg		memory_order __m = memory_order_seq_cst) noexcept
623c0a68be4Smrg      {
624c0a68be4Smrg#if __cplusplus >= 201703L
625c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
626c0a68be4Smrg#endif
627c0a68be4Smrg	return _M_b.fetch_sub(__d, __m);
628c0a68be4Smrg      }
6291debfc3dSmrg
6301debfc3dSmrg      __pointer_type
6311debfc3dSmrg      fetch_sub(ptrdiff_t __d,
6321debfc3dSmrg		memory_order __m = memory_order_seq_cst) volatile noexcept
633c0a68be4Smrg      {
634c0a68be4Smrg#if __cplusplus >= 201703L
635c0a68be4Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
636c0a68be4Smrg#endif
637c0a68be4Smrg	return _M_b.fetch_sub(__d, __m);
638c0a68be4Smrg      }
6391debfc3dSmrg    };
6401debfc3dSmrg
6411debfc3dSmrg
6421debfc3dSmrg  /// Explicit specialization for char.
6431debfc3dSmrg  template<>
6441debfc3dSmrg    struct atomic<char> : __atomic_base<char>
6451debfc3dSmrg    {
6461debfc3dSmrg      typedef char 			__integral_type;
6471debfc3dSmrg      typedef __atomic_base<char> 	__base_type;
6481debfc3dSmrg
6491debfc3dSmrg      atomic() noexcept = default;
6501debfc3dSmrg      ~atomic() noexcept = default;
6511debfc3dSmrg      atomic(const atomic&) = delete;
6521debfc3dSmrg      atomic& operator=(const atomic&) = delete;
6531debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
6541debfc3dSmrg
6551debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
6561debfc3dSmrg
6571debfc3dSmrg      using __base_type::operator __integral_type;
6581debfc3dSmrg      using __base_type::operator=;
6591debfc3dSmrg
660c0a68be4Smrg#if __cplusplus >= 201703L
6611debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
6621debfc3dSmrg#endif
6631debfc3dSmrg    };
6641debfc3dSmrg
6651debfc3dSmrg  /// Explicit specialization for signed char.
6661debfc3dSmrg  template<>
6671debfc3dSmrg    struct atomic<signed char> : __atomic_base<signed char>
6681debfc3dSmrg    {
6691debfc3dSmrg      typedef signed char 		__integral_type;
6701debfc3dSmrg      typedef __atomic_base<signed char> 	__base_type;
6711debfc3dSmrg
6721debfc3dSmrg      atomic() noexcept= default;
6731debfc3dSmrg      ~atomic() noexcept = default;
6741debfc3dSmrg      atomic(const atomic&) = delete;
6751debfc3dSmrg      atomic& operator=(const atomic&) = delete;
6761debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
6771debfc3dSmrg
6781debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
6791debfc3dSmrg
6801debfc3dSmrg      using __base_type::operator __integral_type;
6811debfc3dSmrg      using __base_type::operator=;
6821debfc3dSmrg
683c0a68be4Smrg#if __cplusplus >= 201703L
6841debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
6851debfc3dSmrg#endif
6861debfc3dSmrg    };
6871debfc3dSmrg
6881debfc3dSmrg  /// Explicit specialization for unsigned char.
6891debfc3dSmrg  template<>
6901debfc3dSmrg    struct atomic<unsigned char> : __atomic_base<unsigned char>
6911debfc3dSmrg    {
6921debfc3dSmrg      typedef unsigned char 		__integral_type;
6931debfc3dSmrg      typedef __atomic_base<unsigned char> 	__base_type;
6941debfc3dSmrg
6951debfc3dSmrg      atomic() noexcept= default;
6961debfc3dSmrg      ~atomic() noexcept = default;
6971debfc3dSmrg      atomic(const atomic&) = delete;
6981debfc3dSmrg      atomic& operator=(const atomic&) = delete;
6991debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
7001debfc3dSmrg
7011debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7021debfc3dSmrg
7031debfc3dSmrg      using __base_type::operator __integral_type;
7041debfc3dSmrg      using __base_type::operator=;
7051debfc3dSmrg
706c0a68be4Smrg#if __cplusplus >= 201703L
7071debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
7081debfc3dSmrg#endif
7091debfc3dSmrg    };
7101debfc3dSmrg
7111debfc3dSmrg  /// Explicit specialization for short.
7121debfc3dSmrg  template<>
7131debfc3dSmrg    struct atomic<short> : __atomic_base<short>
7141debfc3dSmrg    {
7151debfc3dSmrg      typedef short 			__integral_type;
7161debfc3dSmrg      typedef __atomic_base<short> 		__base_type;
7171debfc3dSmrg
7181debfc3dSmrg      atomic() noexcept = default;
7191debfc3dSmrg      ~atomic() noexcept = default;
7201debfc3dSmrg      atomic(const atomic&) = delete;
7211debfc3dSmrg      atomic& operator=(const atomic&) = delete;
7221debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
7231debfc3dSmrg
7241debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7251debfc3dSmrg
7261debfc3dSmrg      using __base_type::operator __integral_type;
7271debfc3dSmrg      using __base_type::operator=;
7281debfc3dSmrg
729c0a68be4Smrg#if __cplusplus >= 201703L
7301debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
7311debfc3dSmrg#endif
7321debfc3dSmrg    };
7331debfc3dSmrg
7341debfc3dSmrg  /// Explicit specialization for unsigned short.
7351debfc3dSmrg  template<>
7361debfc3dSmrg    struct atomic<unsigned short> : __atomic_base<unsigned short>
7371debfc3dSmrg    {
7381debfc3dSmrg      typedef unsigned short 	      	__integral_type;
7391debfc3dSmrg      typedef __atomic_base<unsigned short> 		__base_type;
7401debfc3dSmrg
7411debfc3dSmrg      atomic() noexcept = default;
7421debfc3dSmrg      ~atomic() noexcept = default;
7431debfc3dSmrg      atomic(const atomic&) = delete;
7441debfc3dSmrg      atomic& operator=(const atomic&) = delete;
7451debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
7461debfc3dSmrg
7471debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7481debfc3dSmrg
7491debfc3dSmrg      using __base_type::operator __integral_type;
7501debfc3dSmrg      using __base_type::operator=;
7511debfc3dSmrg
752c0a68be4Smrg#if __cplusplus >= 201703L
7531debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
7541debfc3dSmrg#endif
7551debfc3dSmrg    };
7561debfc3dSmrg
7571debfc3dSmrg  /// Explicit specialization for int.
7581debfc3dSmrg  template<>
7591debfc3dSmrg    struct atomic<int> : __atomic_base<int>
7601debfc3dSmrg    {
7611debfc3dSmrg      typedef int 			__integral_type;
7621debfc3dSmrg      typedef __atomic_base<int> 		__base_type;
7631debfc3dSmrg
7641debfc3dSmrg      atomic() noexcept = default;
7651debfc3dSmrg      ~atomic() noexcept = default;
7661debfc3dSmrg      atomic(const atomic&) = delete;
7671debfc3dSmrg      atomic& operator=(const atomic&) = delete;
7681debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
7691debfc3dSmrg
7701debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7711debfc3dSmrg
7721debfc3dSmrg      using __base_type::operator __integral_type;
7731debfc3dSmrg      using __base_type::operator=;
7741debfc3dSmrg
775c0a68be4Smrg#if __cplusplus >= 201703L
7761debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
7771debfc3dSmrg#endif
7781debfc3dSmrg    };
7791debfc3dSmrg
7801debfc3dSmrg  /// Explicit specialization for unsigned int.
7811debfc3dSmrg  template<>
7821debfc3dSmrg    struct atomic<unsigned int> : __atomic_base<unsigned int>
7831debfc3dSmrg    {
7841debfc3dSmrg      typedef unsigned int		__integral_type;
7851debfc3dSmrg      typedef __atomic_base<unsigned int> 	__base_type;
7861debfc3dSmrg
7871debfc3dSmrg      atomic() noexcept = default;
7881debfc3dSmrg      ~atomic() noexcept = default;
7891debfc3dSmrg      atomic(const atomic&) = delete;
7901debfc3dSmrg      atomic& operator=(const atomic&) = delete;
7911debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
7921debfc3dSmrg
7931debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7941debfc3dSmrg
7951debfc3dSmrg      using __base_type::operator __integral_type;
7961debfc3dSmrg      using __base_type::operator=;
7971debfc3dSmrg
798c0a68be4Smrg#if __cplusplus >= 201703L
7991debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
8001debfc3dSmrg#endif
8011debfc3dSmrg    };
8021debfc3dSmrg
8031debfc3dSmrg  /// Explicit specialization for long.
8041debfc3dSmrg  template<>
8051debfc3dSmrg    struct atomic<long> : __atomic_base<long>
8061debfc3dSmrg    {
8071debfc3dSmrg      typedef long 			__integral_type;
8081debfc3dSmrg      typedef __atomic_base<long> 	__base_type;
8091debfc3dSmrg
8101debfc3dSmrg      atomic() noexcept = default;
8111debfc3dSmrg      ~atomic() noexcept = default;
8121debfc3dSmrg      atomic(const atomic&) = delete;
8131debfc3dSmrg      atomic& operator=(const atomic&) = delete;
8141debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
8151debfc3dSmrg
8161debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8171debfc3dSmrg
8181debfc3dSmrg      using __base_type::operator __integral_type;
8191debfc3dSmrg      using __base_type::operator=;
8201debfc3dSmrg
821c0a68be4Smrg#if __cplusplus >= 201703L
8221debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
8231debfc3dSmrg#endif
8241debfc3dSmrg    };
8251debfc3dSmrg
8261debfc3dSmrg  /// Explicit specialization for unsigned long.
8271debfc3dSmrg  template<>
8281debfc3dSmrg    struct atomic<unsigned long> : __atomic_base<unsigned long>
8291debfc3dSmrg    {
8301debfc3dSmrg      typedef unsigned long 		__integral_type;
8311debfc3dSmrg      typedef __atomic_base<unsigned long> 	__base_type;
8321debfc3dSmrg
8331debfc3dSmrg      atomic() noexcept = default;
8341debfc3dSmrg      ~atomic() noexcept = default;
8351debfc3dSmrg      atomic(const atomic&) = delete;
8361debfc3dSmrg      atomic& operator=(const atomic&) = delete;
8371debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
8381debfc3dSmrg
8391debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8401debfc3dSmrg
8411debfc3dSmrg      using __base_type::operator __integral_type;
8421debfc3dSmrg      using __base_type::operator=;
8431debfc3dSmrg
844c0a68be4Smrg#if __cplusplus >= 201703L
8451debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
8461debfc3dSmrg#endif
8471debfc3dSmrg    };
8481debfc3dSmrg
8491debfc3dSmrg  /// Explicit specialization for long long.
8501debfc3dSmrg  template<>
8511debfc3dSmrg    struct atomic<long long> : __atomic_base<long long>
8521debfc3dSmrg    {
8531debfc3dSmrg      typedef long long 		__integral_type;
8541debfc3dSmrg      typedef __atomic_base<long long> 		__base_type;
8551debfc3dSmrg
8561debfc3dSmrg      atomic() noexcept = default;
8571debfc3dSmrg      ~atomic() noexcept = default;
8581debfc3dSmrg      atomic(const atomic&) = delete;
8591debfc3dSmrg      atomic& operator=(const atomic&) = delete;
8601debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
8611debfc3dSmrg
8621debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8631debfc3dSmrg
8641debfc3dSmrg      using __base_type::operator __integral_type;
8651debfc3dSmrg      using __base_type::operator=;
8661debfc3dSmrg
867c0a68be4Smrg#if __cplusplus >= 201703L
8681debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
8691debfc3dSmrg#endif
8701debfc3dSmrg    };
8711debfc3dSmrg
8721debfc3dSmrg  /// Explicit specialization for unsigned long long.
8731debfc3dSmrg  template<>
8741debfc3dSmrg    struct atomic<unsigned long long> : __atomic_base<unsigned long long>
8751debfc3dSmrg    {
8761debfc3dSmrg      typedef unsigned long long       	__integral_type;
8771debfc3dSmrg      typedef __atomic_base<unsigned long long> 	__base_type;
8781debfc3dSmrg
8791debfc3dSmrg      atomic() noexcept = default;
8801debfc3dSmrg      ~atomic() noexcept = default;
8811debfc3dSmrg      atomic(const atomic&) = delete;
8821debfc3dSmrg      atomic& operator=(const atomic&) = delete;
8831debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
8841debfc3dSmrg
8851debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8861debfc3dSmrg
8871debfc3dSmrg      using __base_type::operator __integral_type;
8881debfc3dSmrg      using __base_type::operator=;
8891debfc3dSmrg
890c0a68be4Smrg#if __cplusplus >= 201703L
8911debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
8921debfc3dSmrg#endif
8931debfc3dSmrg    };
8941debfc3dSmrg
8951debfc3dSmrg  /// Explicit specialization for wchar_t.
8961debfc3dSmrg  template<>
8971debfc3dSmrg    struct atomic<wchar_t> : __atomic_base<wchar_t>
8981debfc3dSmrg    {
8991debfc3dSmrg      typedef wchar_t 			__integral_type;
9001debfc3dSmrg      typedef __atomic_base<wchar_t> 	__base_type;
9011debfc3dSmrg
9021debfc3dSmrg      atomic() noexcept = default;
9031debfc3dSmrg      ~atomic() noexcept = default;
9041debfc3dSmrg      atomic(const atomic&) = delete;
9051debfc3dSmrg      atomic& operator=(const atomic&) = delete;
9061debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
9071debfc3dSmrg
9081debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9091debfc3dSmrg
9101debfc3dSmrg      using __base_type::operator __integral_type;
9111debfc3dSmrg      using __base_type::operator=;
9121debfc3dSmrg
913c0a68be4Smrg#if __cplusplus >= 201703L
9141debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
9151debfc3dSmrg#endif
9161debfc3dSmrg    };
9171debfc3dSmrg
918c0a68be4Smrg#ifdef _GLIBCXX_USE_CHAR8_T
919c0a68be4Smrg  /// Explicit specialization for char8_t.
920c0a68be4Smrg  template<>
921c0a68be4Smrg    struct atomic<char8_t> : __atomic_base<char8_t>
922c0a68be4Smrg    {
923c0a68be4Smrg      typedef char8_t 			__integral_type;
924c0a68be4Smrg      typedef __atomic_base<char8_t> 	__base_type;
925c0a68be4Smrg
926c0a68be4Smrg      atomic() noexcept = default;
927c0a68be4Smrg      ~atomic() noexcept = default;
928c0a68be4Smrg      atomic(const atomic&) = delete;
929c0a68be4Smrg      atomic& operator=(const atomic&) = delete;
930c0a68be4Smrg      atomic& operator=(const atomic&) volatile = delete;
931c0a68be4Smrg
932c0a68be4Smrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
933c0a68be4Smrg
934c0a68be4Smrg      using __base_type::operator __integral_type;
935c0a68be4Smrg      using __base_type::operator=;
936c0a68be4Smrg
937c0a68be4Smrg#if __cplusplus > 201402L
938c0a68be4Smrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR8_T_LOCK_FREE == 2;
939c0a68be4Smrg#endif
940c0a68be4Smrg    };
941c0a68be4Smrg#endif
942c0a68be4Smrg
9431debfc3dSmrg  /// Explicit specialization for char16_t.
9441debfc3dSmrg  template<>
9451debfc3dSmrg    struct atomic<char16_t> : __atomic_base<char16_t>
9461debfc3dSmrg    {
9471debfc3dSmrg      typedef char16_t 			__integral_type;
9481debfc3dSmrg      typedef __atomic_base<char16_t> 	__base_type;
9491debfc3dSmrg
9501debfc3dSmrg      atomic() noexcept = default;
9511debfc3dSmrg      ~atomic() noexcept = default;
9521debfc3dSmrg      atomic(const atomic&) = delete;
9531debfc3dSmrg      atomic& operator=(const atomic&) = delete;
9541debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
9551debfc3dSmrg
9561debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9571debfc3dSmrg
9581debfc3dSmrg      using __base_type::operator __integral_type;
9591debfc3dSmrg      using __base_type::operator=;
9601debfc3dSmrg
961c0a68be4Smrg#if __cplusplus >= 201703L
9621debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR16_T_LOCK_FREE == 2;
9631debfc3dSmrg#endif
9641debfc3dSmrg    };
9651debfc3dSmrg
9661debfc3dSmrg  /// Explicit specialization for char32_t.
9671debfc3dSmrg  template<>
9681debfc3dSmrg    struct atomic<char32_t> : __atomic_base<char32_t>
9691debfc3dSmrg    {
9701debfc3dSmrg      typedef char32_t 			__integral_type;
9711debfc3dSmrg      typedef __atomic_base<char32_t> 	__base_type;
9721debfc3dSmrg
9731debfc3dSmrg      atomic() noexcept = default;
9741debfc3dSmrg      ~atomic() noexcept = default;
9751debfc3dSmrg      atomic(const atomic&) = delete;
9761debfc3dSmrg      atomic& operator=(const atomic&) = delete;
9771debfc3dSmrg      atomic& operator=(const atomic&) volatile = delete;
9781debfc3dSmrg
9791debfc3dSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9801debfc3dSmrg
9811debfc3dSmrg      using __base_type::operator __integral_type;
9821debfc3dSmrg      using __base_type::operator=;
9831debfc3dSmrg
984c0a68be4Smrg#if __cplusplus >= 201703L
9851debfc3dSmrg    static constexpr bool is_always_lock_free = ATOMIC_CHAR32_T_LOCK_FREE == 2;
9861debfc3dSmrg#endif
9871debfc3dSmrg    };
9881debfc3dSmrg
9891debfc3dSmrg
9901debfc3dSmrg  /// atomic_bool
9911debfc3dSmrg  typedef atomic<bool>			atomic_bool;
9921debfc3dSmrg
9931debfc3dSmrg  /// atomic_char
9941debfc3dSmrg  typedef atomic<char>			atomic_char;
9951debfc3dSmrg
9961debfc3dSmrg  /// atomic_schar
9971debfc3dSmrg  typedef atomic<signed char>		atomic_schar;
9981debfc3dSmrg
9991debfc3dSmrg  /// atomic_uchar
10001debfc3dSmrg  typedef atomic<unsigned char>		atomic_uchar;
10011debfc3dSmrg
10021debfc3dSmrg  /// atomic_short
10031debfc3dSmrg  typedef atomic<short>			atomic_short;
10041debfc3dSmrg
10051debfc3dSmrg  /// atomic_ushort
10061debfc3dSmrg  typedef atomic<unsigned short>	atomic_ushort;
10071debfc3dSmrg
10081debfc3dSmrg  /// atomic_int
10091debfc3dSmrg  typedef atomic<int>			atomic_int;
10101debfc3dSmrg
10111debfc3dSmrg  /// atomic_uint
10121debfc3dSmrg  typedef atomic<unsigned int>		atomic_uint;
10131debfc3dSmrg
10141debfc3dSmrg  /// atomic_long
10151debfc3dSmrg  typedef atomic<long>			atomic_long;
10161debfc3dSmrg
10171debfc3dSmrg  /// atomic_ulong
10181debfc3dSmrg  typedef atomic<unsigned long>		atomic_ulong;
10191debfc3dSmrg
10201debfc3dSmrg  /// atomic_llong
10211debfc3dSmrg  typedef atomic<long long>		atomic_llong;
10221debfc3dSmrg
10231debfc3dSmrg  /// atomic_ullong
10241debfc3dSmrg  typedef atomic<unsigned long long>	atomic_ullong;
10251debfc3dSmrg
10261debfc3dSmrg  /// atomic_wchar_t
10271debfc3dSmrg  typedef atomic<wchar_t>		atomic_wchar_t;
10281debfc3dSmrg
1029c0a68be4Smrg#ifdef _GLIBCXX_USE_CHAR8_T
1030c0a68be4Smrg  /// atomic_char8_t
1031c0a68be4Smrg  typedef atomic<char8_t>		atomic_char8_t;
1032c0a68be4Smrg#endif
1033c0a68be4Smrg
10341debfc3dSmrg  /// atomic_char16_t
10351debfc3dSmrg  typedef atomic<char16_t>		atomic_char16_t;
10361debfc3dSmrg
10371debfc3dSmrg  /// atomic_char32_t
10381debfc3dSmrg  typedef atomic<char32_t>		atomic_char32_t;
10391debfc3dSmrg
1040a2dc1f3fSmrg#ifdef _GLIBCXX_USE_C99_STDINT_TR1
10411debfc3dSmrg  // _GLIBCXX_RESOLVE_LIB_DEFECTS
10421debfc3dSmrg  // 2441. Exact-width atomic typedefs should be provided
10431debfc3dSmrg
10441debfc3dSmrg  /// atomic_int8_t
10451debfc3dSmrg  typedef atomic<int8_t>		atomic_int8_t;
10461debfc3dSmrg
10471debfc3dSmrg  /// atomic_uint8_t
10481debfc3dSmrg  typedef atomic<uint8_t>		atomic_uint8_t;
10491debfc3dSmrg
10501debfc3dSmrg  /// atomic_int16_t
10511debfc3dSmrg  typedef atomic<int16_t>		atomic_int16_t;
10521debfc3dSmrg
10531debfc3dSmrg  /// atomic_uint16_t
10541debfc3dSmrg  typedef atomic<uint16_t>		atomic_uint16_t;
10551debfc3dSmrg
10561debfc3dSmrg  /// atomic_int32_t
10571debfc3dSmrg  typedef atomic<int32_t>		atomic_int32_t;
10581debfc3dSmrg
10591debfc3dSmrg  /// atomic_uint32_t
10601debfc3dSmrg  typedef atomic<uint32_t>		atomic_uint32_t;
10611debfc3dSmrg
10621debfc3dSmrg  /// atomic_int64_t
10631debfc3dSmrg  typedef atomic<int64_t>		atomic_int64_t;
10641debfc3dSmrg
10651debfc3dSmrg  /// atomic_uint64_t
10661debfc3dSmrg  typedef atomic<uint64_t>		atomic_uint64_t;
10671debfc3dSmrg
10681debfc3dSmrg
10691debfc3dSmrg  /// atomic_int_least8_t
10701debfc3dSmrg  typedef atomic<int_least8_t>		atomic_int_least8_t;
10711debfc3dSmrg
10721debfc3dSmrg  /// atomic_uint_least8_t
10731debfc3dSmrg  typedef atomic<uint_least8_t>		atomic_uint_least8_t;
10741debfc3dSmrg
10751debfc3dSmrg  /// atomic_int_least16_t
10761debfc3dSmrg  typedef atomic<int_least16_t>		atomic_int_least16_t;
10771debfc3dSmrg
10781debfc3dSmrg  /// atomic_uint_least16_t
10791debfc3dSmrg  typedef atomic<uint_least16_t>	atomic_uint_least16_t;
10801debfc3dSmrg
10811debfc3dSmrg  /// atomic_int_least32_t
10821debfc3dSmrg  typedef atomic<int_least32_t>		atomic_int_least32_t;
10831debfc3dSmrg
10841debfc3dSmrg  /// atomic_uint_least32_t
10851debfc3dSmrg  typedef atomic<uint_least32_t>	atomic_uint_least32_t;
10861debfc3dSmrg
10871debfc3dSmrg  /// atomic_int_least64_t
10881debfc3dSmrg  typedef atomic<int_least64_t>		atomic_int_least64_t;
10891debfc3dSmrg
10901debfc3dSmrg  /// atomic_uint_least64_t
10911debfc3dSmrg  typedef atomic<uint_least64_t>	atomic_uint_least64_t;
10921debfc3dSmrg
10931debfc3dSmrg
10941debfc3dSmrg  /// atomic_int_fast8_t
10951debfc3dSmrg  typedef atomic<int_fast8_t>		atomic_int_fast8_t;
10961debfc3dSmrg
10971debfc3dSmrg  /// atomic_uint_fast8_t
10981debfc3dSmrg  typedef atomic<uint_fast8_t>		atomic_uint_fast8_t;
10991debfc3dSmrg
11001debfc3dSmrg  /// atomic_int_fast16_t
11011debfc3dSmrg  typedef atomic<int_fast16_t>		atomic_int_fast16_t;
11021debfc3dSmrg
11031debfc3dSmrg  /// atomic_uint_fast16_t
11041debfc3dSmrg  typedef atomic<uint_fast16_t>		atomic_uint_fast16_t;
11051debfc3dSmrg
11061debfc3dSmrg  /// atomic_int_fast32_t
11071debfc3dSmrg  typedef atomic<int_fast32_t>		atomic_int_fast32_t;
11081debfc3dSmrg
11091debfc3dSmrg  /// atomic_uint_fast32_t
11101debfc3dSmrg  typedef atomic<uint_fast32_t>		atomic_uint_fast32_t;
11111debfc3dSmrg
11121debfc3dSmrg  /// atomic_int_fast64_t
11131debfc3dSmrg  typedef atomic<int_fast64_t>		atomic_int_fast64_t;
11141debfc3dSmrg
11151debfc3dSmrg  /// atomic_uint_fast64_t
11161debfc3dSmrg  typedef atomic<uint_fast64_t>		atomic_uint_fast64_t;
1117a2dc1f3fSmrg#endif
11181debfc3dSmrg
11191debfc3dSmrg
11201debfc3dSmrg  /// atomic_intptr_t
11211debfc3dSmrg  typedef atomic<intptr_t>		atomic_intptr_t;
11221debfc3dSmrg
11231debfc3dSmrg  /// atomic_uintptr_t
11241debfc3dSmrg  typedef atomic<uintptr_t>		atomic_uintptr_t;
11251debfc3dSmrg
11261debfc3dSmrg  /// atomic_size_t
11271debfc3dSmrg  typedef atomic<size_t>		atomic_size_t;
11281debfc3dSmrg
1129a2dc1f3fSmrg  /// atomic_ptrdiff_t
1130a2dc1f3fSmrg  typedef atomic<ptrdiff_t>		atomic_ptrdiff_t;
1131a2dc1f3fSmrg
1132a2dc1f3fSmrg#ifdef _GLIBCXX_USE_C99_STDINT_TR1
11331debfc3dSmrg  /// atomic_intmax_t
11341debfc3dSmrg  typedef atomic<intmax_t>		atomic_intmax_t;
11351debfc3dSmrg
11361debfc3dSmrg  /// atomic_uintmax_t
11371debfc3dSmrg  typedef atomic<uintmax_t>		atomic_uintmax_t;
1138a2dc1f3fSmrg#endif
11391debfc3dSmrg
11401debfc3dSmrg  // Function definitions, atomic_flag operations.
11411debfc3dSmrg  inline bool
11421debfc3dSmrg  atomic_flag_test_and_set_explicit(atomic_flag* __a,
11431debfc3dSmrg				    memory_order __m) noexcept
11441debfc3dSmrg  { return __a->test_and_set(__m); }
11451debfc3dSmrg
11461debfc3dSmrg  inline bool
11471debfc3dSmrg  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
11481debfc3dSmrg				    memory_order __m) noexcept
11491debfc3dSmrg  { return __a->test_and_set(__m); }
11501debfc3dSmrg
11511debfc3dSmrg  inline void
11521debfc3dSmrg  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
11531debfc3dSmrg  { __a->clear(__m); }
11541debfc3dSmrg
11551debfc3dSmrg  inline void
11561debfc3dSmrg  atomic_flag_clear_explicit(volatile atomic_flag* __a,
11571debfc3dSmrg			     memory_order __m) noexcept
11581debfc3dSmrg  { __a->clear(__m); }
11591debfc3dSmrg
11601debfc3dSmrg  inline bool
11611debfc3dSmrg  atomic_flag_test_and_set(atomic_flag* __a) noexcept
11621debfc3dSmrg  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
11631debfc3dSmrg
11641debfc3dSmrg  inline bool
11651debfc3dSmrg  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
11661debfc3dSmrg  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
11671debfc3dSmrg
11681debfc3dSmrg  inline void
11691debfc3dSmrg  atomic_flag_clear(atomic_flag* __a) noexcept
11701debfc3dSmrg  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
11711debfc3dSmrg
11721debfc3dSmrg  inline void
11731debfc3dSmrg  atomic_flag_clear(volatile atomic_flag* __a) noexcept
11741debfc3dSmrg  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
11751debfc3dSmrg
1176*8feb0f0bSmrg  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1177*8feb0f0bSmrg  // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
1178c0a68be4Smrg  template<typename _Tp>
1179*8feb0f0bSmrg    using __atomic_val_t = __type_identity_t<_Tp>;
1180c0a68be4Smrg  template<typename _Tp>
1181c0a68be4Smrg    using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1182c0a68be4Smrg
1183c0a68be4Smrg  // [atomics.nonmembers] Non-member functions.
11841debfc3dSmrg  // Function templates generally applicable to atomic types.
11851debfc3dSmrg  template<typename _ITp>
11861debfc3dSmrg    inline bool
11871debfc3dSmrg    atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
11881debfc3dSmrg    { return __a->is_lock_free(); }
11891debfc3dSmrg
11901debfc3dSmrg  template<typename _ITp>
11911debfc3dSmrg    inline bool
11921debfc3dSmrg    atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
11931debfc3dSmrg    { return __a->is_lock_free(); }
11941debfc3dSmrg
11951debfc3dSmrg  template<typename _ITp>
11961debfc3dSmrg    inline void
1197c0a68be4Smrg    atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
11981debfc3dSmrg    { __a->store(__i, memory_order_relaxed); }
11991debfc3dSmrg
12001debfc3dSmrg  template<typename _ITp>
12011debfc3dSmrg    inline void
1202c0a68be4Smrg    atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
12031debfc3dSmrg    { __a->store(__i, memory_order_relaxed); }
12041debfc3dSmrg
12051debfc3dSmrg  template<typename _ITp>
12061debfc3dSmrg    inline void
1207c0a68be4Smrg    atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
12081debfc3dSmrg			  memory_order __m) noexcept
12091debfc3dSmrg    { __a->store(__i, __m); }
12101debfc3dSmrg
12111debfc3dSmrg  template<typename _ITp>
12121debfc3dSmrg    inline void
1213c0a68be4Smrg    atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
12141debfc3dSmrg			  memory_order __m) noexcept
12151debfc3dSmrg    { __a->store(__i, __m); }
12161debfc3dSmrg
12171debfc3dSmrg  template<typename _ITp>
12181debfc3dSmrg    inline _ITp
12191debfc3dSmrg    atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
12201debfc3dSmrg    { return __a->load(__m); }
12211debfc3dSmrg
12221debfc3dSmrg  template<typename _ITp>
12231debfc3dSmrg    inline _ITp
12241debfc3dSmrg    atomic_load_explicit(const volatile atomic<_ITp>* __a,
12251debfc3dSmrg			 memory_order __m) noexcept
12261debfc3dSmrg    { return __a->load(__m); }
12271debfc3dSmrg
12281debfc3dSmrg  template<typename _ITp>
12291debfc3dSmrg    inline _ITp
1230c0a68be4Smrg    atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
12311debfc3dSmrg			     memory_order __m) noexcept
12321debfc3dSmrg    { return __a->exchange(__i, __m); }
12331debfc3dSmrg
12341debfc3dSmrg  template<typename _ITp>
12351debfc3dSmrg    inline _ITp
1236c0a68be4Smrg    atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1237c0a68be4Smrg			     __atomic_val_t<_ITp> __i,
12381debfc3dSmrg			     memory_order __m) noexcept
12391debfc3dSmrg    { return __a->exchange(__i, __m); }
12401debfc3dSmrg
12411debfc3dSmrg  template<typename _ITp>
12421debfc3dSmrg    inline bool
12431debfc3dSmrg    atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1244c0a68be4Smrg					  __atomic_val_t<_ITp>* __i1,
1245c0a68be4Smrg					  __atomic_val_t<_ITp> __i2,
12461debfc3dSmrg					  memory_order __m1,
12471debfc3dSmrg					  memory_order __m2) noexcept
12481debfc3dSmrg    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
12491debfc3dSmrg
12501debfc3dSmrg  template<typename _ITp>
12511debfc3dSmrg    inline bool
12521debfc3dSmrg    atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1253c0a68be4Smrg					  __atomic_val_t<_ITp>* __i1,
1254c0a68be4Smrg					  __atomic_val_t<_ITp> __i2,
12551debfc3dSmrg					  memory_order __m1,
12561debfc3dSmrg					  memory_order __m2) noexcept
12571debfc3dSmrg    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
12581debfc3dSmrg
12591debfc3dSmrg  template<typename _ITp>
12601debfc3dSmrg    inline bool
12611debfc3dSmrg    atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1262c0a68be4Smrg					    __atomic_val_t<_ITp>* __i1,
1263c0a68be4Smrg					    __atomic_val_t<_ITp> __i2,
12641debfc3dSmrg					    memory_order __m1,
12651debfc3dSmrg					    memory_order __m2) noexcept
12661debfc3dSmrg    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
12671debfc3dSmrg
12681debfc3dSmrg  template<typename _ITp>
12691debfc3dSmrg    inline bool
12701debfc3dSmrg    atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1271c0a68be4Smrg					    __atomic_val_t<_ITp>* __i1,
1272c0a68be4Smrg					    __atomic_val_t<_ITp> __i2,
12731debfc3dSmrg					    memory_order __m1,
12741debfc3dSmrg					    memory_order __m2) noexcept
12751debfc3dSmrg    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
12761debfc3dSmrg
12771debfc3dSmrg
12781debfc3dSmrg  template<typename _ITp>
12791debfc3dSmrg    inline void
1280c0a68be4Smrg    atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
12811debfc3dSmrg    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
12821debfc3dSmrg
12831debfc3dSmrg  template<typename _ITp>
12841debfc3dSmrg    inline void
1285c0a68be4Smrg    atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
12861debfc3dSmrg    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
12871debfc3dSmrg
12881debfc3dSmrg  template<typename _ITp>
12891debfc3dSmrg    inline _ITp
12901debfc3dSmrg    atomic_load(const atomic<_ITp>* __a) noexcept
12911debfc3dSmrg    { return atomic_load_explicit(__a, memory_order_seq_cst); }
12921debfc3dSmrg
12931debfc3dSmrg  template<typename _ITp>
12941debfc3dSmrg    inline _ITp
12951debfc3dSmrg    atomic_load(const volatile atomic<_ITp>* __a) noexcept
12961debfc3dSmrg    { return atomic_load_explicit(__a, memory_order_seq_cst); }
12971debfc3dSmrg
12981debfc3dSmrg  template<typename _ITp>
12991debfc3dSmrg    inline _ITp
1300c0a68be4Smrg    atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
13011debfc3dSmrg    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
13021debfc3dSmrg
13031debfc3dSmrg  template<typename _ITp>
13041debfc3dSmrg    inline _ITp
1305c0a68be4Smrg    atomic_exchange(volatile atomic<_ITp>* __a,
1306c0a68be4Smrg		    __atomic_val_t<_ITp> __i) noexcept
13071debfc3dSmrg    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
13081debfc3dSmrg
13091debfc3dSmrg  template<typename _ITp>
13101debfc3dSmrg    inline bool
13111debfc3dSmrg    atomic_compare_exchange_weak(atomic<_ITp>* __a,
1312c0a68be4Smrg				 __atomic_val_t<_ITp>* __i1,
1313c0a68be4Smrg				 __atomic_val_t<_ITp> __i2) noexcept
13141debfc3dSmrg    {
13151debfc3dSmrg      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
13161debfc3dSmrg						   memory_order_seq_cst,
13171debfc3dSmrg						   memory_order_seq_cst);
13181debfc3dSmrg    }
13191debfc3dSmrg
13201debfc3dSmrg  template<typename _ITp>
13211debfc3dSmrg    inline bool
13221debfc3dSmrg    atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1323c0a68be4Smrg				 __atomic_val_t<_ITp>* __i1,
1324c0a68be4Smrg				 __atomic_val_t<_ITp> __i2) noexcept
13251debfc3dSmrg    {
13261debfc3dSmrg      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
13271debfc3dSmrg						   memory_order_seq_cst,
13281debfc3dSmrg						   memory_order_seq_cst);
13291debfc3dSmrg    }
13301debfc3dSmrg
13311debfc3dSmrg  template<typename _ITp>
13321debfc3dSmrg    inline bool
13331debfc3dSmrg    atomic_compare_exchange_strong(atomic<_ITp>* __a,
1334c0a68be4Smrg				   __atomic_val_t<_ITp>* __i1,
1335c0a68be4Smrg				   __atomic_val_t<_ITp> __i2) noexcept
13361debfc3dSmrg    {
13371debfc3dSmrg      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
13381debfc3dSmrg						     memory_order_seq_cst,
13391debfc3dSmrg						     memory_order_seq_cst);
13401debfc3dSmrg    }
13411debfc3dSmrg
13421debfc3dSmrg  template<typename _ITp>
13431debfc3dSmrg    inline bool
13441debfc3dSmrg    atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1345c0a68be4Smrg				   __atomic_val_t<_ITp>* __i1,
1346c0a68be4Smrg				   __atomic_val_t<_ITp> __i2) noexcept
13471debfc3dSmrg    {
13481debfc3dSmrg      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
13491debfc3dSmrg						     memory_order_seq_cst,
13501debfc3dSmrg						     memory_order_seq_cst);
13511debfc3dSmrg    }
13521debfc3dSmrg
1353c0a68be4Smrg  // Function templates for atomic_integral and atomic_pointer operations only.
1354c0a68be4Smrg  // Some operations (and, or, xor) are only available for atomic integrals,
1355c0a68be4Smrg  // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1356c0a68be4Smrg
13571debfc3dSmrg  template<typename _ITp>
13581debfc3dSmrg    inline _ITp
1359c0a68be4Smrg    atomic_fetch_add_explicit(atomic<_ITp>* __a,
1360c0a68be4Smrg			      __atomic_diff_t<_ITp> __i,
13611debfc3dSmrg			      memory_order __m) noexcept
13621debfc3dSmrg    { return __a->fetch_add(__i, __m); }
13631debfc3dSmrg
13641debfc3dSmrg  template<typename _ITp>
13651debfc3dSmrg    inline _ITp
1366c0a68be4Smrg    atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1367c0a68be4Smrg			      __atomic_diff_t<_ITp> __i,
13681debfc3dSmrg			      memory_order __m) noexcept
13691debfc3dSmrg    { return __a->fetch_add(__i, __m); }
13701debfc3dSmrg
13711debfc3dSmrg  template<typename _ITp>
13721debfc3dSmrg    inline _ITp
1373c0a68be4Smrg    atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1374c0a68be4Smrg			      __atomic_diff_t<_ITp> __i,
13751debfc3dSmrg			      memory_order __m) noexcept
13761debfc3dSmrg    { return __a->fetch_sub(__i, __m); }
13771debfc3dSmrg
13781debfc3dSmrg  template<typename _ITp>
13791debfc3dSmrg    inline _ITp
1380c0a68be4Smrg    atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1381c0a68be4Smrg			      __atomic_diff_t<_ITp> __i,
13821debfc3dSmrg			      memory_order __m) noexcept
13831debfc3dSmrg    { return __a->fetch_sub(__i, __m); }
13841debfc3dSmrg
13851debfc3dSmrg  template<typename _ITp>
13861debfc3dSmrg    inline _ITp
1387c0a68be4Smrg    atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1388c0a68be4Smrg			      __atomic_val_t<_ITp> __i,
13891debfc3dSmrg			      memory_order __m) noexcept
13901debfc3dSmrg    { return __a->fetch_and(__i, __m); }
13911debfc3dSmrg
13921debfc3dSmrg  template<typename _ITp>
13931debfc3dSmrg    inline _ITp
1394c0a68be4Smrg    atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1395c0a68be4Smrg			      __atomic_val_t<_ITp> __i,
13961debfc3dSmrg			      memory_order __m) noexcept
13971debfc3dSmrg    { return __a->fetch_and(__i, __m); }
13981debfc3dSmrg
13991debfc3dSmrg  template<typename _ITp>
14001debfc3dSmrg    inline _ITp
1401c0a68be4Smrg    atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1402c0a68be4Smrg			     __atomic_val_t<_ITp> __i,
14031debfc3dSmrg			     memory_order __m) noexcept
14041debfc3dSmrg    { return __a->fetch_or(__i, __m); }
14051debfc3dSmrg
14061debfc3dSmrg  template<typename _ITp>
14071debfc3dSmrg    inline _ITp
1408c0a68be4Smrg    atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1409c0a68be4Smrg			     __atomic_val_t<_ITp> __i,
14101debfc3dSmrg			     memory_order __m) noexcept
14111debfc3dSmrg    { return __a->fetch_or(__i, __m); }
14121debfc3dSmrg
14131debfc3dSmrg  template<typename _ITp>
14141debfc3dSmrg    inline _ITp
1415c0a68be4Smrg    atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1416c0a68be4Smrg			      __atomic_val_t<_ITp> __i,
14171debfc3dSmrg			      memory_order __m) noexcept
14181debfc3dSmrg    { return __a->fetch_xor(__i, __m); }
14191debfc3dSmrg
14201debfc3dSmrg  template<typename _ITp>
14211debfc3dSmrg    inline _ITp
1422c0a68be4Smrg    atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1423c0a68be4Smrg			      __atomic_val_t<_ITp> __i,
14241debfc3dSmrg			      memory_order __m) noexcept
14251debfc3dSmrg    { return __a->fetch_xor(__i, __m); }
14261debfc3dSmrg
14271debfc3dSmrg  template<typename _ITp>
14281debfc3dSmrg    inline _ITp
1429c0a68be4Smrg    atomic_fetch_add(atomic<_ITp>* __a,
1430c0a68be4Smrg		     __atomic_diff_t<_ITp> __i) noexcept
14311debfc3dSmrg    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
14321debfc3dSmrg
14331debfc3dSmrg  template<typename _ITp>
14341debfc3dSmrg    inline _ITp
1435c0a68be4Smrg    atomic_fetch_add(volatile atomic<_ITp>* __a,
1436c0a68be4Smrg		     __atomic_diff_t<_ITp> __i) noexcept
14371debfc3dSmrg    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
14381debfc3dSmrg
14391debfc3dSmrg  template<typename _ITp>
14401debfc3dSmrg    inline _ITp
1441c0a68be4Smrg    atomic_fetch_sub(atomic<_ITp>* __a,
1442c0a68be4Smrg		     __atomic_diff_t<_ITp> __i) noexcept
14431debfc3dSmrg    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
14441debfc3dSmrg
14451debfc3dSmrg  template<typename _ITp>
14461debfc3dSmrg    inline _ITp
1447c0a68be4Smrg    atomic_fetch_sub(volatile atomic<_ITp>* __a,
1448c0a68be4Smrg		     __atomic_diff_t<_ITp> __i) noexcept
14491debfc3dSmrg    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
14501debfc3dSmrg
14511debfc3dSmrg  template<typename _ITp>
14521debfc3dSmrg    inline _ITp
1453c0a68be4Smrg    atomic_fetch_and(__atomic_base<_ITp>* __a,
1454c0a68be4Smrg		     __atomic_val_t<_ITp> __i) noexcept
14551debfc3dSmrg    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
14561debfc3dSmrg
14571debfc3dSmrg  template<typename _ITp>
14581debfc3dSmrg    inline _ITp
1459c0a68be4Smrg    atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1460c0a68be4Smrg		     __atomic_val_t<_ITp> __i) noexcept
14611debfc3dSmrg    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
14621debfc3dSmrg
14631debfc3dSmrg  template<typename _ITp>
14641debfc3dSmrg    inline _ITp
1465c0a68be4Smrg    atomic_fetch_or(__atomic_base<_ITp>* __a,
1466c0a68be4Smrg		    __atomic_val_t<_ITp> __i) noexcept
14671debfc3dSmrg    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
14681debfc3dSmrg
14691debfc3dSmrg  template<typename _ITp>
14701debfc3dSmrg    inline _ITp
1471c0a68be4Smrg    atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1472c0a68be4Smrg		    __atomic_val_t<_ITp> __i) noexcept
14731debfc3dSmrg    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
14741debfc3dSmrg
14751debfc3dSmrg  template<typename _ITp>
14761debfc3dSmrg    inline _ITp
1477c0a68be4Smrg    atomic_fetch_xor(__atomic_base<_ITp>* __a,
1478c0a68be4Smrg		     __atomic_val_t<_ITp> __i) noexcept
14791debfc3dSmrg    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
14801debfc3dSmrg
14811debfc3dSmrg  template<typename _ITp>
14821debfc3dSmrg    inline _ITp
1483c0a68be4Smrg    atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1484c0a68be4Smrg		     __atomic_val_t<_ITp> __i) noexcept
14851debfc3dSmrg    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
14861debfc3dSmrg
1487*8feb0f0bSmrg#if __cplusplus > 201703L
1488*8feb0f0bSmrg#define __cpp_lib_atomic_float 201711L
1489*8feb0f0bSmrg  template<>
1490*8feb0f0bSmrg    struct atomic<float> : __atomic_float<float>
1491*8feb0f0bSmrg    {
1492*8feb0f0bSmrg      atomic() noexcept = default;
1493*8feb0f0bSmrg
1494*8feb0f0bSmrg      constexpr
1495*8feb0f0bSmrg      atomic(float __fp) noexcept : __atomic_float<float>(__fp)
1496*8feb0f0bSmrg      { }
1497*8feb0f0bSmrg
1498*8feb0f0bSmrg      atomic& operator=(const atomic&) volatile = delete;
1499*8feb0f0bSmrg      atomic& operator=(const atomic&) = delete;
1500*8feb0f0bSmrg
1501*8feb0f0bSmrg      using __atomic_float<float>::operator=;
1502*8feb0f0bSmrg    };
1503*8feb0f0bSmrg
1504*8feb0f0bSmrg  template<>
1505*8feb0f0bSmrg    struct atomic<double> : __atomic_float<double>
1506*8feb0f0bSmrg    {
1507*8feb0f0bSmrg      atomic() noexcept = default;
1508*8feb0f0bSmrg
1509*8feb0f0bSmrg      constexpr
1510*8feb0f0bSmrg      atomic(double __fp) noexcept : __atomic_float<double>(__fp)
1511*8feb0f0bSmrg      { }
1512*8feb0f0bSmrg
1513*8feb0f0bSmrg      atomic& operator=(const atomic&) volatile = delete;
1514*8feb0f0bSmrg      atomic& operator=(const atomic&) = delete;
1515*8feb0f0bSmrg
1516*8feb0f0bSmrg      using __atomic_float<double>::operator=;
1517*8feb0f0bSmrg    };
1518*8feb0f0bSmrg
1519*8feb0f0bSmrg  template<>
1520*8feb0f0bSmrg    struct atomic<long double> : __atomic_float<long double>
1521*8feb0f0bSmrg    {
1522*8feb0f0bSmrg      atomic() noexcept = default;
1523*8feb0f0bSmrg
1524*8feb0f0bSmrg      constexpr
1525*8feb0f0bSmrg      atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
1526*8feb0f0bSmrg      { }
1527*8feb0f0bSmrg
1528*8feb0f0bSmrg      atomic& operator=(const atomic&) volatile = delete;
1529*8feb0f0bSmrg      atomic& operator=(const atomic&) = delete;
1530*8feb0f0bSmrg
1531*8feb0f0bSmrg      using __atomic_float<long double>::operator=;
1532*8feb0f0bSmrg    };
1533*8feb0f0bSmrg
1534*8feb0f0bSmrg#define __cpp_lib_atomic_ref 201806L
1535*8feb0f0bSmrg
1536*8feb0f0bSmrg  /// Class template to provide atomic operations on a non-atomic variable.
1537*8feb0f0bSmrg  template<typename _Tp>
1538*8feb0f0bSmrg    struct atomic_ref : __atomic_ref<_Tp>
1539*8feb0f0bSmrg    {
1540*8feb0f0bSmrg      explicit
1541*8feb0f0bSmrg      atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
1542*8feb0f0bSmrg      { }
1543*8feb0f0bSmrg
1544*8feb0f0bSmrg      atomic_ref& operator=(const atomic_ref&) = delete;
1545*8feb0f0bSmrg
1546*8feb0f0bSmrg      atomic_ref(const atomic_ref&) = default;
1547*8feb0f0bSmrg
1548*8feb0f0bSmrg      using __atomic_ref<_Tp>::operator=;
1549*8feb0f0bSmrg    };
1550*8feb0f0bSmrg
1551*8feb0f0bSmrg#endif // C++2a
1552*8feb0f0bSmrg
1553*8feb0f0bSmrg  /// @} group atomics
15541debfc3dSmrg
15551debfc3dSmrg_GLIBCXX_END_NAMESPACE_VERSION
15561debfc3dSmrg} // namespace
15571debfc3dSmrg
15581debfc3dSmrg#endif // C++11
15591debfc3dSmrg
15601debfc3dSmrg#endif // _GLIBCXX_ATOMIC
1561