1//
2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3// See https://llvm.org/LICENSE.txt for license information.
4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5//
6//===----------------------------------------------------------------------===//
7
8// UNSUPPORTED: c++03, c++11, c++14, c++17
9// XFAIL: !has-64-bit-atomics
10// XFAIL: !has-1024-bit-atomics
11
12// T exchange(T, memory_order = memory_order::seq_cst) const noexcept;
13
14#include <atomic>
15#include <cassert>
16#include <concepts>
17#include <type_traits>
18
19#include "atomic_helpers.h"
20#include "test_helper.h"
21#include "test_macros.h"
22
23template <typename T>
24struct TestExchange {
25 void operator()() const {
26 {
27 T x(T(1));
28 std::atomic_ref<T> const a(x);
29
30 {
31 std::same_as<T> decltype(auto) y = a.exchange(T(2));
32 assert(y == T(1));
33 ASSERT_NOEXCEPT(a.exchange(T(2)));
34 }
35
36 {
37 std::same_as<T> decltype(auto) y = a.exchange(T(3), std::memory_order_seq_cst);
38 assert(y == T(2));
39 ASSERT_NOEXCEPT(a.exchange(T(3), std::memory_order_seq_cst));
40 }
41 }
42
43 // memory_order::release
44 {
45 auto exchange = [](std::atomic_ref<T> const& x, T, T new_val) {
46 x.exchange(new_val, std::memory_order::release);
47 };
48 auto load = [](std::atomic_ref<T> const& x) { return x.load(std::memory_order::acquire); };
49 test_acquire_release<T>(exchange, load);
50 }
51
52 // memory_order::seq_cst
53 {
54 auto exchange_no_arg = [](std::atomic_ref<T> const& x, T, T new_val) { x.exchange(new_val); };
55 auto exchange_with_order = [](std::atomic_ref<T> const& x, T, T new_val) {
56 x.exchange(new_val, std::memory_order::seq_cst);
57 };
58 auto load = [](std::atomic_ref<T> const& x) { return x.load(); };
59 test_seq_cst<T>(exchange_no_arg, load);
60 test_seq_cst<T>(exchange_with_order, load);
61 }
62 }
63};
64
65int main(int, char**) {
66 TestEachAtomicType<TestExchange>()();
67 return 0;
68}
69

source code of libcxx/test/std/atomics/atomics.ref/exchange.pass.cpp