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