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 Integral>
13 // Integral
14 // atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
15 // memory_order m);
16 // template <class Integral>
17 // Integral
18 // atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
19 // memory_order m);
20 // template <class T>
21 // T*
22 // atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
23 // memory_order m);
24 // template <class T>
25 // T*
26 // atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
27
28 #include <atomic>
29 #include <type_traits>
30 #include <cassert>
31
32 template <class T>
33 void
test()34 test()
35 {
36 {
37 typedef std::atomic<T> A;
38 A t;
39 std::atomic_init(&t, T(1));
40 assert(std::atomic_fetch_add_explicit(&t, T(2),
41 std::memory_order_seq_cst) == T(1));
42 assert(t == T(3));
43 }
44 {
45 typedef std::atomic<T> A;
46 volatile A t;
47 std::atomic_init(&t, T(1));
48 assert(std::atomic_fetch_add_explicit(&t, T(2),
49 std::memory_order_seq_cst) == T(1));
50 assert(t == T(3));
51 }
52 }
53
54 template <class T>
55 void
testp()56 testp()
57 {
58 {
59 typedef std::atomic<T> A;
60 typedef typename std::remove_pointer<T>::type X;
61 A t;
62 std::atomic_init(&t, T(1*sizeof(X)));
63 assert(std::atomic_fetch_add_explicit(&t, 2,
64 std::memory_order_seq_cst) == T(1*sizeof(X)));
65 assert(t == T(3*sizeof(X)));
66 }
67 {
68 typedef std::atomic<T> A;
69 typedef typename std::remove_pointer<T>::type X;
70 volatile A t;
71 std::atomic_init(&t, T(1*sizeof(X)));
72 assert(std::atomic_fetch_add_explicit(&t, 2,
73 std::memory_order_seq_cst) == T(1*sizeof(X)));
74 assert(t == T(3*sizeof(X)));
75 }
76 }
77
78 struct A
79 {
80 int i;
81
AA82 explicit A(int d = 0) : i(d) {}
AA83 A(const A& a) : i(a.i) {}
AA84 A(const volatile A& a) : i(a.i) {}
85
operator =A86 void operator=(const volatile A& a) volatile {i = a.i;}
87
operator ==(const A & x,const A & y)88 friend bool operator==(const A& x, const A& y)
89 {return x.i == y.i;}
90 };
91
main()92 int main()
93 {
94 test<char>();
95 test<signed char>();
96 test<unsigned char>();
97 test<short>();
98 test<unsigned short>();
99 test<int>();
100 test<unsigned int>();
101 test<long>();
102 test<unsigned long>();
103 test<long long>();
104 test<unsigned long long>();
105 test<wchar_t>();
106 #ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
107 test<char16_t>();
108 test<char32_t>();
109 #endif // _LIBCPP_HAS_NO_UNICODE_CHARS
110 testp<int*>();
111 testp<const int*>();
112 }
113