xref: /llvm-project/libcxx/test/std/atomics/atomics.types.generic/bool.pass.cpp (revision 208a6d97f56fc36da6833a0e14e5847b7d84322e)
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 // <atomic>
10 
11 // template <class T>
12 // struct atomic
13 // {
14 //     bool is_lock_free() const volatile;
15 //     bool is_lock_free() const;
16 //     void store(T desr, memory_order m = memory_order_seq_cst) volatile;
17 //     void store(T desr, memory_order m = memory_order_seq_cst);
18 //     T load(memory_order m = memory_order_seq_cst) const volatile;
19 //     T load(memory_order m = memory_order_seq_cst) const;
20 //     operator T() const volatile;
21 //     operator T() const;
22 //     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile;
23 //     T exchange(T desr, memory_order m = memory_order_seq_cst);
24 //     bool compare_exchange_weak(T& expc, T desr,
25 //                                memory_order s, memory_order f) volatile;
26 //     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f);
27 //     bool compare_exchange_strong(T& expc, T desr,
28 //                                  memory_order s, memory_order f) volatile;
29 //     bool compare_exchange_strong(T& expc, T desr,
30 //                                  memory_order s, memory_order f);
31 //     bool compare_exchange_weak(T& expc, T desr,
32 //                                memory_order m = memory_order_seq_cst) volatile;
33 //     bool compare_exchange_weak(T& expc, T desr,
34 //                                memory_order m = memory_order_seq_cst);
35 //     bool compare_exchange_strong(T& expc, T desr,
36 //                                 memory_order m = memory_order_seq_cst) volatile;
37 //     bool compare_exchange_strong(T& expc, T desr,
38 //                                  memory_order m = memory_order_seq_cst);
39 //
40 //     atomic() = default;
41 //     constexpr atomic(T desr);
42 //     atomic(const atomic&) = delete;
43 //     atomic& operator=(const atomic&) = delete;
44 //     atomic& operator=(const atomic&) volatile = delete;
45 //     T operator=(T) volatile;
46 //     T operator=(T);
47 // };
48 //
49 // typedef atomic<bool> atomic_bool;
50 
51 #include <atomic>
52 #include <new>
53 #include <cassert>
54 
55 #include <cmpxchg_loop.h>
56 
57 #include "test_macros.h"
58 
main(int,char **)59 int main(int, char**)
60 {
61     {
62         volatile std::atomic<bool> obj(true);
63         assert(obj == true);
64         {
65             bool lockfree = obj.is_lock_free();
66             (void)lockfree;
67 #if TEST_STD_VER >= 17
68             if (std::atomic<bool>::is_always_lock_free)
69                 assert(lockfree);
70 #endif
71         }
72         obj.store(false);
73         assert(obj == false);
74         obj.store(true, std::memory_order_release);
75         assert(obj == true);
76         assert(obj.load() == true);
77         assert(obj.load(std::memory_order_acquire) == true);
78         assert(obj.exchange(false) == true);
79         assert(obj == false);
80         assert(obj.exchange(true, std::memory_order_relaxed) == false);
81         assert(obj == true);
82         bool x = obj;
83         assert(cmpxchg_weak_loop(obj, x, false) == true);
84         assert(obj == false);
85         assert(x == true);
86         assert(obj.compare_exchange_weak(x, true,
87                                          std::memory_order_seq_cst) == false);
88         assert(obj == false);
89         assert(x == false);
90         obj.store(true);
91         x = true;
92         assert(cmpxchg_weak_loop(obj, x, false,
93                                  std::memory_order_seq_cst,
94                                  std::memory_order_seq_cst) == true);
95         assert(obj == false);
96         assert(x == true);
97         x = true;
98         obj.store(true);
99         assert(obj.compare_exchange_strong(x, false) == true);
100         assert(obj == false);
101         assert(x == true);
102         assert(obj.compare_exchange_strong(x, true,
103                                          std::memory_order_seq_cst) == false);
104         assert(obj == false);
105         assert(x == false);
106         x = true;
107         obj.store(true);
108         assert(obj.compare_exchange_strong(x, false,
109                                            std::memory_order_seq_cst,
110                                            std::memory_order_seq_cst) == true);
111         assert(obj == false);
112         assert(x == true);
113         assert((obj = false) == false);
114         assert(obj == false);
115         assert((obj = true) == true);
116         assert(obj == true);
117     }
118     {
119         std::atomic<bool> obj(true);
120         assert(obj == true);
121         {
122             bool lockfree = obj.is_lock_free();
123             (void)lockfree;
124 #if TEST_STD_VER >= 17
125             if (std::atomic<bool>::is_always_lock_free)
126                 assert(lockfree);
127 #endif
128         }
129         obj.store(false);
130         assert(obj == false);
131         obj.store(true, std::memory_order_release);
132         assert(obj == true);
133         assert(obj.load() == true);
134         assert(obj.load(std::memory_order_acquire) == true);
135         assert(obj.exchange(false) == true);
136         assert(obj == false);
137         assert(obj.exchange(true, std::memory_order_relaxed) == false);
138         assert(obj == true);
139         bool x = obj;
140         assert(cmpxchg_weak_loop(obj, x, false) == true);
141         assert(obj == false);
142         assert(x == true);
143         assert(obj.compare_exchange_weak(x, true,
144                                          std::memory_order_seq_cst) == false);
145         assert(obj == false);
146         assert(x == false);
147         obj.store(true);
148         x = true;
149         assert(cmpxchg_weak_loop(obj, x, false,
150                                  std::memory_order_seq_cst,
151                                  std::memory_order_seq_cst) == true);
152         assert(obj == false);
153         assert(x == true);
154         x = true;
155         obj.store(true);
156         assert(obj.compare_exchange_strong(x, false) == true);
157         assert(obj == false);
158         assert(x == true);
159         assert(obj.compare_exchange_strong(x, true,
160                                          std::memory_order_seq_cst) == false);
161         assert(obj == false);
162         assert(x == false);
163         x = true;
164         obj.store(true);
165         assert(obj.compare_exchange_strong(x, false,
166                                            std::memory_order_seq_cst,
167                                            std::memory_order_seq_cst) == true);
168         assert(obj == false);
169         assert(x == true);
170         assert((obj = false) == false);
171         assert(obj == false);
172         assert((obj = true) == true);
173         assert(obj == true);
174     }
175     {
176         std::atomic_bool obj(true);
177         assert(obj == true);
178         {
179             bool lockfree = obj.is_lock_free();
180             (void)lockfree;
181 #if TEST_STD_VER >= 17
182             if (std::atomic_bool::is_always_lock_free)
183                 assert(lockfree);
184 #endif
185         }
186         obj.store(false);
187         assert(obj == false);
188         obj.store(true, std::memory_order_release);
189         assert(obj == true);
190         assert(obj.load() == true);
191         assert(obj.load(std::memory_order_acquire) == true);
192         assert(obj.exchange(false) == true);
193         assert(obj == false);
194         assert(obj.exchange(true, std::memory_order_relaxed) == false);
195         assert(obj == true);
196         bool x = obj;
197         assert(cmpxchg_weak_loop(obj, x, false) == true);
198         assert(obj == false);
199         assert(x == true);
200         assert(obj.compare_exchange_weak(x, true,
201                                          std::memory_order_seq_cst) == false);
202         assert(obj == false);
203         assert(x == false);
204         obj.store(true);
205         x = true;
206         assert(cmpxchg_weak_loop(obj, x, false,
207                                  std::memory_order_seq_cst,
208                                  std::memory_order_seq_cst) == true);
209         assert(obj == false);
210         assert(x == true);
211         x = true;
212         obj.store(true);
213         assert(obj.compare_exchange_strong(x, false) == true);
214         assert(obj == false);
215         assert(x == true);
216         assert(obj.compare_exchange_strong(x, true,
217                                          std::memory_order_seq_cst) == false);
218         assert(obj == false);
219         assert(x == false);
220         x = true;
221         obj.store(true);
222         assert(obj.compare_exchange_strong(x, false,
223                                            std::memory_order_seq_cst,
224                                            std::memory_order_seq_cst) == true);
225         assert(obj == false);
226         assert(x == true);
227         assert((obj = false) == false);
228         assert(obj == false);
229         assert((obj = true) == true);
230         assert(obj == true);
231     }
232     {
233         typedef std::atomic<bool> A;
234         TEST_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
235         A& zero = *new (storage) A();
236         assert(zero == false);
237         zero.~A();
238     }
239 
240   return 0;
241 }
242