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// <complex>
11
12// template<class T>
13//   T
14//   arg(const complex<T>& x);
15
16#include <complex>
17#include <cassert>
18
19#include "../cases.h"
20
21template <class T>
22void
23test()
24{
25    std::complex<T> z(1, 0);
26    assert(arg(z) == 0);
27}
28
29void test_edges()
30{
31    const double pi = std::atan2(+0., -0.);
32    const unsigned N = sizeof(x) / sizeof(x[0]);
33    for (unsigned i = 0; i < N; ++i)
34    {
35        double r = arg(x[i]);
36        if (std::isnan(x[i].real()) || std::isnan(x[i].imag()))
37            assert(std::isnan(r));
38        else
39        {
40            switch (classify(x[i]))
41            {
42            case zero:
43                if (std::signbit(x[i].real()))
44                {
45                    if (std::signbit(x[i].imag()))
46                        is_about(r, -pi);
47                    else
48                        is_about(r, pi);
49                }
50                else
51                {
52                    assert(std::signbit(x[i].imag()) == std::signbit(r));
53                }
54                break;
55            case non_zero:
56                if (x[i].real() == 0)
57                {
58                    if (x[i].imag() < 0)
59                        is_about(r, -pi/2);
60                    else
61                        is_about(r, pi/2);
62                }
63                else if (x[i].imag() == 0)
64                {
65                    if (x[i].real() < 0)
66                    {
67                        if (std::signbit(x[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(x[i].imag()) == std::signbit(r));
76                    }
77                }
78                else if (x[i].imag() > 0)
79                    assert(r > 0);
80                else
81                    assert(r < 0);
82                break;
83            case inf:
84                if (std::isinf(x[i].real()) && std::isinf(x[i].imag()))
85                {
86                    if (x[i].real() < 0)
87                    {
88                        if (x[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 (x[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(x[i].real()))
102                {
103                    if (x[i].real() < 0)
104                    {
105                        if (std::signbit(x[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(x[i].imag()));
114                    }
115                }
116                else
117                {
118                    if (x[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
129int main()
130{
131    test<float>();
132    test<double>();
133    test<long double>();
134    test_edges();
135}
136