xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/atomic (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
14fee23f9Smrg// -*- C++ -*- header.
24fee23f9Smrg
3b1e83836Smrg// Copyright (C) 2008-2022 Free Software Foundation, Inc.
44fee23f9Smrg//
54fee23f9Smrg// This file is part of the GNU ISO C++ Library.  This library is free
64fee23f9Smrg// software; you can redistribute it and/or modify it under the
74fee23f9Smrg// terms of the GNU General Public License as published by the
84fee23f9Smrg// Free Software Foundation; either version 3, or (at your option)
94fee23f9Smrg// any later version.
104fee23f9Smrg
114fee23f9Smrg// This library is distributed in the hope that it will be useful,
124fee23f9Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of
134fee23f9Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144fee23f9Smrg// GNU General Public License for more details.
154fee23f9Smrg
164fee23f9Smrg// Under Section 7 of GPL version 3, you are granted additional
174fee23f9Smrg// permissions described in the GCC Runtime Library Exception, version
184fee23f9Smrg// 3.1, as published by the Free Software Foundation.
194fee23f9Smrg
204fee23f9Smrg// You should have received a copy of the GNU General Public License and
214fee23f9Smrg// a copy of the GCC Runtime Library Exception along with this program;
224fee23f9Smrg// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
234fee23f9Smrg// <http://www.gnu.org/licenses/>.
244fee23f9Smrg
2548fb7bfaSmrg/** @file include/atomic
264fee23f9Smrg *  This is a Standard C++ Library header.
274fee23f9Smrg */
284fee23f9Smrg
294fee23f9Smrg// Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
304fee23f9Smrg// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
314fee23f9Smrg
324fee23f9Smrg#ifndef _GLIBCXX_ATOMIC
334fee23f9Smrg#define _GLIBCXX_ATOMIC 1
344fee23f9Smrg
354fee23f9Smrg#pragma GCC system_header
364fee23f9Smrg
3748fb7bfaSmrg#if __cplusplus < 201103L
384fee23f9Smrg# include <bits/c++0x_warning.h>
394d5abbe8Smrg#else
404fee23f9Smrg
414fee23f9Smrg#include <bits/atomic_base.h>
424fee23f9Smrg
4348fb7bfaSmrgnamespace std _GLIBCXX_VISIBILITY(default)
4448fb7bfaSmrg{
4548fb7bfaSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION
464fee23f9Smrg
474fee23f9Smrg  /**
484fee23f9Smrg   * @addtogroup atomics
494fee23f9Smrg   * @{
504fee23f9Smrg   */
514fee23f9Smrg
52181254a7Smrg#if __cplusplus >= 201703L
53b1e83836Smrg# define __cpp_lib_atomic_is_always_lock_free 201603L
54b17d1066Smrg#endif
55b17d1066Smrg
564d5abbe8Smrg  template<typename _Tp>
574d5abbe8Smrg    struct atomic;
584d5abbe8Smrg
594d5abbe8Smrg  /// atomic<bool>
6048fb7bfaSmrg  // NB: No operators or fetch-operations for this type.
614d5abbe8Smrg  template<>
624d5abbe8Smrg  struct atomic<bool>
634fee23f9Smrg  {
64181254a7Smrg    using value_type = bool;
65181254a7Smrg
6648fb7bfaSmrg  private:
6748fb7bfaSmrg    __atomic_base<bool>	_M_base;
684fee23f9Smrg
6948fb7bfaSmrg  public:
704d5abbe8Smrg    atomic() noexcept = default;
714d5abbe8Smrg    ~atomic() noexcept = default;
724d5abbe8Smrg    atomic(const atomic&) = delete;
734d5abbe8Smrg    atomic& operator=(const atomic&) = delete;
744d5abbe8Smrg    atomic& operator=(const atomic&) volatile = delete;
754fee23f9Smrg
764d5abbe8Smrg    constexpr atomic(bool __i) noexcept : _M_base(__i) { }
774fee23f9Smrg
7848fb7bfaSmrg    bool
7948fb7bfaSmrg    operator=(bool __i) noexcept
8048fb7bfaSmrg    { return _M_base.operator=(__i); }
8148fb7bfaSmrg
8248fb7bfaSmrg    bool
8348fb7bfaSmrg    operator=(bool __i) volatile noexcept
8448fb7bfaSmrg    { return _M_base.operator=(__i); }
8548fb7bfaSmrg
8648fb7bfaSmrg    operator bool() const noexcept
8748fb7bfaSmrg    { return _M_base.load(); }
8848fb7bfaSmrg
8948fb7bfaSmrg    operator bool() const volatile noexcept
9048fb7bfaSmrg    { return _M_base.load(); }
9148fb7bfaSmrg
9248fb7bfaSmrg    bool
9348fb7bfaSmrg    is_lock_free() const noexcept { return _M_base.is_lock_free(); }
9448fb7bfaSmrg
9548fb7bfaSmrg    bool
9648fb7bfaSmrg    is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
9748fb7bfaSmrg
98181254a7Smrg#if __cplusplus >= 201703L
99b17d1066Smrg    static constexpr bool is_always_lock_free = ATOMIC_BOOL_LOCK_FREE == 2;
100b17d1066Smrg#endif
101b17d1066Smrg
10248fb7bfaSmrg    void
10348fb7bfaSmrg    store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
10448fb7bfaSmrg    { _M_base.store(__i, __m); }
10548fb7bfaSmrg
10648fb7bfaSmrg    void
10748fb7bfaSmrg    store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
10848fb7bfaSmrg    { _M_base.store(__i, __m); }
10948fb7bfaSmrg
11048fb7bfaSmrg    bool
11148fb7bfaSmrg    load(memory_order __m = memory_order_seq_cst) const noexcept
11248fb7bfaSmrg    { return _M_base.load(__m); }
11348fb7bfaSmrg
11448fb7bfaSmrg    bool
11548fb7bfaSmrg    load(memory_order __m = memory_order_seq_cst) const volatile noexcept
11648fb7bfaSmrg    { return _M_base.load(__m); }
11748fb7bfaSmrg
11848fb7bfaSmrg    bool
11948fb7bfaSmrg    exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
12048fb7bfaSmrg    { return _M_base.exchange(__i, __m); }
12148fb7bfaSmrg
12248fb7bfaSmrg    bool
12348fb7bfaSmrg    exchange(bool __i,
12448fb7bfaSmrg	     memory_order __m = memory_order_seq_cst) volatile noexcept
12548fb7bfaSmrg    { return _M_base.exchange(__i, __m); }
12648fb7bfaSmrg
12748fb7bfaSmrg    bool
12848fb7bfaSmrg    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
12948fb7bfaSmrg			  memory_order __m2) noexcept
13048fb7bfaSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
13148fb7bfaSmrg
13248fb7bfaSmrg    bool
13348fb7bfaSmrg    compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
13448fb7bfaSmrg			  memory_order __m2) volatile noexcept
13548fb7bfaSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
13648fb7bfaSmrg
13748fb7bfaSmrg    bool
13848fb7bfaSmrg    compare_exchange_weak(bool& __i1, bool __i2,
13948fb7bfaSmrg			  memory_order __m = memory_order_seq_cst) noexcept
14048fb7bfaSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
14148fb7bfaSmrg
14248fb7bfaSmrg    bool
14348fb7bfaSmrg    compare_exchange_weak(bool& __i1, bool __i2,
14448fb7bfaSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
14548fb7bfaSmrg    { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
14648fb7bfaSmrg
14748fb7bfaSmrg    bool
14848fb7bfaSmrg    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
14948fb7bfaSmrg			    memory_order __m2) noexcept
15048fb7bfaSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
15148fb7bfaSmrg
15248fb7bfaSmrg    bool
15348fb7bfaSmrg    compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
15448fb7bfaSmrg			    memory_order __m2) volatile noexcept
15548fb7bfaSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
15648fb7bfaSmrg
15748fb7bfaSmrg    bool
15848fb7bfaSmrg    compare_exchange_strong(bool& __i1, bool __i2,
15948fb7bfaSmrg			    memory_order __m = memory_order_seq_cst) noexcept
16048fb7bfaSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
16148fb7bfaSmrg
16248fb7bfaSmrg    bool
16348fb7bfaSmrg    compare_exchange_strong(bool& __i1, bool __i2,
16448fb7bfaSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
16548fb7bfaSmrg    { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
166b1e83836Smrg
167b1e83836Smrg#if __cpp_lib_atomic_wait
168b1e83836Smrg    void
169b1e83836Smrg    wait(bool __old, memory_order __m = memory_order_seq_cst) const noexcept
170b1e83836Smrg    { _M_base.wait(__old, __m); }
171b1e83836Smrg
172b1e83836Smrg    // TODO add const volatile overload
173b1e83836Smrg
174b1e83836Smrg    void
175b1e83836Smrg    notify_one() noexcept
176b1e83836Smrg    { _M_base.notify_one(); }
177b1e83836Smrg
178b1e83836Smrg    void
179b1e83836Smrg    notify_all() noexcept
180b1e83836Smrg    { _M_base.notify_all(); }
181b1e83836Smrg#endif // __cpp_lib_atomic_wait
18248fb7bfaSmrg  };
18348fb7bfaSmrg
184*0a307195Smrg/// @cond undocumented
185*0a307195Smrg#if __cpp_lib_atomic_value_initialization
186fb8a8121Smrg# define _GLIBCXX20_INIT(I) = I
187*0a307195Smrg#else
188*0a307195Smrg# define _GLIBCXX20_INIT(I)
189fb8a8121Smrg#endif
190*0a307195Smrg/// @endcond
19148fb7bfaSmrg
19248fb7bfaSmrg  /**
19348fb7bfaSmrg   *  @brief Generic atomic type, primary class template.
19448fb7bfaSmrg   *
195fb8a8121Smrg   *  @tparam _Tp  Type to be made atomic, must be trivially copyable.
19648fb7bfaSmrg   */
1974fee23f9Smrg  template<typename _Tp>
1984fee23f9Smrg    struct atomic
1994fee23f9Smrg    {
200181254a7Smrg      using value_type = _Tp;
201181254a7Smrg
2024fee23f9Smrg    private:
2034d5abbe8Smrg      // Align 1/2/4/8/16-byte types to at least their size.
2044d5abbe8Smrg      static constexpr int _S_min_alignment
2054d5abbe8Smrg	= (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
2064d5abbe8Smrg	? 0 : sizeof(_Tp);
2074d5abbe8Smrg
2084d5abbe8Smrg      static constexpr int _S_alignment
2094d5abbe8Smrg        = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
2104d5abbe8Smrg
211fb8a8121Smrg      alignas(_S_alignment) _Tp _M_i _GLIBCXX20_INIT(_Tp());
2124d5abbe8Smrg
2134d5abbe8Smrg      static_assert(__is_trivially_copyable(_Tp),
2144d5abbe8Smrg		    "std::atomic requires a trivially copyable type");
2154d5abbe8Smrg
2164d5abbe8Smrg      static_assert(sizeof(_Tp) > 0,
2174d5abbe8Smrg		    "Incomplete or zero-sized types are not supported");
2184fee23f9Smrg
219fb8a8121Smrg#if __cplusplus > 201703L
220fb8a8121Smrg      static_assert(is_copy_constructible_v<_Tp>);
221fb8a8121Smrg      static_assert(is_move_constructible_v<_Tp>);
222fb8a8121Smrg      static_assert(is_copy_assignable_v<_Tp>);
223fb8a8121Smrg      static_assert(is_move_assignable_v<_Tp>);
224fb8a8121Smrg#endif
225fb8a8121Smrg
2264fee23f9Smrg    public:
227fb8a8121Smrg      atomic() = default;
22848fb7bfaSmrg      ~atomic() noexcept = default;
2294fee23f9Smrg      atomic(const atomic&) = delete;
23048fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
2314fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
2324fee23f9Smrg
23348fb7bfaSmrg      constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
2344fee23f9Smrg
23548fb7bfaSmrg      operator _Tp() const noexcept
23648fb7bfaSmrg      { return load(); }
23748fb7bfaSmrg
23848fb7bfaSmrg      operator _Tp() const volatile noexcept
23948fb7bfaSmrg      { return load(); }
2404fee23f9Smrg
2414fee23f9Smrg      _Tp
24248fb7bfaSmrg      operator=(_Tp __i) noexcept
24348fb7bfaSmrg      { store(__i); return __i; }
24448fb7bfaSmrg
24548fb7bfaSmrg      _Tp
24648fb7bfaSmrg      operator=(_Tp __i) volatile noexcept
24748fb7bfaSmrg      { store(__i); return __i; }
2484fee23f9Smrg
2494fee23f9Smrg      bool
25048fb7bfaSmrg      is_lock_free() const noexcept
2514d5abbe8Smrg      {
2524d5abbe8Smrg	// Produce a fake, minimally aligned pointer.
2534d5abbe8Smrg	return __atomic_is_lock_free(sizeof(_M_i),
254181254a7Smrg	    reinterpret_cast<void *>(-_S_alignment));
2554d5abbe8Smrg      }
25648fb7bfaSmrg
25748fb7bfaSmrg      bool
25848fb7bfaSmrg      is_lock_free() const volatile noexcept
2594d5abbe8Smrg      {
2604d5abbe8Smrg	// Produce a fake, minimally aligned pointer.
2614d5abbe8Smrg	return __atomic_is_lock_free(sizeof(_M_i),
262181254a7Smrg	    reinterpret_cast<void *>(-_S_alignment));
2634d5abbe8Smrg      }
2644fee23f9Smrg
265181254a7Smrg#if __cplusplus >= 201703L
266b17d1066Smrg      static constexpr bool is_always_lock_free
267b17d1066Smrg	= __atomic_always_lock_free(sizeof(_M_i), 0);
268b17d1066Smrg#endif
269b17d1066Smrg
2704fee23f9Smrg      void
2714d5abbe8Smrg      store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
272b1e83836Smrg      {
273b1e83836Smrg	__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
274b1e83836Smrg      }
27548fb7bfaSmrg
27648fb7bfaSmrg      void
2774d5abbe8Smrg      store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
278b1e83836Smrg      {
279b1e83836Smrg	__atomic_store(std::__addressof(_M_i), std::__addressof(__i), int(__m));
280b1e83836Smrg      }
2814fee23f9Smrg
2824fee23f9Smrg      _Tp
2834d5abbe8Smrg      load(memory_order __m = memory_order_seq_cst) const noexcept
28448fb7bfaSmrg      {
2853f4ceed9Smrg	alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2863f4ceed9Smrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
287181254a7Smrg	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2883f4ceed9Smrg	return *__ptr;
28948fb7bfaSmrg      }
2904fee23f9Smrg
2914fee23f9Smrg      _Tp
2924d5abbe8Smrg      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
29348fb7bfaSmrg      {
2943f4ceed9Smrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
2953f4ceed9Smrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
296181254a7Smrg	__atomic_load(std::__addressof(_M_i), __ptr, int(__m));
2973f4ceed9Smrg	return *__ptr;
29848fb7bfaSmrg      }
29948fb7bfaSmrg
30048fb7bfaSmrg      _Tp
3014d5abbe8Smrg      exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
30248fb7bfaSmrg      {
3033f4ceed9Smrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
3043f4ceed9Smrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
305b17d1066Smrg	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
306181254a7Smrg			  __ptr, int(__m));
3073f4ceed9Smrg	return *__ptr;
30848fb7bfaSmrg      }
30948fb7bfaSmrg
31048fb7bfaSmrg      _Tp
31148fb7bfaSmrg      exchange(_Tp __i,
3124d5abbe8Smrg	       memory_order __m = memory_order_seq_cst) volatile noexcept
31348fb7bfaSmrg      {
3143f4ceed9Smrg        alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
3153f4ceed9Smrg	_Tp* __ptr = reinterpret_cast<_Tp*>(__buf);
316b17d1066Smrg	__atomic_exchange(std::__addressof(_M_i), std::__addressof(__i),
317181254a7Smrg			  __ptr, int(__m));
3183f4ceed9Smrg	return *__ptr;
31948fb7bfaSmrg      }
3204fee23f9Smrg
3214fee23f9Smrg      bool
32248fb7bfaSmrg      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
32348fb7bfaSmrg			    memory_order __f) noexcept
32448fb7bfaSmrg      {
325b1e83836Smrg	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
326b1e83836Smrg
327b17d1066Smrg	return __atomic_compare_exchange(std::__addressof(_M_i),
328b17d1066Smrg					 std::__addressof(__e),
329b17d1066Smrg					 std::__addressof(__i),
330181254a7Smrg					 true, int(__s), int(__f));
33148fb7bfaSmrg      }
3324fee23f9Smrg
3334fee23f9Smrg      bool
33448fb7bfaSmrg      compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
33548fb7bfaSmrg			    memory_order __f) volatile noexcept
33648fb7bfaSmrg      {
337b1e83836Smrg	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
338b1e83836Smrg
339b17d1066Smrg	return __atomic_compare_exchange(std::__addressof(_M_i),
340b17d1066Smrg					 std::__addressof(__e),
341b17d1066Smrg					 std::__addressof(__i),
342181254a7Smrg					 true, int(__s), int(__f));
34348fb7bfaSmrg      }
3444fee23f9Smrg
3454fee23f9Smrg      bool
34648fb7bfaSmrg      compare_exchange_weak(_Tp& __e, _Tp __i,
34748fb7bfaSmrg			    memory_order __m = memory_order_seq_cst) noexcept
3484d5abbe8Smrg      { return compare_exchange_weak(__e, __i, __m,
3494d5abbe8Smrg                                     __cmpexch_failure_order(__m)); }
3504fee23f9Smrg
3514fee23f9Smrg      bool
35248fb7bfaSmrg      compare_exchange_weak(_Tp& __e, _Tp __i,
35348fb7bfaSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
3544d5abbe8Smrg      { return compare_exchange_weak(__e, __i, __m,
3554d5abbe8Smrg                                     __cmpexch_failure_order(__m)); }
35648fb7bfaSmrg
35748fb7bfaSmrg      bool
35848fb7bfaSmrg      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
35948fb7bfaSmrg			      memory_order __f) noexcept
36048fb7bfaSmrg      {
361b1e83836Smrg	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
362b1e83836Smrg
363b17d1066Smrg	return __atomic_compare_exchange(std::__addressof(_M_i),
364b17d1066Smrg					 std::__addressof(__e),
365b17d1066Smrg					 std::__addressof(__i),
366181254a7Smrg					 false, int(__s), int(__f));
36748fb7bfaSmrg      }
36848fb7bfaSmrg
36948fb7bfaSmrg      bool
37048fb7bfaSmrg      compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
37148fb7bfaSmrg			      memory_order __f) volatile noexcept
37248fb7bfaSmrg      {
373b1e83836Smrg	__glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
374b1e83836Smrg
375b17d1066Smrg	return __atomic_compare_exchange(std::__addressof(_M_i),
376b17d1066Smrg					 std::__addressof(__e),
377b17d1066Smrg					 std::__addressof(__i),
378181254a7Smrg					 false, int(__s), int(__f));
37948fb7bfaSmrg      }
38048fb7bfaSmrg
38148fb7bfaSmrg      bool
38248fb7bfaSmrg      compare_exchange_strong(_Tp& __e, _Tp __i,
38348fb7bfaSmrg			       memory_order __m = memory_order_seq_cst) noexcept
3844d5abbe8Smrg      { return compare_exchange_strong(__e, __i, __m,
3854d5abbe8Smrg                                       __cmpexch_failure_order(__m)); }
38648fb7bfaSmrg
38748fb7bfaSmrg      bool
38848fb7bfaSmrg      compare_exchange_strong(_Tp& __e, _Tp __i,
38948fb7bfaSmrg		     memory_order __m = memory_order_seq_cst) volatile noexcept
3904d5abbe8Smrg      { return compare_exchange_strong(__e, __i, __m,
3914d5abbe8Smrg                                       __cmpexch_failure_order(__m)); }
392b1e83836Smrg
393b1e83836Smrg#if __cpp_lib_atomic_wait
394b1e83836Smrg    void
395b1e83836Smrg    wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
396b1e83836Smrg    {
397b1e83836Smrg      std::__atomic_wait_address_v(&_M_i, __old,
398b1e83836Smrg			 [__m, this] { return this->load(__m); });
399b1e83836Smrg    }
400b1e83836Smrg
401b1e83836Smrg    // TODO add const volatile overload
402b1e83836Smrg
403b1e83836Smrg    void
404b1e83836Smrg    notify_one() noexcept
405b1e83836Smrg    { std::__atomic_notify_address(&_M_i, false); }
406b1e83836Smrg
407b1e83836Smrg    void
408b1e83836Smrg    notify_all() noexcept
409b1e83836Smrg    { std::__atomic_notify_address(&_M_i, true); }
410b1e83836Smrg#endif // __cpp_lib_atomic_wait
411b1e83836Smrg
4124fee23f9Smrg    };
413fb8a8121Smrg#undef _GLIBCXX20_INIT
4144fee23f9Smrg
4154fee23f9Smrg  /// Partial specialization for pointer types.
4164fee23f9Smrg  template<typename _Tp>
41748fb7bfaSmrg    struct atomic<_Tp*>
4184fee23f9Smrg    {
419181254a7Smrg      using value_type = _Tp*;
420181254a7Smrg      using difference_type = ptrdiff_t;
421181254a7Smrg
42248fb7bfaSmrg      typedef _Tp* 			__pointer_type;
42348fb7bfaSmrg      typedef __atomic_base<_Tp*>	__base_type;
42448fb7bfaSmrg      __base_type			_M_b;
42548fb7bfaSmrg
42648fb7bfaSmrg      atomic() noexcept = default;
42748fb7bfaSmrg      ~atomic() noexcept = default;
4284fee23f9Smrg      atomic(const atomic&) = delete;
42948fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
4304fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
4314fee23f9Smrg
43248fb7bfaSmrg      constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
43348fb7bfaSmrg
43448fb7bfaSmrg      operator __pointer_type() const noexcept
43548fb7bfaSmrg      { return __pointer_type(_M_b); }
43648fb7bfaSmrg
43748fb7bfaSmrg      operator __pointer_type() const volatile noexcept
43848fb7bfaSmrg      { return __pointer_type(_M_b); }
43948fb7bfaSmrg
44048fb7bfaSmrg      __pointer_type
44148fb7bfaSmrg      operator=(__pointer_type __p) noexcept
44248fb7bfaSmrg      { return _M_b.operator=(__p); }
44348fb7bfaSmrg
44448fb7bfaSmrg      __pointer_type
44548fb7bfaSmrg      operator=(__pointer_type __p) volatile noexcept
44648fb7bfaSmrg      { return _M_b.operator=(__p); }
44748fb7bfaSmrg
44848fb7bfaSmrg      __pointer_type
44948fb7bfaSmrg      operator++(int) noexcept
450181254a7Smrg      {
451181254a7Smrg#if __cplusplus >= 201703L
452181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
453181254a7Smrg#endif
454181254a7Smrg	return _M_b++;
455181254a7Smrg      }
45648fb7bfaSmrg
45748fb7bfaSmrg      __pointer_type
45848fb7bfaSmrg      operator++(int) volatile noexcept
459181254a7Smrg      {
460181254a7Smrg#if __cplusplus >= 201703L
461181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
462181254a7Smrg#endif
463181254a7Smrg	return _M_b++;
464181254a7Smrg      }
46548fb7bfaSmrg
46648fb7bfaSmrg      __pointer_type
46748fb7bfaSmrg      operator--(int) noexcept
468181254a7Smrg      {
469181254a7Smrg#if __cplusplus >= 201703L
470181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
471181254a7Smrg#endif
472181254a7Smrg	return _M_b--;
473181254a7Smrg      }
47448fb7bfaSmrg
47548fb7bfaSmrg      __pointer_type
47648fb7bfaSmrg      operator--(int) volatile noexcept
477181254a7Smrg      {
478181254a7Smrg#if __cplusplus >= 201703L
479181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
480181254a7Smrg#endif
481181254a7Smrg	return _M_b--;
482181254a7Smrg      }
48348fb7bfaSmrg
48448fb7bfaSmrg      __pointer_type
48548fb7bfaSmrg      operator++() noexcept
486181254a7Smrg      {
487181254a7Smrg#if __cplusplus >= 201703L
488181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
489181254a7Smrg#endif
490181254a7Smrg	return ++_M_b;
491181254a7Smrg      }
49248fb7bfaSmrg
49348fb7bfaSmrg      __pointer_type
49448fb7bfaSmrg      operator++() volatile noexcept
495181254a7Smrg      {
496181254a7Smrg#if __cplusplus >= 201703L
497181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
498181254a7Smrg#endif
499181254a7Smrg	return ++_M_b;
500181254a7Smrg      }
50148fb7bfaSmrg
50248fb7bfaSmrg      __pointer_type
50348fb7bfaSmrg      operator--() noexcept
504181254a7Smrg      {
505181254a7Smrg#if __cplusplus >= 201703L
506181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
507181254a7Smrg#endif
508181254a7Smrg	return --_M_b;
509181254a7Smrg      }
51048fb7bfaSmrg
51148fb7bfaSmrg      __pointer_type
51248fb7bfaSmrg      operator--() volatile noexcept
513181254a7Smrg      {
514181254a7Smrg#if __cplusplus >= 201703L
515181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
516181254a7Smrg#endif
517181254a7Smrg	return --_M_b;
518181254a7Smrg      }
51948fb7bfaSmrg
52048fb7bfaSmrg      __pointer_type
52148fb7bfaSmrg      operator+=(ptrdiff_t __d) noexcept
522181254a7Smrg      {
523181254a7Smrg#if __cplusplus >= 201703L
524181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
525181254a7Smrg#endif
526181254a7Smrg	return _M_b.operator+=(__d);
527181254a7Smrg      }
52848fb7bfaSmrg
52948fb7bfaSmrg      __pointer_type
53048fb7bfaSmrg      operator+=(ptrdiff_t __d) volatile noexcept
531181254a7Smrg      {
532181254a7Smrg#if __cplusplus >= 201703L
533181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
534181254a7Smrg#endif
535181254a7Smrg	return _M_b.operator+=(__d);
536181254a7Smrg      }
53748fb7bfaSmrg
53848fb7bfaSmrg      __pointer_type
53948fb7bfaSmrg      operator-=(ptrdiff_t __d) noexcept
540181254a7Smrg      {
541181254a7Smrg#if __cplusplus >= 201703L
542181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
543181254a7Smrg#endif
544181254a7Smrg	return _M_b.operator-=(__d);
545181254a7Smrg      }
54648fb7bfaSmrg
54748fb7bfaSmrg      __pointer_type
54848fb7bfaSmrg      operator-=(ptrdiff_t __d) volatile noexcept
549181254a7Smrg      {
550181254a7Smrg#if __cplusplus >= 201703L
551181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
552181254a7Smrg#endif
553181254a7Smrg	return _M_b.operator-=(__d);
554181254a7Smrg      }
55548fb7bfaSmrg
55648fb7bfaSmrg      bool
55748fb7bfaSmrg      is_lock_free() const noexcept
55848fb7bfaSmrg      { return _M_b.is_lock_free(); }
55948fb7bfaSmrg
56048fb7bfaSmrg      bool
56148fb7bfaSmrg      is_lock_free() const volatile noexcept
56248fb7bfaSmrg      { return _M_b.is_lock_free(); }
5634fee23f9Smrg
564181254a7Smrg#if __cplusplus >= 201703L
565b1e83836Smrg      static constexpr bool is_always_lock_free
566b1e83836Smrg	= ATOMIC_POINTER_LOCK_FREE == 2;
567b17d1066Smrg#endif
568b17d1066Smrg
5694fee23f9Smrg      void
57048fb7bfaSmrg      store(__pointer_type __p,
57148fb7bfaSmrg	    memory_order __m = memory_order_seq_cst) noexcept
57248fb7bfaSmrg      { return _M_b.store(__p, __m); }
5734fee23f9Smrg
57448fb7bfaSmrg      void
57548fb7bfaSmrg      store(__pointer_type __p,
57648fb7bfaSmrg	    memory_order __m = memory_order_seq_cst) volatile noexcept
57748fb7bfaSmrg      { return _M_b.store(__p, __m); }
5784fee23f9Smrg
57948fb7bfaSmrg      __pointer_type
58048fb7bfaSmrg      load(memory_order __m = memory_order_seq_cst) const noexcept
58148fb7bfaSmrg      { return _M_b.load(__m); }
58248fb7bfaSmrg
58348fb7bfaSmrg      __pointer_type
58448fb7bfaSmrg      load(memory_order __m = memory_order_seq_cst) const volatile noexcept
58548fb7bfaSmrg      { return _M_b.load(__m); }
58648fb7bfaSmrg
58748fb7bfaSmrg      __pointer_type
58848fb7bfaSmrg      exchange(__pointer_type __p,
58948fb7bfaSmrg	       memory_order __m = memory_order_seq_cst) noexcept
59048fb7bfaSmrg      { return _M_b.exchange(__p, __m); }
59148fb7bfaSmrg
59248fb7bfaSmrg      __pointer_type
59348fb7bfaSmrg      exchange(__pointer_type __p,
59448fb7bfaSmrg	       memory_order __m = memory_order_seq_cst) volatile noexcept
59548fb7bfaSmrg      { return _M_b.exchange(__p, __m); }
5964fee23f9Smrg
5974fee23f9Smrg      bool
59848fb7bfaSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
59948fb7bfaSmrg			    memory_order __m1, memory_order __m2) noexcept
600b1e83836Smrg      { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
6014fee23f9Smrg
6024fee23f9Smrg      bool
60348fb7bfaSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
60448fb7bfaSmrg			    memory_order __m1,
60548fb7bfaSmrg			    memory_order __m2) volatile noexcept
606b1e83836Smrg      { return _M_b.compare_exchange_weak(__p1, __p2, __m1, __m2); }
6074fee23f9Smrg
6084fee23f9Smrg      bool
60948fb7bfaSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
61048fb7bfaSmrg			    memory_order __m = memory_order_seq_cst) noexcept
6114fee23f9Smrg      {
61248fb7bfaSmrg	return compare_exchange_weak(__p1, __p2, __m,
61348fb7bfaSmrg				     __cmpexch_failure_order(__m));
6144fee23f9Smrg      }
6154fee23f9Smrg
61648fb7bfaSmrg      bool
61748fb7bfaSmrg      compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
61848fb7bfaSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
6194fee23f9Smrg      {
62048fb7bfaSmrg	return compare_exchange_weak(__p1, __p2, __m,
62148fb7bfaSmrg				     __cmpexch_failure_order(__m));
62248fb7bfaSmrg      }
6234fee23f9Smrg
62448fb7bfaSmrg      bool
62548fb7bfaSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
62648fb7bfaSmrg			      memory_order __m1, memory_order __m2) noexcept
62748fb7bfaSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
6284fee23f9Smrg
62948fb7bfaSmrg      bool
63048fb7bfaSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
63148fb7bfaSmrg			      memory_order __m1,
63248fb7bfaSmrg			      memory_order __m2) volatile noexcept
63348fb7bfaSmrg      { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
6344fee23f9Smrg
63548fb7bfaSmrg      bool
63648fb7bfaSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
63748fb7bfaSmrg			      memory_order __m = memory_order_seq_cst) noexcept
63848fb7bfaSmrg      {
63948fb7bfaSmrg	return _M_b.compare_exchange_strong(__p1, __p2, __m,
64048fb7bfaSmrg					    __cmpexch_failure_order(__m));
64148fb7bfaSmrg      }
64248fb7bfaSmrg
64348fb7bfaSmrg      bool
64448fb7bfaSmrg      compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
64548fb7bfaSmrg		    memory_order __m = memory_order_seq_cst) volatile noexcept
64648fb7bfaSmrg      {
64748fb7bfaSmrg	return _M_b.compare_exchange_strong(__p1, __p2, __m,
64848fb7bfaSmrg					    __cmpexch_failure_order(__m));
64948fb7bfaSmrg      }
65048fb7bfaSmrg
651b1e83836Smrg#if __cpp_lib_atomic_wait
652b1e83836Smrg    void
653b1e83836Smrg    wait(__pointer_type __old, memory_order __m = memory_order_seq_cst) const noexcept
654b1e83836Smrg    { _M_b.wait(__old, __m); }
655b1e83836Smrg
656b1e83836Smrg    // TODO add const volatile overload
657b1e83836Smrg
658b1e83836Smrg    void
659b1e83836Smrg    notify_one() noexcept
660b1e83836Smrg    { _M_b.notify_one(); }
661b1e83836Smrg
662b1e83836Smrg    void
663b1e83836Smrg    notify_all() noexcept
664b1e83836Smrg    { _M_b.notify_all(); }
665b1e83836Smrg#endif // __cpp_lib_atomic_wait
666b1e83836Smrg
66748fb7bfaSmrg      __pointer_type
66848fb7bfaSmrg      fetch_add(ptrdiff_t __d,
66948fb7bfaSmrg		memory_order __m = memory_order_seq_cst) noexcept
670181254a7Smrg      {
671181254a7Smrg#if __cplusplus >= 201703L
672181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
673181254a7Smrg#endif
674181254a7Smrg	return _M_b.fetch_add(__d, __m);
675181254a7Smrg      }
67648fb7bfaSmrg
67748fb7bfaSmrg      __pointer_type
67848fb7bfaSmrg      fetch_add(ptrdiff_t __d,
67948fb7bfaSmrg		memory_order __m = memory_order_seq_cst) volatile noexcept
680181254a7Smrg      {
681181254a7Smrg#if __cplusplus >= 201703L
682181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
683181254a7Smrg#endif
684181254a7Smrg	return _M_b.fetch_add(__d, __m);
685181254a7Smrg      }
68648fb7bfaSmrg
68748fb7bfaSmrg      __pointer_type
68848fb7bfaSmrg      fetch_sub(ptrdiff_t __d,
68948fb7bfaSmrg		memory_order __m = memory_order_seq_cst) noexcept
690181254a7Smrg      {
691181254a7Smrg#if __cplusplus >= 201703L
692181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
693181254a7Smrg#endif
694181254a7Smrg	return _M_b.fetch_sub(__d, __m);
695181254a7Smrg      }
69648fb7bfaSmrg
69748fb7bfaSmrg      __pointer_type
69848fb7bfaSmrg      fetch_sub(ptrdiff_t __d,
69948fb7bfaSmrg		memory_order __m = memory_order_seq_cst) volatile noexcept
700181254a7Smrg      {
701181254a7Smrg#if __cplusplus >= 201703L
702181254a7Smrg	static_assert( is_object<_Tp>::value, "pointer to object type" );
703181254a7Smrg#endif
704181254a7Smrg	return _M_b.fetch_sub(__d, __m);
705181254a7Smrg      }
7064fee23f9Smrg    };
7074fee23f9Smrg
70848fb7bfaSmrg
7094fee23f9Smrg  /// Explicit specialization for char.
7104fee23f9Smrg  template<>
7114d5abbe8Smrg    struct atomic<char> : __atomic_base<char>
7124fee23f9Smrg    {
7134fee23f9Smrg      typedef char 			__integral_type;
7144d5abbe8Smrg      typedef __atomic_base<char> 	__base_type;
7154fee23f9Smrg
71648fb7bfaSmrg      atomic() noexcept = default;
71748fb7bfaSmrg      ~atomic() noexcept = default;
7184fee23f9Smrg      atomic(const atomic&) = delete;
71948fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
7204fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
7214fee23f9Smrg
72248fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7234fee23f9Smrg
7244fee23f9Smrg      using __base_type::operator __integral_type;
7254fee23f9Smrg      using __base_type::operator=;
726b17d1066Smrg
727181254a7Smrg#if __cplusplus >= 201703L
728b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
729b17d1066Smrg#endif
7304fee23f9Smrg    };
7314fee23f9Smrg
7324fee23f9Smrg  /// Explicit specialization for signed char.
7334fee23f9Smrg  template<>
7344d5abbe8Smrg    struct atomic<signed char> : __atomic_base<signed char>
7354fee23f9Smrg    {
7364fee23f9Smrg      typedef signed char 		__integral_type;
7374d5abbe8Smrg      typedef __atomic_base<signed char> 	__base_type;
7384fee23f9Smrg
73948fb7bfaSmrg      atomic() noexcept= default;
74048fb7bfaSmrg      ~atomic() noexcept = default;
7414fee23f9Smrg      atomic(const atomic&) = delete;
74248fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
7434fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
7444fee23f9Smrg
74548fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7464fee23f9Smrg
7474fee23f9Smrg      using __base_type::operator __integral_type;
7484fee23f9Smrg      using __base_type::operator=;
749b17d1066Smrg
750181254a7Smrg#if __cplusplus >= 201703L
751b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
752b17d1066Smrg#endif
7534fee23f9Smrg    };
7544fee23f9Smrg
7554fee23f9Smrg  /// Explicit specialization for unsigned char.
7564fee23f9Smrg  template<>
7574d5abbe8Smrg    struct atomic<unsigned char> : __atomic_base<unsigned char>
7584fee23f9Smrg    {
7594fee23f9Smrg      typedef unsigned char 		__integral_type;
7604d5abbe8Smrg      typedef __atomic_base<unsigned char> 	__base_type;
7614fee23f9Smrg
76248fb7bfaSmrg      atomic() noexcept= default;
76348fb7bfaSmrg      ~atomic() noexcept = default;
7644fee23f9Smrg      atomic(const atomic&) = delete;
76548fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
7664fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
7674fee23f9Smrg
76848fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7694fee23f9Smrg
7704fee23f9Smrg      using __base_type::operator __integral_type;
7714fee23f9Smrg      using __base_type::operator=;
772b17d1066Smrg
773181254a7Smrg#if __cplusplus >= 201703L
774b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_CHAR_LOCK_FREE == 2;
775b17d1066Smrg#endif
7764fee23f9Smrg    };
7774fee23f9Smrg
7784fee23f9Smrg  /// Explicit specialization for short.
7794fee23f9Smrg  template<>
7804d5abbe8Smrg    struct atomic<short> : __atomic_base<short>
7814fee23f9Smrg    {
7824fee23f9Smrg      typedef short 			__integral_type;
7834d5abbe8Smrg      typedef __atomic_base<short> 		__base_type;
7844fee23f9Smrg
78548fb7bfaSmrg      atomic() noexcept = default;
78648fb7bfaSmrg      ~atomic() noexcept = default;
7874fee23f9Smrg      atomic(const atomic&) = delete;
78848fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
7894fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
7904fee23f9Smrg
79148fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
7924fee23f9Smrg
7934fee23f9Smrg      using __base_type::operator __integral_type;
7944fee23f9Smrg      using __base_type::operator=;
795b17d1066Smrg
796181254a7Smrg#if __cplusplus >= 201703L
797b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
798b17d1066Smrg#endif
7994fee23f9Smrg    };
8004fee23f9Smrg
8014fee23f9Smrg  /// Explicit specialization for unsigned short.
8024fee23f9Smrg  template<>
8034d5abbe8Smrg    struct atomic<unsigned short> : __atomic_base<unsigned short>
8044fee23f9Smrg    {
8054fee23f9Smrg      typedef unsigned short 	      	__integral_type;
8064d5abbe8Smrg      typedef __atomic_base<unsigned short> 		__base_type;
8074fee23f9Smrg
80848fb7bfaSmrg      atomic() noexcept = default;
80948fb7bfaSmrg      ~atomic() noexcept = default;
8104fee23f9Smrg      atomic(const atomic&) = delete;
81148fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
8124fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
8134fee23f9Smrg
81448fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8154fee23f9Smrg
8164fee23f9Smrg      using __base_type::operator __integral_type;
8174fee23f9Smrg      using __base_type::operator=;
818b17d1066Smrg
819181254a7Smrg#if __cplusplus >= 201703L
820b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_SHORT_LOCK_FREE == 2;
821b17d1066Smrg#endif
8224fee23f9Smrg    };
8234fee23f9Smrg
8244fee23f9Smrg  /// Explicit specialization for int.
8254fee23f9Smrg  template<>
8264d5abbe8Smrg    struct atomic<int> : __atomic_base<int>
8274fee23f9Smrg    {
8284fee23f9Smrg      typedef int 			__integral_type;
8294d5abbe8Smrg      typedef __atomic_base<int> 		__base_type;
8304fee23f9Smrg
83148fb7bfaSmrg      atomic() noexcept = default;
83248fb7bfaSmrg      ~atomic() noexcept = default;
8334fee23f9Smrg      atomic(const atomic&) = delete;
83448fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
8354fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
8364fee23f9Smrg
83748fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8384fee23f9Smrg
8394fee23f9Smrg      using __base_type::operator __integral_type;
8404fee23f9Smrg      using __base_type::operator=;
841b17d1066Smrg
842181254a7Smrg#if __cplusplus >= 201703L
843b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
844b17d1066Smrg#endif
8454fee23f9Smrg    };
8464fee23f9Smrg
8474fee23f9Smrg  /// Explicit specialization for unsigned int.
8484fee23f9Smrg  template<>
8494d5abbe8Smrg    struct atomic<unsigned int> : __atomic_base<unsigned int>
8504fee23f9Smrg    {
8514fee23f9Smrg      typedef unsigned int		__integral_type;
8524d5abbe8Smrg      typedef __atomic_base<unsigned int> 	__base_type;
8534fee23f9Smrg
85448fb7bfaSmrg      atomic() noexcept = default;
85548fb7bfaSmrg      ~atomic() noexcept = default;
8564fee23f9Smrg      atomic(const atomic&) = delete;
85748fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
8584fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
8594fee23f9Smrg
86048fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8614fee23f9Smrg
8624fee23f9Smrg      using __base_type::operator __integral_type;
8634fee23f9Smrg      using __base_type::operator=;
864b17d1066Smrg
865181254a7Smrg#if __cplusplus >= 201703L
866b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_INT_LOCK_FREE == 2;
867b17d1066Smrg#endif
8684fee23f9Smrg    };
8694fee23f9Smrg
8704fee23f9Smrg  /// Explicit specialization for long.
8714fee23f9Smrg  template<>
8724d5abbe8Smrg    struct atomic<long> : __atomic_base<long>
8734fee23f9Smrg    {
8744fee23f9Smrg      typedef long 			__integral_type;
8754d5abbe8Smrg      typedef __atomic_base<long> 	__base_type;
8764fee23f9Smrg
87748fb7bfaSmrg      atomic() noexcept = default;
87848fb7bfaSmrg      ~atomic() noexcept = default;
8794fee23f9Smrg      atomic(const atomic&) = delete;
88048fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
8814fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
8824fee23f9Smrg
88348fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
8844fee23f9Smrg
8854fee23f9Smrg      using __base_type::operator __integral_type;
8864fee23f9Smrg      using __base_type::operator=;
887b17d1066Smrg
888181254a7Smrg#if __cplusplus >= 201703L
889b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
890b17d1066Smrg#endif
8914fee23f9Smrg    };
8924fee23f9Smrg
8934fee23f9Smrg  /// Explicit specialization for unsigned long.
8944fee23f9Smrg  template<>
8954d5abbe8Smrg    struct atomic<unsigned long> : __atomic_base<unsigned long>
8964fee23f9Smrg    {
8974fee23f9Smrg      typedef unsigned long 		__integral_type;
8984d5abbe8Smrg      typedef __atomic_base<unsigned long> 	__base_type;
8994fee23f9Smrg
90048fb7bfaSmrg      atomic() noexcept = default;
90148fb7bfaSmrg      ~atomic() noexcept = default;
9024fee23f9Smrg      atomic(const atomic&) = delete;
90348fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
9044fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
9054fee23f9Smrg
90648fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9074fee23f9Smrg
9084fee23f9Smrg      using __base_type::operator __integral_type;
9094fee23f9Smrg      using __base_type::operator=;
910b17d1066Smrg
911181254a7Smrg#if __cplusplus >= 201703L
912b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_LONG_LOCK_FREE == 2;
913b17d1066Smrg#endif
9144fee23f9Smrg    };
9154fee23f9Smrg
9164fee23f9Smrg  /// Explicit specialization for long long.
9174fee23f9Smrg  template<>
9184d5abbe8Smrg    struct atomic<long long> : __atomic_base<long long>
9194fee23f9Smrg    {
9204fee23f9Smrg      typedef long long 		__integral_type;
9214d5abbe8Smrg      typedef __atomic_base<long long> 		__base_type;
9224fee23f9Smrg
92348fb7bfaSmrg      atomic() noexcept = default;
92448fb7bfaSmrg      ~atomic() noexcept = default;
9254fee23f9Smrg      atomic(const atomic&) = delete;
92648fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
9274fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
9284fee23f9Smrg
92948fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9304fee23f9Smrg
9314fee23f9Smrg      using __base_type::operator __integral_type;
9324fee23f9Smrg      using __base_type::operator=;
933b17d1066Smrg
934181254a7Smrg#if __cplusplus >= 201703L
935b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
936b17d1066Smrg#endif
9374fee23f9Smrg    };
9384fee23f9Smrg
9394fee23f9Smrg  /// Explicit specialization for unsigned long long.
9404fee23f9Smrg  template<>
9414d5abbe8Smrg    struct atomic<unsigned long long> : __atomic_base<unsigned long long>
9424fee23f9Smrg    {
9434fee23f9Smrg      typedef unsigned long long       	__integral_type;
9444d5abbe8Smrg      typedef __atomic_base<unsigned long long> 	__base_type;
9454fee23f9Smrg
94648fb7bfaSmrg      atomic() noexcept = default;
94748fb7bfaSmrg      ~atomic() noexcept = default;
9484fee23f9Smrg      atomic(const atomic&) = delete;
94948fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
9504fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
9514fee23f9Smrg
95248fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9534fee23f9Smrg
9544fee23f9Smrg      using __base_type::operator __integral_type;
9554fee23f9Smrg      using __base_type::operator=;
956b17d1066Smrg
957181254a7Smrg#if __cplusplus >= 201703L
958b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_LLONG_LOCK_FREE == 2;
959b17d1066Smrg#endif
9604fee23f9Smrg    };
9614fee23f9Smrg
9624fee23f9Smrg  /// Explicit specialization for wchar_t.
9634fee23f9Smrg  template<>
9644d5abbe8Smrg    struct atomic<wchar_t> : __atomic_base<wchar_t>
9654fee23f9Smrg    {
9664fee23f9Smrg      typedef wchar_t 			__integral_type;
9674d5abbe8Smrg      typedef __atomic_base<wchar_t> 	__base_type;
9684fee23f9Smrg
96948fb7bfaSmrg      atomic() noexcept = default;
97048fb7bfaSmrg      ~atomic() noexcept = default;
9714fee23f9Smrg      atomic(const atomic&) = delete;
97248fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
9734fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
9744fee23f9Smrg
97548fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
9764fee23f9Smrg
9774fee23f9Smrg      using __base_type::operator __integral_type;
9784fee23f9Smrg      using __base_type::operator=;
979b17d1066Smrg
980181254a7Smrg#if __cplusplus >= 201703L
981b17d1066Smrg      static constexpr bool is_always_lock_free = ATOMIC_WCHAR_T_LOCK_FREE == 2;
982b17d1066Smrg#endif
9834fee23f9Smrg    };
9844fee23f9Smrg
985181254a7Smrg#ifdef _GLIBCXX_USE_CHAR8_T
986181254a7Smrg  /// Explicit specialization for char8_t.
987181254a7Smrg  template<>
988181254a7Smrg    struct atomic<char8_t> : __atomic_base<char8_t>
989181254a7Smrg    {
990181254a7Smrg      typedef char8_t 			__integral_type;
991181254a7Smrg      typedef __atomic_base<char8_t> 	__base_type;
992181254a7Smrg
993181254a7Smrg      atomic() noexcept = default;
994181254a7Smrg      ~atomic() noexcept = default;
995181254a7Smrg      atomic(const atomic&) = delete;
996181254a7Smrg      atomic& operator=(const atomic&) = delete;
997181254a7Smrg      atomic& operator=(const atomic&) volatile = delete;
998181254a7Smrg
999181254a7Smrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
1000181254a7Smrg
1001181254a7Smrg      using __base_type::operator __integral_type;
1002181254a7Smrg      using __base_type::operator=;
1003181254a7Smrg
1004181254a7Smrg#if __cplusplus > 201402L
1005b1e83836Smrg      static constexpr bool is_always_lock_free
1006b1e83836Smrg	= ATOMIC_CHAR8_T_LOCK_FREE == 2;
1007181254a7Smrg#endif
1008181254a7Smrg    };
1009181254a7Smrg#endif
1010181254a7Smrg
10114fee23f9Smrg  /// Explicit specialization for char16_t.
10124fee23f9Smrg  template<>
10134d5abbe8Smrg    struct atomic<char16_t> : __atomic_base<char16_t>
10144fee23f9Smrg    {
10154fee23f9Smrg      typedef char16_t 			__integral_type;
10164d5abbe8Smrg      typedef __atomic_base<char16_t> 	__base_type;
10174fee23f9Smrg
101848fb7bfaSmrg      atomic() noexcept = default;
101948fb7bfaSmrg      ~atomic() noexcept = default;
10204fee23f9Smrg      atomic(const atomic&) = delete;
102148fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
10224fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
10234fee23f9Smrg
102448fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
10254fee23f9Smrg
10264fee23f9Smrg      using __base_type::operator __integral_type;
10274fee23f9Smrg      using __base_type::operator=;
1028b17d1066Smrg
1029181254a7Smrg#if __cplusplus >= 201703L
1030b1e83836Smrg      static constexpr bool is_always_lock_free
1031b1e83836Smrg	= ATOMIC_CHAR16_T_LOCK_FREE == 2;
1032b17d1066Smrg#endif
10334fee23f9Smrg    };
10344fee23f9Smrg
10354fee23f9Smrg  /// Explicit specialization for char32_t.
10364fee23f9Smrg  template<>
10374d5abbe8Smrg    struct atomic<char32_t> : __atomic_base<char32_t>
10384fee23f9Smrg    {
10394fee23f9Smrg      typedef char32_t 			__integral_type;
10404d5abbe8Smrg      typedef __atomic_base<char32_t> 	__base_type;
10414fee23f9Smrg
104248fb7bfaSmrg      atomic() noexcept = default;
104348fb7bfaSmrg      ~atomic() noexcept = default;
10444fee23f9Smrg      atomic(const atomic&) = delete;
104548fb7bfaSmrg      atomic& operator=(const atomic&) = delete;
10464fee23f9Smrg      atomic& operator=(const atomic&) volatile = delete;
10474fee23f9Smrg
104848fb7bfaSmrg      constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
10494fee23f9Smrg
10504fee23f9Smrg      using __base_type::operator __integral_type;
10514fee23f9Smrg      using __base_type::operator=;
1052b17d1066Smrg
1053181254a7Smrg#if __cplusplus >= 201703L
1054b1e83836Smrg      static constexpr bool is_always_lock_free
1055b1e83836Smrg	= ATOMIC_CHAR32_T_LOCK_FREE == 2;
1056b17d1066Smrg#endif
10574fee23f9Smrg    };
10584fee23f9Smrg
10594fee23f9Smrg
10604d5abbe8Smrg  /// atomic_bool
10614d5abbe8Smrg  typedef atomic<bool>			atomic_bool;
10624d5abbe8Smrg
10634d5abbe8Smrg  /// atomic_char
10644d5abbe8Smrg  typedef atomic<char>			atomic_char;
10654d5abbe8Smrg
10664d5abbe8Smrg  /// atomic_schar
10674d5abbe8Smrg  typedef atomic<signed char>		atomic_schar;
10684d5abbe8Smrg
10694d5abbe8Smrg  /// atomic_uchar
10704d5abbe8Smrg  typedef atomic<unsigned char>		atomic_uchar;
10714d5abbe8Smrg
10724d5abbe8Smrg  /// atomic_short
10734d5abbe8Smrg  typedef atomic<short>			atomic_short;
10744d5abbe8Smrg
10754d5abbe8Smrg  /// atomic_ushort
10764d5abbe8Smrg  typedef atomic<unsigned short>	atomic_ushort;
10774d5abbe8Smrg
10784d5abbe8Smrg  /// atomic_int
10794d5abbe8Smrg  typedef atomic<int>			atomic_int;
10804d5abbe8Smrg
10814d5abbe8Smrg  /// atomic_uint
10824d5abbe8Smrg  typedef atomic<unsigned int>		atomic_uint;
10834d5abbe8Smrg
10844d5abbe8Smrg  /// atomic_long
10854d5abbe8Smrg  typedef atomic<long>			atomic_long;
10864d5abbe8Smrg
10874d5abbe8Smrg  /// atomic_ulong
10884d5abbe8Smrg  typedef atomic<unsigned long>		atomic_ulong;
10894d5abbe8Smrg
10904d5abbe8Smrg  /// atomic_llong
10914d5abbe8Smrg  typedef atomic<long long>		atomic_llong;
10924d5abbe8Smrg
10934d5abbe8Smrg  /// atomic_ullong
10944d5abbe8Smrg  typedef atomic<unsigned long long>	atomic_ullong;
10954d5abbe8Smrg
10964d5abbe8Smrg  /// atomic_wchar_t
10974d5abbe8Smrg  typedef atomic<wchar_t>		atomic_wchar_t;
10984d5abbe8Smrg
1099181254a7Smrg#ifdef _GLIBCXX_USE_CHAR8_T
1100181254a7Smrg  /// atomic_char8_t
1101181254a7Smrg  typedef atomic<char8_t>		atomic_char8_t;
1102181254a7Smrg#endif
1103181254a7Smrg
11044d5abbe8Smrg  /// atomic_char16_t
11054d5abbe8Smrg  typedef atomic<char16_t>		atomic_char16_t;
11064d5abbe8Smrg
11074d5abbe8Smrg  /// atomic_char32_t
11084d5abbe8Smrg  typedef atomic<char32_t>		atomic_char32_t;
11094d5abbe8Smrg
1110a3e9eb18Smrg#ifdef _GLIBCXX_USE_C99_STDINT_TR1
1111b17d1066Smrg  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1112b17d1066Smrg  // 2441. Exact-width atomic typedefs should be provided
1113b17d1066Smrg
1114b17d1066Smrg  /// atomic_int8_t
1115b17d1066Smrg  typedef atomic<int8_t>		atomic_int8_t;
1116b17d1066Smrg
1117b17d1066Smrg  /// atomic_uint8_t
1118b17d1066Smrg  typedef atomic<uint8_t>		atomic_uint8_t;
1119b17d1066Smrg
1120b17d1066Smrg  /// atomic_int16_t
1121b17d1066Smrg  typedef atomic<int16_t>		atomic_int16_t;
1122b17d1066Smrg
1123b17d1066Smrg  /// atomic_uint16_t
1124b17d1066Smrg  typedef atomic<uint16_t>		atomic_uint16_t;
1125b17d1066Smrg
1126b17d1066Smrg  /// atomic_int32_t
1127b17d1066Smrg  typedef atomic<int32_t>		atomic_int32_t;
1128b17d1066Smrg
1129b17d1066Smrg  /// atomic_uint32_t
1130b17d1066Smrg  typedef atomic<uint32_t>		atomic_uint32_t;
1131b17d1066Smrg
1132b17d1066Smrg  /// atomic_int64_t
1133b17d1066Smrg  typedef atomic<int64_t>		atomic_int64_t;
1134b17d1066Smrg
1135b17d1066Smrg  /// atomic_uint64_t
1136b17d1066Smrg  typedef atomic<uint64_t>		atomic_uint64_t;
1137b17d1066Smrg
1138b17d1066Smrg
11394d5abbe8Smrg  /// atomic_int_least8_t
11404d5abbe8Smrg  typedef atomic<int_least8_t>		atomic_int_least8_t;
11414d5abbe8Smrg
11424d5abbe8Smrg  /// atomic_uint_least8_t
11434d5abbe8Smrg  typedef atomic<uint_least8_t>		atomic_uint_least8_t;
11444d5abbe8Smrg
11454d5abbe8Smrg  /// atomic_int_least16_t
11464d5abbe8Smrg  typedef atomic<int_least16_t>		atomic_int_least16_t;
11474d5abbe8Smrg
11484d5abbe8Smrg  /// atomic_uint_least16_t
11494d5abbe8Smrg  typedef atomic<uint_least16_t>	atomic_uint_least16_t;
11504d5abbe8Smrg
11514d5abbe8Smrg  /// atomic_int_least32_t
11524d5abbe8Smrg  typedef atomic<int_least32_t>		atomic_int_least32_t;
11534d5abbe8Smrg
11544d5abbe8Smrg  /// atomic_uint_least32_t
11554d5abbe8Smrg  typedef atomic<uint_least32_t>	atomic_uint_least32_t;
11564d5abbe8Smrg
11574d5abbe8Smrg  /// atomic_int_least64_t
11584d5abbe8Smrg  typedef atomic<int_least64_t>		atomic_int_least64_t;
11594d5abbe8Smrg
11604d5abbe8Smrg  /// atomic_uint_least64_t
11614d5abbe8Smrg  typedef atomic<uint_least64_t>	atomic_uint_least64_t;
11624d5abbe8Smrg
11634d5abbe8Smrg
11644d5abbe8Smrg  /// atomic_int_fast8_t
11654d5abbe8Smrg  typedef atomic<int_fast8_t>		atomic_int_fast8_t;
11664d5abbe8Smrg
11674d5abbe8Smrg  /// atomic_uint_fast8_t
11684d5abbe8Smrg  typedef atomic<uint_fast8_t>		atomic_uint_fast8_t;
11694d5abbe8Smrg
11704d5abbe8Smrg  /// atomic_int_fast16_t
11714d5abbe8Smrg  typedef atomic<int_fast16_t>		atomic_int_fast16_t;
11724d5abbe8Smrg
11734d5abbe8Smrg  /// atomic_uint_fast16_t
11744d5abbe8Smrg  typedef atomic<uint_fast16_t>		atomic_uint_fast16_t;
11754d5abbe8Smrg
11764d5abbe8Smrg  /// atomic_int_fast32_t
11774d5abbe8Smrg  typedef atomic<int_fast32_t>		atomic_int_fast32_t;
11784d5abbe8Smrg
11794d5abbe8Smrg  /// atomic_uint_fast32_t
11804d5abbe8Smrg  typedef atomic<uint_fast32_t>		atomic_uint_fast32_t;
11814d5abbe8Smrg
11824d5abbe8Smrg  /// atomic_int_fast64_t
11834d5abbe8Smrg  typedef atomic<int_fast64_t>		atomic_int_fast64_t;
11844d5abbe8Smrg
11854d5abbe8Smrg  /// atomic_uint_fast64_t
11864d5abbe8Smrg  typedef atomic<uint_fast64_t>		atomic_uint_fast64_t;
1187a3e9eb18Smrg#endif
11884d5abbe8Smrg
11894d5abbe8Smrg
11904d5abbe8Smrg  /// atomic_intptr_t
11914d5abbe8Smrg  typedef atomic<intptr_t>		atomic_intptr_t;
11924d5abbe8Smrg
11934d5abbe8Smrg  /// atomic_uintptr_t
11944d5abbe8Smrg  typedef atomic<uintptr_t>		atomic_uintptr_t;
11954d5abbe8Smrg
11964d5abbe8Smrg  /// atomic_size_t
11974d5abbe8Smrg  typedef atomic<size_t>		atomic_size_t;
11984d5abbe8Smrg
1199a3e9eb18Smrg  /// atomic_ptrdiff_t
1200a3e9eb18Smrg  typedef atomic<ptrdiff_t>		atomic_ptrdiff_t;
1201a3e9eb18Smrg
1202a3e9eb18Smrg#ifdef _GLIBCXX_USE_C99_STDINT_TR1
12034d5abbe8Smrg  /// atomic_intmax_t
12044d5abbe8Smrg  typedef atomic<intmax_t>		atomic_intmax_t;
12054d5abbe8Smrg
12064d5abbe8Smrg  /// atomic_uintmax_t
12074d5abbe8Smrg  typedef atomic<uintmax_t>		atomic_uintmax_t;
1208a3e9eb18Smrg#endif
12094d5abbe8Smrg
121048fb7bfaSmrg  // Function definitions, atomic_flag operations.
12114fee23f9Smrg  inline bool
121248fb7bfaSmrg  atomic_flag_test_and_set_explicit(atomic_flag* __a,
121348fb7bfaSmrg				    memory_order __m) noexcept
121448fb7bfaSmrg  { return __a->test_and_set(__m); }
121548fb7bfaSmrg
121648fb7bfaSmrg  inline bool
121748fb7bfaSmrg  atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
121848fb7bfaSmrg				    memory_order __m) noexcept
12194fee23f9Smrg  { return __a->test_and_set(__m); }
12204fee23f9Smrg
1221b1e83836Smrg#if __cpp_lib_atomic_flag_test
1222b1e83836Smrg  inline bool
1223b1e83836Smrg  atomic_flag_test(const atomic_flag* __a) noexcept
1224b1e83836Smrg  { return __a->test(); }
1225b1e83836Smrg
1226b1e83836Smrg  inline bool
1227b1e83836Smrg  atomic_flag_test(const volatile atomic_flag* __a) noexcept
1228b1e83836Smrg  { return __a->test(); }
1229b1e83836Smrg
1230b1e83836Smrg  inline bool
1231b1e83836Smrg  atomic_flag_test_explicit(const atomic_flag* __a,
1232b1e83836Smrg			    memory_order __m) noexcept
1233b1e83836Smrg  { return __a->test(__m); }
1234b1e83836Smrg
1235b1e83836Smrg  inline bool
1236b1e83836Smrg  atomic_flag_test_explicit(const volatile atomic_flag* __a,
1237b1e83836Smrg			    memory_order __m) noexcept
1238b1e83836Smrg  { return __a->test(__m); }
1239b1e83836Smrg#endif
1240b1e83836Smrg
12414fee23f9Smrg  inline void
124248fb7bfaSmrg  atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
124348fb7bfaSmrg  { __a->clear(__m); }
12444fee23f9Smrg
124548fb7bfaSmrg  inline void
124648fb7bfaSmrg  atomic_flag_clear_explicit(volatile atomic_flag* __a,
124748fb7bfaSmrg			     memory_order __m) noexcept
124848fb7bfaSmrg  { __a->clear(__m); }
12494fee23f9Smrg
12504fee23f9Smrg  inline bool
125148fb7bfaSmrg  atomic_flag_test_and_set(atomic_flag* __a) noexcept
125248fb7bfaSmrg  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
125348fb7bfaSmrg
125448fb7bfaSmrg  inline bool
125548fb7bfaSmrg  atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
125648fb7bfaSmrg  { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
125748fb7bfaSmrg
125848fb7bfaSmrg  inline void
125948fb7bfaSmrg  atomic_flag_clear(atomic_flag* __a) noexcept
126048fb7bfaSmrg  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
126148fb7bfaSmrg
126248fb7bfaSmrg  inline void
126348fb7bfaSmrg  atomic_flag_clear(volatile atomic_flag* __a) noexcept
126448fb7bfaSmrg  { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
126548fb7bfaSmrg
1266b1e83836Smrg#if __cpp_lib_atomic_wait
1267b1e83836Smrg  inline void
1268b1e83836Smrg  atomic_flag_wait(atomic_flag* __a, bool __old) noexcept
1269b1e83836Smrg  { __a->wait(__old); }
1270b1e83836Smrg
1271b1e83836Smrg  inline void
1272b1e83836Smrg  atomic_flag_wait_explicit(atomic_flag* __a, bool __old,
1273b1e83836Smrg                                memory_order __m) noexcept
1274b1e83836Smrg  { __a->wait(__old, __m); }
1275b1e83836Smrg
1276b1e83836Smrg  inline void
1277b1e83836Smrg  atomic_flag_notify_one(atomic_flag* __a) noexcept
1278b1e83836Smrg  { __a->notify_one(); }
1279b1e83836Smrg
1280b1e83836Smrg  inline void
1281b1e83836Smrg  atomic_flag_notify_all(atomic_flag* __a) noexcept
1282b1e83836Smrg  { __a->notify_all(); }
1283b1e83836Smrg#endif // __cpp_lib_atomic_wait
1284b1e83836Smrg
1285b1e83836Smrg  /// @cond undocumented
1286a448f87cSmrg  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1287a448f87cSmrg  // 3220. P0558 broke conforming C++14 uses of atomic shared_ptr
1288181254a7Smrg  template<typename _Tp>
1289a448f87cSmrg    using __atomic_val_t = __type_identity_t<_Tp>;
1290181254a7Smrg  template<typename _Tp>
1291181254a7Smrg    using __atomic_diff_t = typename atomic<_Tp>::difference_type;
1292b1e83836Smrg  /// @endcond
1293181254a7Smrg
1294181254a7Smrg  // [atomics.nonmembers] Non-member functions.
129548fb7bfaSmrg  // Function templates generally applicable to atomic types.
129648fb7bfaSmrg  template<typename _ITp>
129748fb7bfaSmrg    inline bool
129848fb7bfaSmrg    atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
12994fee23f9Smrg    { return __a->is_lock_free(); }
13004fee23f9Smrg
130148fb7bfaSmrg  template<typename _ITp>
13024fee23f9Smrg    inline bool
130348fb7bfaSmrg    atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
13044fee23f9Smrg    { return __a->is_lock_free(); }
13054fee23f9Smrg
13064fee23f9Smrg  template<typename _ITp>
13074fee23f9Smrg    inline void
1308181254a7Smrg    atomic_init(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
13094d5abbe8Smrg    { __a->store(__i, memory_order_relaxed); }
131048fb7bfaSmrg
131148fb7bfaSmrg  template<typename _ITp>
131248fb7bfaSmrg    inline void
1313181254a7Smrg    atomic_init(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
13144d5abbe8Smrg    { __a->store(__i, memory_order_relaxed); }
131548fb7bfaSmrg
131648fb7bfaSmrg  template<typename _ITp>
131748fb7bfaSmrg    inline void
1318181254a7Smrg    atomic_store_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
131948fb7bfaSmrg			  memory_order __m) noexcept
132048fb7bfaSmrg    { __a->store(__i, __m); }
132148fb7bfaSmrg
132248fb7bfaSmrg  template<typename _ITp>
132348fb7bfaSmrg    inline void
1324181254a7Smrg    atomic_store_explicit(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
132548fb7bfaSmrg			  memory_order __m) noexcept
13264fee23f9Smrg    { __a->store(__i, __m); }
13274fee23f9Smrg
13284fee23f9Smrg  template<typename _ITp>
13294fee23f9Smrg    inline _ITp
133048fb7bfaSmrg    atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
13314fee23f9Smrg    { return __a->load(__m); }
13324fee23f9Smrg
13334fee23f9Smrg  template<typename _ITp>
13344fee23f9Smrg    inline _ITp
133548fb7bfaSmrg    atomic_load_explicit(const volatile atomic<_ITp>* __a,
133648fb7bfaSmrg			 memory_order __m) noexcept
133748fb7bfaSmrg    { return __a->load(__m); }
133848fb7bfaSmrg
133948fb7bfaSmrg  template<typename _ITp>
134048fb7bfaSmrg    inline _ITp
1341181254a7Smrg    atomic_exchange_explicit(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i,
134248fb7bfaSmrg			     memory_order __m) noexcept
134348fb7bfaSmrg    { return __a->exchange(__i, __m); }
134448fb7bfaSmrg
134548fb7bfaSmrg  template<typename _ITp>
134648fb7bfaSmrg    inline _ITp
1347181254a7Smrg    atomic_exchange_explicit(volatile atomic<_ITp>* __a,
1348181254a7Smrg			     __atomic_val_t<_ITp> __i,
134948fb7bfaSmrg			     memory_order __m) noexcept
13504fee23f9Smrg    { return __a->exchange(__i, __m); }
13514fee23f9Smrg
13524fee23f9Smrg  template<typename _ITp>
13534fee23f9Smrg    inline bool
135448fb7bfaSmrg    atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
1355181254a7Smrg					  __atomic_val_t<_ITp>* __i1,
1356181254a7Smrg					  __atomic_val_t<_ITp> __i2,
13574fee23f9Smrg					  memory_order __m1,
135848fb7bfaSmrg					  memory_order __m2) noexcept
135948fb7bfaSmrg    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
13604fee23f9Smrg
13614fee23f9Smrg  template<typename _ITp>
13624fee23f9Smrg    inline bool
136348fb7bfaSmrg    atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
1364181254a7Smrg					  __atomic_val_t<_ITp>* __i1,
1365181254a7Smrg					  __atomic_val_t<_ITp> __i2,
136648fb7bfaSmrg					  memory_order __m1,
136748fb7bfaSmrg					  memory_order __m2) noexcept
136848fb7bfaSmrg    { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
136948fb7bfaSmrg
137048fb7bfaSmrg  template<typename _ITp>
137148fb7bfaSmrg    inline bool
137248fb7bfaSmrg    atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
1373181254a7Smrg					    __atomic_val_t<_ITp>* __i1,
1374181254a7Smrg					    __atomic_val_t<_ITp> __i2,
137548fb7bfaSmrg					    memory_order __m1,
137648fb7bfaSmrg					    memory_order __m2) noexcept
137748fb7bfaSmrg    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
137848fb7bfaSmrg
137948fb7bfaSmrg  template<typename _ITp>
138048fb7bfaSmrg    inline bool
138148fb7bfaSmrg    atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
1382181254a7Smrg					    __atomic_val_t<_ITp>* __i1,
1383181254a7Smrg					    __atomic_val_t<_ITp> __i2,
138448fb7bfaSmrg					    memory_order __m1,
138548fb7bfaSmrg					    memory_order __m2) noexcept
138648fb7bfaSmrg    { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
138748fb7bfaSmrg
13884fee23f9Smrg
13894fee23f9Smrg  template<typename _ITp>
13904fee23f9Smrg    inline void
1391181254a7Smrg    atomic_store(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
139248fb7bfaSmrg    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
139348fb7bfaSmrg
139448fb7bfaSmrg  template<typename _ITp>
139548fb7bfaSmrg    inline void
1396181254a7Smrg    atomic_store(volatile atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
13974fee23f9Smrg    { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
13984fee23f9Smrg
13994fee23f9Smrg  template<typename _ITp>
14004fee23f9Smrg    inline _ITp
140148fb7bfaSmrg    atomic_load(const atomic<_ITp>* __a) noexcept
14024fee23f9Smrg    { return atomic_load_explicit(__a, memory_order_seq_cst); }
14034fee23f9Smrg
14044fee23f9Smrg  template<typename _ITp>
14054fee23f9Smrg    inline _ITp
140648fb7bfaSmrg    atomic_load(const volatile atomic<_ITp>* __a) noexcept
140748fb7bfaSmrg    { return atomic_load_explicit(__a, memory_order_seq_cst); }
140848fb7bfaSmrg
140948fb7bfaSmrg  template<typename _ITp>
141048fb7bfaSmrg    inline _ITp
1411181254a7Smrg    atomic_exchange(atomic<_ITp>* __a, __atomic_val_t<_ITp> __i) noexcept
141248fb7bfaSmrg    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
141348fb7bfaSmrg
141448fb7bfaSmrg  template<typename _ITp>
141548fb7bfaSmrg    inline _ITp
1416181254a7Smrg    atomic_exchange(volatile atomic<_ITp>* __a,
1417181254a7Smrg		    __atomic_val_t<_ITp> __i) noexcept
14184fee23f9Smrg    { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
14194fee23f9Smrg
14204fee23f9Smrg  template<typename _ITp>
14214fee23f9Smrg    inline bool
142248fb7bfaSmrg    atomic_compare_exchange_weak(atomic<_ITp>* __a,
1423181254a7Smrg				 __atomic_val_t<_ITp>* __i1,
1424181254a7Smrg				 __atomic_val_t<_ITp> __i2) noexcept
14254fee23f9Smrg    {
14264fee23f9Smrg      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
14274fee23f9Smrg						   memory_order_seq_cst,
14284fee23f9Smrg						   memory_order_seq_cst);
14294fee23f9Smrg    }
14304fee23f9Smrg
14314fee23f9Smrg  template<typename _ITp>
14324fee23f9Smrg    inline bool
143348fb7bfaSmrg    atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
1434181254a7Smrg				 __atomic_val_t<_ITp>* __i1,
1435181254a7Smrg				 __atomic_val_t<_ITp> __i2) noexcept
143648fb7bfaSmrg    {
143748fb7bfaSmrg      return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
143848fb7bfaSmrg						   memory_order_seq_cst,
143948fb7bfaSmrg						   memory_order_seq_cst);
144048fb7bfaSmrg    }
144148fb7bfaSmrg
144248fb7bfaSmrg  template<typename _ITp>
144348fb7bfaSmrg    inline bool
144448fb7bfaSmrg    atomic_compare_exchange_strong(atomic<_ITp>* __a,
1445181254a7Smrg				   __atomic_val_t<_ITp>* __i1,
1446181254a7Smrg				   __atomic_val_t<_ITp> __i2) noexcept
14474fee23f9Smrg    {
14484fee23f9Smrg      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
14494fee23f9Smrg						     memory_order_seq_cst,
14504fee23f9Smrg						     memory_order_seq_cst);
14514fee23f9Smrg    }
14524fee23f9Smrg
14534fee23f9Smrg  template<typename _ITp>
145448fb7bfaSmrg    inline bool
145548fb7bfaSmrg    atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
1456181254a7Smrg				   __atomic_val_t<_ITp>* __i1,
1457181254a7Smrg				   __atomic_val_t<_ITp> __i2) noexcept
145848fb7bfaSmrg    {
145948fb7bfaSmrg      return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
146048fb7bfaSmrg						     memory_order_seq_cst,
146148fb7bfaSmrg						     memory_order_seq_cst);
146248fb7bfaSmrg    }
146348fb7bfaSmrg
1464b1e83836Smrg
1465b1e83836Smrg#if __cpp_lib_atomic_wait
1466b1e83836Smrg  template<typename _Tp>
1467b1e83836Smrg    inline void
1468b1e83836Smrg    atomic_wait(const atomic<_Tp>* __a,
1469b1e83836Smrg	        typename std::atomic<_Tp>::value_type __old) noexcept
1470b1e83836Smrg    { __a->wait(__old); }
1471b1e83836Smrg
1472b1e83836Smrg  template<typename _Tp>
1473b1e83836Smrg    inline void
1474b1e83836Smrg    atomic_wait_explicit(const atomic<_Tp>* __a,
1475b1e83836Smrg			 typename std::atomic<_Tp>::value_type __old,
1476b1e83836Smrg			 std::memory_order __m) noexcept
1477b1e83836Smrg    { __a->wait(__old, __m); }
1478b1e83836Smrg
1479b1e83836Smrg  template<typename _Tp>
1480b1e83836Smrg    inline void
1481b1e83836Smrg    atomic_notify_one(atomic<_Tp>* __a) noexcept
1482b1e83836Smrg    { __a->notify_one(); }
1483b1e83836Smrg
1484b1e83836Smrg  template<typename _Tp>
1485b1e83836Smrg    inline void
1486b1e83836Smrg    atomic_notify_all(atomic<_Tp>* __a) noexcept
1487b1e83836Smrg    { __a->notify_all(); }
1488b1e83836Smrg#endif // __cpp_lib_atomic_wait
1489b1e83836Smrg
1490181254a7Smrg  // Function templates for atomic_integral and atomic_pointer operations only.
1491181254a7Smrg  // Some operations (and, or, xor) are only available for atomic integrals,
1492181254a7Smrg  // which is implemented by taking a parameter of type __atomic_base<_ITp>*.
1493181254a7Smrg
149448fb7bfaSmrg  template<typename _ITp>
14954fee23f9Smrg    inline _ITp
1496181254a7Smrg    atomic_fetch_add_explicit(atomic<_ITp>* __a,
1497181254a7Smrg			      __atomic_diff_t<_ITp> __i,
149848fb7bfaSmrg			      memory_order __m) noexcept
149948fb7bfaSmrg    { return __a->fetch_add(__i, __m); }
150048fb7bfaSmrg
150148fb7bfaSmrg  template<typename _ITp>
150248fb7bfaSmrg    inline _ITp
1503181254a7Smrg    atomic_fetch_add_explicit(volatile atomic<_ITp>* __a,
1504181254a7Smrg			      __atomic_diff_t<_ITp> __i,
150548fb7bfaSmrg			      memory_order __m) noexcept
150648fb7bfaSmrg    { return __a->fetch_add(__i, __m); }
150748fb7bfaSmrg
150848fb7bfaSmrg  template<typename _ITp>
150948fb7bfaSmrg    inline _ITp
1510181254a7Smrg    atomic_fetch_sub_explicit(atomic<_ITp>* __a,
1511181254a7Smrg			      __atomic_diff_t<_ITp> __i,
151248fb7bfaSmrg			      memory_order __m) noexcept
151348fb7bfaSmrg    { return __a->fetch_sub(__i, __m); }
151448fb7bfaSmrg
151548fb7bfaSmrg  template<typename _ITp>
151648fb7bfaSmrg    inline _ITp
1517181254a7Smrg    atomic_fetch_sub_explicit(volatile atomic<_ITp>* __a,
1518181254a7Smrg			      __atomic_diff_t<_ITp> __i,
151948fb7bfaSmrg			      memory_order __m) noexcept
152048fb7bfaSmrg    { return __a->fetch_sub(__i, __m); }
152148fb7bfaSmrg
152248fb7bfaSmrg  template<typename _ITp>
152348fb7bfaSmrg    inline _ITp
1524181254a7Smrg    atomic_fetch_and_explicit(__atomic_base<_ITp>* __a,
1525181254a7Smrg			      __atomic_val_t<_ITp> __i,
152648fb7bfaSmrg			      memory_order __m) noexcept
152748fb7bfaSmrg    { return __a->fetch_and(__i, __m); }
152848fb7bfaSmrg
152948fb7bfaSmrg  template<typename _ITp>
153048fb7bfaSmrg    inline _ITp
1531181254a7Smrg    atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a,
1532181254a7Smrg			      __atomic_val_t<_ITp> __i,
153348fb7bfaSmrg			      memory_order __m) noexcept
153448fb7bfaSmrg    { return __a->fetch_and(__i, __m); }
153548fb7bfaSmrg
153648fb7bfaSmrg  template<typename _ITp>
153748fb7bfaSmrg    inline _ITp
1538181254a7Smrg    atomic_fetch_or_explicit(__atomic_base<_ITp>* __a,
1539181254a7Smrg			     __atomic_val_t<_ITp> __i,
154048fb7bfaSmrg			     memory_order __m) noexcept
154148fb7bfaSmrg    { return __a->fetch_or(__i, __m); }
154248fb7bfaSmrg
154348fb7bfaSmrg  template<typename _ITp>
154448fb7bfaSmrg    inline _ITp
1545181254a7Smrg    atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a,
1546181254a7Smrg			     __atomic_val_t<_ITp> __i,
154748fb7bfaSmrg			     memory_order __m) noexcept
154848fb7bfaSmrg    { return __a->fetch_or(__i, __m); }
154948fb7bfaSmrg
155048fb7bfaSmrg  template<typename _ITp>
155148fb7bfaSmrg    inline _ITp
1552181254a7Smrg    atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a,
1553181254a7Smrg			      __atomic_val_t<_ITp> __i,
155448fb7bfaSmrg			      memory_order __m) noexcept
155548fb7bfaSmrg    { return __a->fetch_xor(__i, __m); }
155648fb7bfaSmrg
155748fb7bfaSmrg  template<typename _ITp>
155848fb7bfaSmrg    inline _ITp
1559181254a7Smrg    atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a,
1560181254a7Smrg			      __atomic_val_t<_ITp> __i,
156148fb7bfaSmrg			      memory_order __m) noexcept
156248fb7bfaSmrg    { return __a->fetch_xor(__i, __m); }
156348fb7bfaSmrg
156448fb7bfaSmrg  template<typename _ITp>
156548fb7bfaSmrg    inline _ITp
1566181254a7Smrg    atomic_fetch_add(atomic<_ITp>* __a,
1567181254a7Smrg		     __atomic_diff_t<_ITp> __i) noexcept
15684fee23f9Smrg    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
15694fee23f9Smrg
15704fee23f9Smrg  template<typename _ITp>
15714fee23f9Smrg    inline _ITp
1572181254a7Smrg    atomic_fetch_add(volatile atomic<_ITp>* __a,
1573181254a7Smrg		     __atomic_diff_t<_ITp> __i) noexcept
157448fb7bfaSmrg    { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
157548fb7bfaSmrg
157648fb7bfaSmrg  template<typename _ITp>
157748fb7bfaSmrg    inline _ITp
1578181254a7Smrg    atomic_fetch_sub(atomic<_ITp>* __a,
1579181254a7Smrg		     __atomic_diff_t<_ITp> __i) noexcept
15804fee23f9Smrg    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
15814fee23f9Smrg
15824fee23f9Smrg  template<typename _ITp>
15834fee23f9Smrg    inline _ITp
1584181254a7Smrg    atomic_fetch_sub(volatile atomic<_ITp>* __a,
1585181254a7Smrg		     __atomic_diff_t<_ITp> __i) noexcept
158648fb7bfaSmrg    { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
158748fb7bfaSmrg
158848fb7bfaSmrg  template<typename _ITp>
158948fb7bfaSmrg    inline _ITp
1590181254a7Smrg    atomic_fetch_and(__atomic_base<_ITp>* __a,
1591181254a7Smrg		     __atomic_val_t<_ITp> __i) noexcept
15924fee23f9Smrg    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
15934fee23f9Smrg
15944fee23f9Smrg  template<typename _ITp>
15954fee23f9Smrg    inline _ITp
1596181254a7Smrg    atomic_fetch_and(volatile __atomic_base<_ITp>* __a,
1597181254a7Smrg		     __atomic_val_t<_ITp> __i) noexcept
159848fb7bfaSmrg    { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
159948fb7bfaSmrg
160048fb7bfaSmrg  template<typename _ITp>
160148fb7bfaSmrg    inline _ITp
1602181254a7Smrg    atomic_fetch_or(__atomic_base<_ITp>* __a,
1603181254a7Smrg		    __atomic_val_t<_ITp> __i) noexcept
16044fee23f9Smrg    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
16054fee23f9Smrg
16064fee23f9Smrg  template<typename _ITp>
16074fee23f9Smrg    inline _ITp
1608181254a7Smrg    atomic_fetch_or(volatile __atomic_base<_ITp>* __a,
1609181254a7Smrg		    __atomic_val_t<_ITp> __i) noexcept
161048fb7bfaSmrg    { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
161148fb7bfaSmrg
161248fb7bfaSmrg  template<typename _ITp>
161348fb7bfaSmrg    inline _ITp
1614181254a7Smrg    atomic_fetch_xor(__atomic_base<_ITp>* __a,
1615181254a7Smrg		     __atomic_val_t<_ITp> __i) noexcept
16164fee23f9Smrg    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
16174fee23f9Smrg
161848fb7bfaSmrg  template<typename _ITp>
161948fb7bfaSmrg    inline _ITp
1620181254a7Smrg    atomic_fetch_xor(volatile __atomic_base<_ITp>* __a,
1621181254a7Smrg		     __atomic_val_t<_ITp> __i) noexcept
162248fb7bfaSmrg    { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
162348fb7bfaSmrg
1624fb8a8121Smrg#if __cplusplus > 201703L
1625fb8a8121Smrg#define __cpp_lib_atomic_float 201711L
1626fb8a8121Smrg  template<>
1627fb8a8121Smrg    struct atomic<float> : __atomic_float<float>
1628fb8a8121Smrg    {
1629fb8a8121Smrg      atomic() noexcept = default;
1630fb8a8121Smrg
1631fb8a8121Smrg      constexpr
1632fb8a8121Smrg      atomic(float __fp) noexcept : __atomic_float<float>(__fp)
1633fb8a8121Smrg      { }
1634fb8a8121Smrg
1635fb8a8121Smrg      atomic& operator=(const atomic&) volatile = delete;
1636fb8a8121Smrg      atomic& operator=(const atomic&) = delete;
1637fb8a8121Smrg
1638fb8a8121Smrg      using __atomic_float<float>::operator=;
1639fb8a8121Smrg    };
1640fb8a8121Smrg
1641fb8a8121Smrg  template<>
1642fb8a8121Smrg    struct atomic<double> : __atomic_float<double>
1643fb8a8121Smrg    {
1644fb8a8121Smrg      atomic() noexcept = default;
1645fb8a8121Smrg
1646fb8a8121Smrg      constexpr
1647fb8a8121Smrg      atomic(double __fp) noexcept : __atomic_float<double>(__fp)
1648fb8a8121Smrg      { }
1649fb8a8121Smrg
1650fb8a8121Smrg      atomic& operator=(const atomic&) volatile = delete;
1651fb8a8121Smrg      atomic& operator=(const atomic&) = delete;
1652fb8a8121Smrg
1653fb8a8121Smrg      using __atomic_float<double>::operator=;
1654fb8a8121Smrg    };
1655fb8a8121Smrg
1656fb8a8121Smrg  template<>
1657fb8a8121Smrg    struct atomic<long double> : __atomic_float<long double>
1658fb8a8121Smrg    {
1659fb8a8121Smrg      atomic() noexcept = default;
1660fb8a8121Smrg
1661fb8a8121Smrg      constexpr
1662fb8a8121Smrg      atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
1663fb8a8121Smrg      { }
1664fb8a8121Smrg
1665fb8a8121Smrg      atomic& operator=(const atomic&) volatile = delete;
1666fb8a8121Smrg      atomic& operator=(const atomic&) = delete;
1667fb8a8121Smrg
1668fb8a8121Smrg      using __atomic_float<long double>::operator=;
1669fb8a8121Smrg    };
1670fb8a8121Smrg
1671fb8a8121Smrg#define __cpp_lib_atomic_ref 201806L
1672fb8a8121Smrg
1673fb8a8121Smrg  /// Class template to provide atomic operations on a non-atomic variable.
1674fb8a8121Smrg  template<typename _Tp>
1675fb8a8121Smrg    struct atomic_ref : __atomic_ref<_Tp>
1676fb8a8121Smrg    {
1677fb8a8121Smrg      explicit
1678fb8a8121Smrg      atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
1679fb8a8121Smrg      { }
1680fb8a8121Smrg
1681fb8a8121Smrg      atomic_ref& operator=(const atomic_ref&) = delete;
1682fb8a8121Smrg
1683fb8a8121Smrg      atomic_ref(const atomic_ref&) = default;
1684fb8a8121Smrg
1685fb8a8121Smrg      using __atomic_ref<_Tp>::operator=;
1686fb8a8121Smrg    };
1687fb8a8121Smrg
1688fb8a8121Smrg#endif // C++2a
1689fb8a8121Smrg
1690a448f87cSmrg  /// @} group atomics
16914fee23f9Smrg
169248fb7bfaSmrg_GLIBCXX_END_NAMESPACE_VERSION
169348fb7bfaSmrg} // namespace
16944fee23f9Smrg
16954d5abbe8Smrg#endif // C++11
16964d5abbe8Smrg
16974d5abbe8Smrg#endif // _GLIBCXX_ATOMIC
1698