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