]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/std/atomics/atomics.types.generic/integral.pass.cpp
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / test / std / atomics / atomics.types.generic / integral.pass.cpp
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 // UNSUPPORTED: libcpp-has-no-threads
11
12 // <atomic>
13
14 // template <>
15 // struct atomic<integral>
16 // {
17 //     bool is_lock_free() const volatile;
18 //     bool is_lock_free() const;
19 //     void store(integral desr, memory_order m = memory_order_seq_cst) volatile;
20 //     void store(integral desr, memory_order m = memory_order_seq_cst);
21 //     integral load(memory_order m = memory_order_seq_cst) const volatile;
22 //     integral load(memory_order m = memory_order_seq_cst) const;
23 //     operator integral() const volatile;
24 //     operator integral() const;
25 //     integral exchange(integral desr,
26 //                       memory_order m = memory_order_seq_cst) volatile;
27 //     integral exchange(integral desr, memory_order m = memory_order_seq_cst);
28 //     bool compare_exchange_weak(integral& expc, integral desr,
29 //                                memory_order s, memory_order f) volatile;
30 //     bool compare_exchange_weak(integral& expc, integral desr,
31 //                                memory_order s, memory_order f);
32 //     bool compare_exchange_strong(integral& expc, integral desr,
33 //                                  memory_order s, memory_order f) volatile;
34 //     bool compare_exchange_strong(integral& expc, integral desr,
35 //                                  memory_order s, memory_order f);
36 //     bool compare_exchange_weak(integral& expc, integral desr,
37 //                                memory_order m = memory_order_seq_cst) volatile;
38 //     bool compare_exchange_weak(integral& expc, integral desr,
39 //                                memory_order m = memory_order_seq_cst);
40 //     bool compare_exchange_strong(integral& expc, integral desr,
41 //                                 memory_order m = memory_order_seq_cst) volatile;
42 //     bool compare_exchange_strong(integral& expc, integral desr,
43 //                                  memory_order m = memory_order_seq_cst);
44 //
45 //     integral
46 //         fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile;
47 //     integral fetch_add(integral op, memory_order m = memory_order_seq_cst);
48 //     integral
49 //         fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile;
50 //     integral fetch_sub(integral op, memory_order m = memory_order_seq_cst);
51 //     integral
52 //         fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile;
53 //     integral fetch_and(integral op, memory_order m = memory_order_seq_cst);
54 //     integral
55 //         fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile;
56 //     integral fetch_or(integral op, memory_order m = memory_order_seq_cst);
57 //     integral
58 //         fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile;
59 //     integral fetch_xor(integral op, memory_order m = memory_order_seq_cst);
60 //
61 //     atomic() = default;
62 //     constexpr atomic(integral desr);
63 //     atomic(const atomic&) = delete;
64 //     atomic& operator=(const atomic&) = delete;
65 //     atomic& operator=(const atomic&) volatile = delete;
66 //     integral operator=(integral desr) volatile;
67 //     integral operator=(integral desr);
68 //
69 //     integral operator++(int) volatile;
70 //     integral operator++(int);
71 //     integral operator--(int) volatile;
72 //     integral operator--(int);
73 //     integral operator++() volatile;
74 //     integral operator++();
75 //     integral operator--() volatile;
76 //     integral operator--();
77 //     integral operator+=(integral op) volatile;
78 //     integral operator+=(integral op);
79 //     integral operator-=(integral op) volatile;
80 //     integral operator-=(integral op);
81 //     integral operator&=(integral op) volatile;
82 //     integral operator&=(integral op);
83 //     integral operator|=(integral op) volatile;
84 //     integral operator|=(integral op);
85 //     integral operator^=(integral op) volatile;
86 //     integral operator^=(integral op);
87 // };
88
89 #include <atomic>
90 #include <new>
91 #include <cassert>
92
93 #include <cmpxchg_loop.h>
94
95 #include "test_macros.h"
96
97 template <class A, class T>
98 void
99 do_test()
100 {
101     A obj(T(0));
102     assert(obj == T(0));
103     std::atomic_init(&obj, T(1));
104     assert(obj == T(1));
105     std::atomic_init(&obj, T(2));
106     assert(obj == T(2));
107     bool b0 = obj.is_lock_free();
108     ((void)b0); // mark as unused
109     obj.store(T(0));
110     assert(obj == T(0));
111     obj.store(T(1), std::memory_order_release);
112     assert(obj == T(1));
113     assert(obj.load() == T(1));
114     assert(obj.load(std::memory_order_acquire) == T(1));
115     assert(obj.exchange(T(2)) == T(1));
116     assert(obj == T(2));
117     assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2));
118     assert(obj == T(3));
119     T x = obj;
120     assert(cmpxchg_weak_loop(obj, x, T(2)) == true);
121     assert(obj == T(2));
122     assert(x == T(3));
123     assert(obj.compare_exchange_weak(x, T(1)) == false);
124     assert(obj == T(2));
125     assert(x == T(2));
126     x = T(2);
127     assert(obj.compare_exchange_strong(x, T(1)) == true);
128     assert(obj == T(1));
129     assert(x == T(2));
130     assert(obj.compare_exchange_strong(x, T(0)) == false);
131     assert(obj == T(1));
132     assert(x == T(1));
133     assert((obj = T(0)) == T(0));
134     assert(obj == T(0));
135     assert(obj++ == T(0));
136     assert(obj == T(1));
137     assert(++obj == T(2));
138     assert(obj == T(2));
139     assert(--obj == T(1));
140     assert(obj == T(1));
141     assert(obj-- == T(1));
142     assert(obj == T(0));
143     obj = T(2);
144     assert((obj += T(3)) == T(5));
145     assert(obj == T(5));
146     assert((obj -= T(3)) == T(2));
147     assert(obj == T(2));
148     assert((obj |= T(5)) == T(7));
149     assert(obj == T(7));
150     assert((obj &= T(0xF)) == T(7));
151     assert(obj == T(7));
152     assert((obj ^= T(0xF)) == T(8));
153     assert(obj == T(8));
154
155     {
156         TEST_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23};
157         A& zero = *new (storage) A();
158         assert(zero == 0);
159         zero.~A();
160     }
161 }
162
163 template <class A, class T>
164 void test()
165 {
166     do_test<A, T>();
167     do_test<volatile A, T>();
168 }
169
170
171 int main()
172 {
173     test<std::atomic_char, char>();
174     test<std::atomic_schar, signed char>();
175     test<std::atomic_uchar, unsigned char>();
176     test<std::atomic_short, short>();
177     test<std::atomic_ushort, unsigned short>();
178     test<std::atomic_int, int>();
179     test<std::atomic_uint, unsigned int>();
180     test<std::atomic_long, long>();
181     test<std::atomic_ulong, unsigned long>();
182     test<std::atomic_llong, long long>();
183     test<std::atomic_ullong, unsigned long long>();
184 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
185     test<std::atomic_char16_t, char16_t>();
186     test<std::atomic_char32_t, char32_t>();
187 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
188     test<std::atomic_wchar_t, wchar_t>();
189
190         test<std::atomic_int8_t,    int8_t>();
191         test<std::atomic_uint8_t,  uint8_t>();
192         test<std::atomic_int16_t,   int16_t>();
193         test<std::atomic_uint16_t, uint16_t>();
194         test<std::atomic_int32_t,   int32_t>();
195         test<std::atomic_uint32_t, uint32_t>();
196         test<std::atomic_int64_t,   int64_t>();
197         test<std::atomic_uint64_t, uint64_t>();
198
199     test<volatile std::atomic_char, char>();
200     test<volatile std::atomic_schar, signed char>();
201     test<volatile std::atomic_uchar, unsigned char>();
202     test<volatile std::atomic_short, short>();
203     test<volatile std::atomic_ushort, unsigned short>();
204     test<volatile std::atomic_int, int>();
205     test<volatile std::atomic_uint, unsigned int>();
206     test<volatile std::atomic_long, long>();
207     test<volatile std::atomic_ulong, unsigned long>();
208     test<volatile std::atomic_llong, long long>();
209     test<volatile std::atomic_ullong, unsigned long long>();
210 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
211     test<volatile std::atomic_char16_t, char16_t>();
212     test<volatile std::atomic_char32_t, char32_t>();
213 #endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
214     test<volatile std::atomic_wchar_t, wchar_t>();
215
216         test<volatile std::atomic_int8_t,    int8_t>();
217         test<volatile std::atomic_uint8_t,  uint8_t>();
218         test<volatile std::atomic_int16_t,   int16_t>();
219         test<volatile std::atomic_uint16_t, uint16_t>();
220         test<volatile std::atomic_int32_t,   int32_t>();
221         test<volatile std::atomic_uint32_t, uint32_t>();
222         test<volatile std::atomic_int64_t,   int64_t>();
223         test<volatile std::atomic_uint64_t, uint64_t>();
224 }