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
19#include "test_helper.h"
20#include "test_macros.h"
21
22template <class T>
23concept HasVolatileAssign = requires(volatile std::atomic<T>& a, T t) { a = t; };
24
25template <class T, template <class> class MaybeVolatile = std::type_identity_t>
26void test_impl() {
27 static_assert(HasVolatileAssign<T> == std::atomic<T>::is_always_lock_free);
28
29 static_assert(noexcept(std::declval<MaybeVolatile<std::atomic<T>>&>() = (T(0))));
30
31 // assignment
32 {
33 MaybeVolatile<std::atomic<T>> a(T(3.1));
34 std::same_as<T> decltype(auto) r = (a = T(1.2));
35 assert(a.load() == T(1.2));
36 assert(r == T(1.2));
37 }
38
39 // memory_order::seq_cst
40 {
41 auto assign = [](MaybeVolatile<std::atomic<T>>& x, T, T new_val) { x = new_val; };
42 auto load = [](MaybeVolatile<std::atomic<T>>& x) { return x.load(); };
43 test_seq_cst<T, MaybeVolatile>(assign, load);
44 }
45}
46
47template <class T>
48void test() {
49 test_impl<T>();
50 if constexpr (std::atomic<T>::is_always_lock_free) {
51 test_impl<T, std::add_volatile_t>();
52 }
53}
54
55int main(int, char**) {
56 test<float>();
57 test<double>();
58 // TODO https://github.com/llvm/llvm-project/issues/47978
59 // test<long double>();
60
61 return 0;
62}
63

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