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