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