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