1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <atomic>
11
12// template <class T>
13// struct atomic
14// {
15//     bool is_lock_free() const volatile;
16//     bool is_lock_free() const;
17//     void store(T desr, memory_order m = memory_order_seq_cst) volatile;
18//     void store(T desr, memory_order m = memory_order_seq_cst);
19//     T load(memory_order m = memory_order_seq_cst) const volatile;
20//     T load(memory_order m = memory_order_seq_cst) const;
21//     operator T() const volatile;
22//     operator T() const;
23//     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile;
24//     T exchange(T desr, memory_order m = memory_order_seq_cst);
25//     bool compare_exchange_weak(T& expc, T desr,
26//                                memory_order s, memory_order f) volatile;
27//     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f);
28//     bool compare_exchange_strong(T& expc, T desr,
29//                                  memory_order s, memory_order f) volatile;
30//     bool compare_exchange_strong(T& expc, T desr,
31//                                  memory_order s, memory_order f);
32//     bool compare_exchange_weak(T& expc, T desr,
33//                                memory_order m = memory_order_seq_cst) volatile;
34//     bool compare_exchange_weak(T& expc, T desr,
35//                                memory_order m = memory_order_seq_cst);
36//     bool compare_exchange_strong(T& expc, T desr,
37//                                 memory_order m = memory_order_seq_cst) volatile;
38//     bool compare_exchange_strong(T& expc, T desr,
39//                                  memory_order m = memory_order_seq_cst);
40//
41//     atomic() = default;
42//     constexpr atomic(T desr);
43//     atomic(const atomic&) = delete;
44//     atomic& operator=(const atomic&) = delete;
45//     atomic& operator=(const atomic&) volatile = delete;
46//     T operator=(T) volatile;
47//     T operator=(T);
48// };
49//
50// typedef atomic<bool> atomic_bool;
51
52#include <atomic>
53#include <new>
54#include <cassert>
55
56int main()
57{
58    {
59        volatile std::atomic<bool> _;
60        volatile std::atomic<bool> obj(true);
61        assert(obj == true);
62        std::atomic_init(&obj, false);
63        assert(obj == false);
64        std::atomic_init(&obj, true);
65        assert(obj == true);
66        bool b0 = obj.is_lock_free();
67        obj.store(false);
68        assert(obj == false);
69        obj.store(true, std::memory_order_release);
70        assert(obj == true);
71        assert(obj.load() == true);
72        assert(obj.load(std::memory_order_acquire) == true);
73        assert(obj.exchange(false) == true);
74        assert(obj == false);
75        assert(obj.exchange(true, std::memory_order_relaxed) == false);
76        assert(obj == true);
77        bool x = obj;
78        assert(obj.compare_exchange_weak(x, false) == true);
79        assert(obj == false);
80        assert(x == true);
81        assert(obj.compare_exchange_weak(x, true,
82                                         std::memory_order_seq_cst) == false);
83        assert(obj == false);
84        assert(x == false);
85        obj.store(true);
86        x = true;
87        assert(obj.compare_exchange_weak(x, false,
88                                         std::memory_order_seq_cst,
89                                         std::memory_order_seq_cst) == true);
90        assert(obj == false);
91        assert(x == true);
92        x = true;
93        obj.store(true);
94        assert(obj.compare_exchange_strong(x, false) == true);
95        assert(obj == false);
96        assert(x == true);
97        assert(obj.compare_exchange_strong(x, true,
98                                         std::memory_order_seq_cst) == false);
99        assert(obj == false);
100        assert(x == false);
101        x = true;
102        obj.store(true);
103        assert(obj.compare_exchange_strong(x, false,
104                                           std::memory_order_seq_cst,
105                                           std::memory_order_seq_cst) == true);
106        assert(obj == false);
107        assert(x == true);
108        assert((obj = false) == false);
109        assert(obj == false);
110        assert((obj = true) == true);
111        assert(obj == true);
112    }
113    {
114        std::atomic<bool> _;
115        std::atomic<bool> obj(true);
116        assert(obj == true);
117        std::atomic_init(&obj, false);
118        assert(obj == false);
119        std::atomic_init(&obj, true);
120        assert(obj == true);
121        bool b0 = obj.is_lock_free();
122        obj.store(false);
123        assert(obj == false);
124        obj.store(true, std::memory_order_release);
125        assert(obj == true);
126        assert(obj.load() == true);
127        assert(obj.load(std::memory_order_acquire) == true);
128        assert(obj.exchange(false) == true);
129        assert(obj == false);
130        assert(obj.exchange(true, std::memory_order_relaxed) == false);
131        assert(obj == true);
132        bool x = obj;
133        assert(obj.compare_exchange_weak(x, false) == true);
134        assert(obj == false);
135        assert(x == true);
136        assert(obj.compare_exchange_weak(x, true,
137                                         std::memory_order_seq_cst) == false);
138        assert(obj == false);
139        assert(x == false);
140        obj.store(true);
141        x = true;
142        assert(obj.compare_exchange_weak(x, false,
143                                         std::memory_order_seq_cst,
144                                         std::memory_order_seq_cst) == true);
145        assert(obj == false);
146        assert(x == true);
147        x = true;
148        obj.store(true);
149        assert(obj.compare_exchange_strong(x, false) == true);
150        assert(obj == false);
151        assert(x == true);
152        assert(obj.compare_exchange_strong(x, true,
153                                         std::memory_order_seq_cst) == false);
154        assert(obj == false);
155        assert(x == false);
156        x = true;
157        obj.store(true);
158        assert(obj.compare_exchange_strong(x, false,
159                                           std::memory_order_seq_cst,
160                                           std::memory_order_seq_cst) == true);
161        assert(obj == false);
162        assert(x == true);
163        assert((obj = false) == false);
164        assert(obj == false);
165        assert((obj = true) == true);
166        assert(obj == true);
167    }
168    {
169        std::atomic_bool _;
170        std::atomic_bool obj(true);
171        assert(obj == true);
172        std::atomic_init(&obj, false);
173        assert(obj == false);
174        std::atomic_init(&obj, true);
175        assert(obj == true);
176        bool b0 = obj.is_lock_free();
177        obj.store(false);
178        assert(obj == false);
179        obj.store(true, std::memory_order_release);
180        assert(obj == true);
181        assert(obj.load() == true);
182        assert(obj.load(std::memory_order_acquire) == true);
183        assert(obj.exchange(false) == true);
184        assert(obj == false);
185        assert(obj.exchange(true, std::memory_order_relaxed) == false);
186        assert(obj == true);
187        bool x = obj;
188        assert(obj.compare_exchange_weak(x, false) == true);
189        assert(obj == false);
190        assert(x == true);
191        assert(obj.compare_exchange_weak(x, true,
192                                         std::memory_order_seq_cst) == false);
193        assert(obj == false);
194        assert(x == false);
195        obj.store(true);
196        x = true;
197        assert(obj.compare_exchange_weak(x, false,
198                                         std::memory_order_seq_cst,
199                                         std::memory_order_seq_cst) == true);
200        assert(obj == false);
201        assert(x == true);
202        x = true;
203        obj.store(true);
204        assert(obj.compare_exchange_strong(x, false) == true);
205        assert(obj == false);
206        assert(x == true);
207        assert(obj.compare_exchange_strong(x, true,
208                                         std::memory_order_seq_cst) == false);
209        assert(obj == false);
210        assert(x == false);
211        x = true;
212        obj.store(true);
213        assert(obj.compare_exchange_strong(x, false,
214                                           std::memory_order_seq_cst,
215                                           std::memory_order_seq_cst) == true);
216        assert(obj == false);
217        assert(x == true);
218        assert((obj = false) == false);
219        assert(obj == false);
220        assert((obj = true) == true);
221        assert(obj == true);
222    }
223    {
224        typedef std::atomic<bool> A;
225        _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
226        A& zero = *new (storage) A();
227        assert(zero == false);
228        zero.~A();
229    }
230}
231