1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// UNSUPPORTED: c++03, c++11, c++14, c++17
9// XFAIL: !has-64-bit-atomics
10
11// floating-point-type operator=(floating-point-type) volatile noexcept;
12// floating-point-type operator=(floating-point-type) noexcept;
13
14#include <atomic>
15#include <cassert>
16#include <concepts>
17#include <type_traits>
18#include <utility>
19
20#include "test_helper.h"
21#include "test_macros.h"
22
23template <class T>
24concept HasVolatileAssign = requires(volatile std::atomic<T>& a, T t) { a = t; };
25
26template <class T, template <class> class MaybeVolatile = std::type_identity_t>
27void test_impl() {
28 static_assert(HasVolatileAssign<T> == std::atomic<T>::is_always_lock_free);
29
30 static_assert(noexcept(std::declval<MaybeVolatile<std::atomic<T>>&>() = (T(0))));
31
32 // assignment
33 {
34 MaybeVolatile<std::atomic<T>> a(T(3.1));
35 std::same_as<T> decltype(auto) r = (a = T(1.2));
36 assert(a.load() == T(1.2));
37 assert(r == T(1.2));
38 }
39
40 // memory_order::seq_cst
41 {
42 auto assign = [](MaybeVolatile<std::atomic<T>>& x, T, T new_val) { x = new_val; };
43 auto load = [](MaybeVolatile<std::atomic<T>>& x) { return x.load(); };
44 test_seq_cst<T, MaybeVolatile>(assign, load);
45 }
46}
47
48template <class T>
49void test() {
50 test_impl<T>();
51 if constexpr (std::atomic<T>::is_always_lock_free) {
52 test_impl<T, std::add_volatile_t>();
53 }
54}
55
56int main(int, char**) {
57 test<float>();
58 test<double>();
59 // TODO https://github.com/llvm/llvm-project/issues/47978
60 // test<long double>();
61
62 return 0;
63}
64

source code of libcxx/test/std/atomics/atomics.types.generic/atomics.types.float/assign.pass.cpp