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 73template <class A, class T> 74void 75do_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 125template <class A, class T> 126void test() 127{ 128 do_test<A, T>(); 129 do_test<volatile A, T>(); 130} 131 132int main() 133{ 134 test<std::atomic<int*>, int*>(); 135} 136