integral.pass.cpp (8493B)
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 }