|
1 | | -// { dg-do compile { target c++20 } } |
| 1 | +// Copyright (C) 2019-2025 Free Software Foundation, Inc. |
| 2 | +// |
| 3 | +// This file is part of the GNU ISO C++ Library. This library is free |
| 4 | +// software; you can redistribute it and/or modify it under the |
| 5 | +// terms of the GNU General Public License as published by the |
| 6 | +// Free Software Foundation; either version 3, or (at your option) |
| 7 | +// any later version. |
| 8 | + |
| 9 | +// This library is distributed in the hope that it will be useful, |
| 10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | +// GNU General Public License for more details. |
| 13 | + |
| 14 | +// You should have received a copy of the GNU General Public License along |
| 15 | +// with this library; see the file COPYING3. If not see |
| 16 | +// <http://www.gnu.org/licenses/>. |
| 17 | + |
| 18 | +// { dg-do run { target c++20 } } |
| 19 | +// { dg-require-atomic-cmpxchg-word "" } |
| 20 | +// { dg-add-options libatomic } |
2 | 21 |
|
3 | 22 | #include <atomic> |
| 23 | +#include <testsuite_hooks.h> |
| 24 | + |
| 25 | +void |
| 26 | +test01() |
| 27 | +{ |
| 28 | + bool value; |
| 29 | + |
| 30 | + { |
| 31 | + const auto mo = std::memory_order_relaxed; |
| 32 | + std::atomic_ref<bool> a(value); |
| 33 | + bool ok = a.is_lock_free(); |
| 34 | + if constexpr (std::atomic_ref<bool>::is_always_lock_free) |
| 35 | + VERIFY( ok ); |
| 36 | + a = false; |
| 37 | + VERIFY( !a.load() ); |
| 38 | + VERIFY( !a.load(mo) ); |
| 39 | + a.store(true); |
| 40 | + VERIFY( a.load() ); |
| 41 | + auto v = a.exchange(false); |
| 42 | + VERIFY( !a.load() ); |
| 43 | + VERIFY( v ); |
| 44 | + v = a.exchange(true, mo); |
| 45 | + VERIFY( a.load() ); |
| 46 | + VERIFY( !v ); |
| 47 | + |
| 48 | + auto expected = a.load(); |
| 49 | + while (!a.compare_exchange_weak(expected, false, mo, mo)) |
| 50 | + { /* weak form can fail spuriously */ } |
| 51 | + VERIFY( !a.load() ); |
| 52 | + VERIFY( expected ); |
| 53 | + |
| 54 | + ok = a.compare_exchange_strong(expected, true); |
| 55 | + VERIFY( !ok && !a.load() && !expected ); |
| 56 | + |
| 57 | + ok = a.compare_exchange_strong(expected, true); |
| 58 | + VERIFY( ok && a.load() && !expected ); |
| 59 | + } |
| 60 | +} |
| 61 | + |
| 62 | +void |
| 63 | +test02() |
| 64 | +{ |
| 65 | + bool b = false; |
| 66 | + std::atomic_ref<bool> a0(b); |
| 67 | + std::atomic_ref<bool> a1(b); |
| 68 | + std::atomic_ref<const bool> a1c(b); |
| 69 | + std::atomic_ref<volatile bool> a1v(b); |
| 70 | + std::atomic_ref<const volatile bool> a1cv(b); |
| 71 | + std::atomic_ref<bool> a2(a0); |
| 72 | + b = true; |
| 73 | + VERIFY( a1.load() ); |
| 74 | + VERIFY( a1c.load() ); |
| 75 | + VERIFY( a1v.load() ); |
| 76 | + VERIFY( a1cv.load() ); |
| 77 | + VERIFY( a2.load() ); |
| 78 | +} |
4 | 79 |
|
5 | | -template<class T> concept has_and = requires (T& a) { a &= false; }; |
6 | | -template<class T> concept has_or = requires (T& a) { a |= false; }; |
7 | | -template<class T> concept has_xor = requires (T& a) { a ^= false; }; |
8 | | -template<class T> concept has_fetch_add = requires (T& a) { a.fetch_add(true); }; |
9 | | -template<class T> concept has_fetch_sub = requires (T& a) { a.fetch_sub(true); }; |
10 | | - |
11 | | -static_assert( not has_and<std::atomic_ref<bool>> ); |
12 | | -static_assert( not has_or<std::atomic_ref<bool>> ); |
13 | | -static_assert( not has_xor<std::atomic_ref<bool>> ); |
14 | | -static_assert( not has_fetch_add<std::atomic_ref<bool>> ); |
15 | | -static_assert( not has_fetch_sub<std::atomic_ref<bool>> ); |
| 80 | +int |
| 81 | +main() |
| 82 | +{ |
| 83 | + test01(); |
| 84 | + test02(); |
| 85 | +} |
0 commit comments