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
9// UNSUPPORTED: c++03
10
11// XFAIL: availability-synchronization_library-missing
12
13// <atomic>
14
15// Tests the basic features and makes sure they work with a hijacking operator&.
16
17// template<class T> struct atomic {
18// using value_type = T;
19//
20// static constexpr bool is_always_lock_free = implementation-defined;
21// bool is_lock_free() const volatile noexcept;
22// bool is_lock_free() const noexcept;
23//
24// // [atomics.types.operations], operations on atomic types
25// constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
26// constexpr atomic(T) noexcept;
27// atomic(const atomic&) = delete;
28// atomic& operator=(const atomic&) = delete;
29// atomic& operator=(const atomic&) volatile = delete;
30//
31// T load(memory_order = memory_order::seq_cst) const volatile noexcept;
32// T load(memory_order = memory_order::seq_cst) const noexcept;
33// operator T() const volatile noexcept;
34// operator T() const noexcept;
35// void store(T, memory_order = memory_order::seq_cst) volatile noexcept;
36// void store(T, memory_order = memory_order::seq_cst) noexcept;
37// T operator=(T) volatile noexcept;
38// T operator=(T) noexcept;
39//
40// T exchange(T, memory_order = memory_order::seq_cst) volatile noexcept;
41// T exchange(T, memory_order = memory_order::seq_cst) noexcept;
42// bool compare_exchange_weak(T&, T, memory_order, memory_order) volatile noexcept;
43// bool compare_exchange_weak(T&, T, memory_order, memory_order) noexcept;
44// bool compare_exchange_strong(T&, T, memory_order, memory_order) volatile noexcept;
45// bool compare_exchange_strong(T&, T, memory_order, memory_order) noexcept;
46// bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
47// bool compare_exchange_weak(T&, T, memory_order = memory_order::seq_cst) noexcept;
48// bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) volatile noexcept;
49// bool compare_exchange_strong(T&, T, memory_order = memory_order::seq_cst) noexcept;
50//
51// void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
52// void wait(T, memory_order = memory_order::seq_cst) const noexcept;
53// void notify_one() volatile noexcept;
54// void notify_one() noexcept;
55// void notify_all() volatile noexcept;
56// void notify_all() noexcept;
57// };
58
59#include <atomic>
60#include <type_traits>
61
62#include "operator_hijacker.h"
63#include "test_macros.h"
64
65template <class T>
66void test() {
67 T a;
68 typename T::value_type v;
69#if TEST_STD_VER >= 20
70 std::memory_order m = std::memory_order::seq_cst;
71#else
72 std::memory_order m = std::memory_order_seq_cst;
73#endif
74
75 TEST_IGNORE_NODISCARD a.is_lock_free();
76
77 TEST_DIAGNOSTIC_PUSH
78 // MSVC warning C4197: 'volatile std::atomic<operator_hijacker>': top-level volatile in cast is ignored
79 TEST_MSVC_DIAGNOSTIC_IGNORED(4197)
80
81 TEST_IGNORE_NODISCARD T();
82 TEST_IGNORE_NODISCARD T(v);
83
84 TEST_DIAGNOSTIC_POP
85
86 TEST_IGNORE_NODISCARD a.load();
87 TEST_IGNORE_NODISCARD static_cast<typename T::value_type>(a);
88 a.store(v);
89 a = v;
90
91 TEST_IGNORE_NODISCARD a.exchange(v);
92 TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v, m, m);
93 TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m, m);
94 TEST_IGNORE_NODISCARD a.compare_exchange_weak(v, v);
95 TEST_IGNORE_NODISCARD a.compare_exchange_strong(v, v, m);
96
97 a.wait(v);
98 a.notify_one();
99 a.notify_all();
100}
101
102void test() {
103 test<std::atomic<operator_hijacker>>();
104 test<volatile std::atomic<operator_hijacker>>();
105}
106

source code of libcxx/test/std/atomics/atomics.types.generic/general.compile.pass.cpp