1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // XFAIL: LIBCXX-AIX-FIXME
10 
11 // <complex>
12 
13 // template<class T>
14 //   T
15 //   arg(const complex<T>& x);
16 
17 #include <complex>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "../cases.h"
22 
23 template <class T>
24 void
25 test()
26 {
27     std::complex<T> z(1, 0);
28     assert(arg(z) == 0);
29 }
30 
31 void test_edges()
32 {
33     const double pi = std::atan2(+0., -0.);
34     const unsigned N = sizeof(testcases) / sizeof(testcases[0]);
35     for (unsigned i = 0; i < N; ++i)
36     {
37         double r = arg(testcases[i]);
38         if (std::isnan(testcases[i].real()) || std::isnan(testcases[i].imag()))
39             assert(std::isnan(r));
40         else
41         {
42             switch (classify(testcases[i]))
43             {
44             case zero:
45                 if (std::signbit(testcases[i].real()))
46                 {
47                     if (std::signbit(testcases[i].imag()))
48                         is_about(r, -pi);
49                     else
50                         is_about(r, pi);
51                 }
52                 else
53                 {
54                     assert(std::signbit(testcases[i].imag()) == std::signbit(r));
55                 }
56                 break;
57             case non_zero:
58                 if (testcases[i].real() == 0)
59                 {
60                     if (testcases[i].imag() < 0)
61                         is_about(r, -pi/2);
62                     else
63                         is_about(r, pi/2);
64                 }
65                 else if (testcases[i].imag() == 0)
66                 {
67                     if (testcases[i].real() < 0)
68                     {
69                         if (std::signbit(testcases[i].imag()))
70                             is_about(r, -pi);
71                         else
72                             is_about(r, pi);
73                     }
74                     else
75                     {
76                         assert(r == 0);
77                         assert(std::signbit(testcases[i].imag()) == std::signbit(r));
78                     }
79                 }
80                 else if (testcases[i].imag() > 0)
81                     assert(r > 0);
82                 else
83                     assert(r < 0);
84                 break;
85             case inf:
86                 if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag()))
87                 {
88                     if (testcases[i].real() < 0)
89                     {
90                         if (testcases[i].imag() > 0)
91                             is_about(r, 0.75 * pi);
92                         else
93                             is_about(r, -0.75 * pi);
94                     }
95                     else
96                     {
97                         if (testcases[i].imag() > 0)
98                             is_about(r, 0.25 * pi);
99                         else
100                             is_about(r, -0.25 * pi);
101                     }
102                 }
103                 else if (std::isinf(testcases[i].real()))
104                 {
105                     if (testcases[i].real() < 0)
106                     {
107                         if (std::signbit(testcases[i].imag()))
108                             is_about(r, -pi);
109                         else
110                             is_about(r, pi);
111                     }
112                     else
113                     {
114                         assert(r == 0);
115                         assert(std::signbit(r) == std::signbit(testcases[i].imag()));
116                     }
117                 }
118                 else
119                 {
120                     if (testcases[i].imag() < 0)
121                         is_about(r, -pi/2);
122                     else
123                         is_about(r, pi/2);
124                 }
125                 break;
126             }
127         }
128     }
129 }
130 
131 int main(int, char**)
132 {
133     test<float>();
134     test<double>();
135     test<long double>();
136     test_edges();
137 
138   return 0;
139 }
140