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 <class T> 13 // struct atomic<T*> 14 // { 15 // bool is_lock_free() const volatile; 16 // bool is_lock_free() const; 17 // void store(T* desr, memory_order m = memory_order_seq_cst) volatile; 18 // void store(T* desr, memory_order m = memory_order_seq_cst); 19 // T* load(memory_order m = memory_order_seq_cst) const volatile; 20 // T* load(memory_order m = memory_order_seq_cst) const; 21 // operator T*() const volatile; 22 // operator T*() const; 23 // T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile; 24 // T* exchange(T* desr, memory_order m = memory_order_seq_cst); 25 // bool compare_exchange_weak(T*& expc, T* desr, 26 // memory_order s, memory_order f) volatile; 27 // bool compare_exchange_weak(T*& expc, T* desr, 28 // memory_order s, memory_order f); 29 // bool compare_exchange_strong(T*& expc, T* desr, 30 // memory_order s, memory_order f) volatile; 31 // bool compare_exchange_strong(T*& expc, T* desr, 32 // memory_order s, memory_order f); 33 // bool compare_exchange_weak(T*& expc, T* desr, 34 // memory_order m = memory_order_seq_cst) volatile; 35 // bool compare_exchange_weak(T*& expc, T* desr, 36 // memory_order m = memory_order_seq_cst); 37 // bool compare_exchange_strong(T*& expc, T* desr, 38 // memory_order m = memory_order_seq_cst) volatile; 39 // bool compare_exchange_strong(T*& expc, T* desr, 40 // memory_order m = memory_order_seq_cst); 41 // T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile; 42 // T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst); 43 // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile; 44 // T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst); 45 // 46 // atomic() = default; 47 // constexpr atomic(T* desr); 48 // atomic(const atomic&) = delete; 49 // atomic& operator=(const atomic&) = delete; 50 // atomic& operator=(const atomic&) volatile = delete; 51 // 52 // T* operator=(T*) volatile; 53 // T* operator=(T*); 54 // T* operator++(int) volatile; 55 // T* operator++(int); 56 // T* operator--(int) volatile; 57 // T* operator--(int); 58 // T* operator++() volatile; 59 // T* operator++(); 60 // T* operator--() volatile; 61 // T* operator--(); 62 // T* operator+=(ptrdiff_t op) volatile; 63 // T* operator+=(ptrdiff_t op); 64 // T* operator-=(ptrdiff_t op) volatile; 65 // T* operator-=(ptrdiff_t op); 66 // }; 67 68 #include <atomic> 69 #include <new> 70 #include <type_traits> 71 #include <cassert> 72 73 template <class A, class T> 74 void 75 do_test() 76 { 77 typedef typename std::remove_pointer<T>::type X; 78 A obj(T(0)); 79 assert(obj == T(0)); 80 std::atomic_init(&obj, T(1)); 81 assert(obj == T(1)); 82 std::atomic_init(&obj, T(2)); 83 assert(obj == T(2)); 84 bool b0 = obj.is_lock_free(); 85 obj.store(T(0)); 86 assert(obj == T(0)); 87 obj.store(T(1), std::memory_order_release); 88 assert(obj == T(1)); 89 assert(obj.load() == T(1)); 90 assert(obj.load(std::memory_order_acquire) == T(1)); 91 assert(obj.exchange(T(2)) == T(1)); 92 assert(obj == T(2)); 93 assert(obj.exchange(T(3), std::memory_order_relaxed) == T(2)); 94 assert(obj == T(3)); 95 T x = obj; 96 assert(obj.compare_exchange_weak(x, T(2)) == true); 97 assert(obj == T(2)); 98 assert(x == T(3)); 99 assert(obj.compare_exchange_weak(x, T(1)) == false); 100 assert(obj == T(2)); 101 assert(x == T(2)); 102 x = T(2); 103 assert(obj.compare_exchange_strong(x, T(1)) == true); 104 assert(obj == T(1)); 105 assert(x == T(2)); 106 assert(obj.compare_exchange_strong(x, T(0)) == false); 107 assert(obj == T(1)); 108 assert(x == T(1)); 109 assert((obj = T(0)) == T(0)); 110 assert(obj == T(0)); 111 obj = T(2*sizeof(X)); 112 assert((obj += std::ptrdiff_t(3)) == T(5*sizeof(X))); 113 assert(obj == T(5*sizeof(X))); 114 assert((obj -= std::ptrdiff_t(3)) == T(2*sizeof(X))); 115 assert(obj == T(2*sizeof(X))); 116 117 { 118 _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {23}; 119 A& zero = *new (storage) A(); 120 assert(zero == 0); 121 zero.~A(); 122 } 123 } 124 125 template <class A, class T> 126 void test() 127 { 128 do_test<A, T>(); 129 do_test<volatile A, T>(); 130 } 131 132 int main() 133 { 134 test<std::atomic<int*>, int*>(); 135 } 136