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