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

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