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