1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <atomic>
// template <>
// struct atomic<integral>
// {
// bool is_lock_free() const volatile;
// bool is_lock_free() const;
// void store(integral desr, memory_order m = memory_order_seq_cst) volatile;
// void store(integral desr, memory_order m = memory_order_seq_cst);
// integral load(memory_order m = memory_order_seq_cst) const volatile;
// integral load(memory_order m = memory_order_seq_cst) const;
// operator integral() const volatile;
// operator integral() const;
// integral exchange(integral desr,
// memory_order m = memory_order_seq_cst) volatile;
// integral exchange(integral desr, memory_order m = memory_order_seq_cst);
// bool compare_exchange_weak(integral& expc, integral desr,
// memory_order s, memory_order f) volatile;
// bool compare_exchange_weak(integral& expc, integral desr,
// memory_order s, memory_order f);
// bool compare_exchange_strong(integral& expc, integral desr,
// memory_order s, memory_order f) volatile;
// bool compare_exchange_strong(integral& expc, integral desr,
// memory_order s, memory_order f);
// bool compare_exchange_weak(integral& expc, integral desr,
// memory_order m = memory_order_seq_cst) volatile;
// bool compare_exchange_weak(integral& expc, integral desr,
// memory_order m = memory_order_seq_cst);
// bool compare_exchange_strong(integral& expc, integral desr,
// memory_order m = memory_order_seq_cst) volatile;
// bool compare_exchange_strong(integral& expc, integral desr,
// memory_order m = memory_order_seq_cst);
//
// integral
// fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile;
// integral fetch_add(integral op, memory_order m = memory_order_seq_cst);
// integral
// fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile;
// integral fetch_sub(integral op, memory_order m = memory_order_seq_cst);
// integral
// fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile;
// integral fetch_and(integral op, memory_order m = memory_order_seq_cst);
// integral
// fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile;
// integral fetch_or(integral op, memory_order m = memory_order_seq_cst);
// integral
// fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile;
// integral fetch_xor(integral op, memory_order m = memory_order_seq_cst);
//
// atomic() = default;
// constexpr atomic(integral desr);
// atomic(const atomic&) = delete;
// atomic& operator=(const atomic&) = delete;
// atomic& operator=(const atomic&) volatile = delete;
// integral operator=(integral desr) volatile;
// integral operator=(integral desr);
//
// integral operator++(int) volatile;
// integral operator++(int);
// integral operator--(int) volatile;
// integral operator--(int);
// integral operator++() volatile;
// integral operator++();
// integral operator--() volatile;
// integral operator--();
// integral operator+=(integral op) volatile;
// integral operator+=(integral op);
// integral operator-=(integral op) volatile;
// integral operator-=(integral op);
// integral operator&=(integral op) volatile;
// integral operator&=(integral op);
// integral operator|=(integral op) volatile;
// integral operator|=(integral op);
// integral operator^=(integral op) volatile;
// integral operator^=(integral op);
// };
#include <atomic>
#include <new>
#include <cassert>
template <class A, class T>
void
do_test()
{
A obj(T(0));
assert(obj == T(0));
std::atomic_init(&obj, T(1));
assert(obj == T(1));
std::atomic_init(&obj, T(2));
assert(obj == T(2));
bool b0 = obj.is_lock_free();
obj.store(T(0));
assert(obj == T(0));
obj.store(T(1), std::memory_order_release);
assert(obj == T(1));
assert(obj.load() == T(1));
assert(obj.load(std::memory_order_acquire) == T(1));
assert(obj.exchange(T(2)) == T(1));
assert(obj == T(2));
assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2));
assert(obj == T(3));
T x = obj;
assert(obj.compare_exchange_weak(x, T(2)) == true);
assert(obj == T(2));
assert(x == T(3));
assert(obj.compare_exchange_weak(x, T(1)) == false);
assert(obj == T(2));
assert(x == T(2));
x = T(2);
assert(obj.compare_exchange_strong(x, T(1)) == true);
assert(obj == T(1));
assert(x == T(2));
assert(obj.compare_exchange_strong(x, T(0)) == false);
assert(obj == T(1));
assert(x == T(1));
assert((obj = T(0)) == T(0));
assert(obj == T(0));
assert(obj++ == T(0));
assert(obj == T(1));
assert(++obj == T(2));
assert(obj == T(2));
assert(--obj == T(1));
assert(obj == T(1));
assert(obj-- == T(1));
assert(obj == T(0));
obj = T(2);
assert((obj += T(3)) == T(5));
assert(obj == T(5));
assert((obj -= T(3)) == T(2));
assert(obj == T(2));
assert((obj |= T(5)) == T(7));
assert(obj == T(7));
assert((obj &= T(0xF)) == T(7));
assert(obj == T(7));
assert((obj ^= T(0xF)) == T(8));
assert(obj == T(8));
{
_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23};
A& zero = *new (storage) A();
assert(zero == 0);
zero.~A();
}
}
template <class A, class T>
void test()
{
do_test<A, T>();
do_test<volatile A, T>();
}
int main()
{
test<std::atomic_char, char>();
test<std::atomic_schar, signed char>();
test<std::atomic_uchar, unsigned char>();
test<std::atomic_short, short>();
test<std::atomic_ushort, unsigned short>();
test<std::atomic_int, int>();
test<std::atomic_uint, unsigned int>();
test<std::atomic_long, long>();
test<std::atomic_ulong, unsigned long>();
test<std::atomic_llong, long long>();
test<std::atomic_ullong, unsigned long long>();
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<std::atomic_char16_t, char16_t>();
test<std::atomic_char32_t, char32_t>();
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
test<std::atomic_wchar_t, wchar_t>();
test<volatile std::atomic_char, char>();
test<volatile std::atomic_schar, signed char>();
test<volatile std::atomic_uchar, unsigned char>();
test<volatile std::atomic_short, short>();
test<volatile std::atomic_ushort, unsigned short>();
test<volatile std::atomic_int, int>();
test<volatile std::atomic_uint, unsigned int>();
test<volatile std::atomic_long, long>();
test<volatile std::atomic_ulong, unsigned long>();
test<volatile std::atomic_llong, long long>();
test<volatile std::atomic_ullong, unsigned long long>();
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
test<volatile std::atomic_char16_t, char16_t>();
test<volatile std::atomic_char32_t, char32_t>();
#endif // _LIBCPP_HAS_NO_UNICODE_CHARS
test<volatile std::atomic_wchar_t, wchar_t>();
}
|