1 | // (C) Copyright John Maddock 2005. |
---|
2 | // Use, modification and distribution are subject to the |
---|
3 | // Boost Software License, Version 1.0. (See accompanying file |
---|
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
---|
5 | |
---|
6 | #ifdef TEST_STD_HEADERS |
---|
7 | #include <complex> |
---|
8 | #else |
---|
9 | #include <boost/tr1/complex.hpp> |
---|
10 | #endif |
---|
11 | |
---|
12 | #include <boost/test/test_tools.hpp> |
---|
13 | #include <boost/test/included/test_exec_monitor.hpp> |
---|
14 | #include <boost/test/floating_point_comparison.hpp> |
---|
15 | #include <boost/type_traits/is_same.hpp> |
---|
16 | #include <boost/type_traits/is_floating_point.hpp> |
---|
17 | #include <boost/mpl/if.hpp> |
---|
18 | #include <boost/static_assert.hpp> |
---|
19 | |
---|
20 | #include <iostream> |
---|
21 | #include <iomanip> |
---|
22 | |
---|
23 | #ifndef VERBOSE |
---|
24 | #undef BOOST_MESSAGE |
---|
25 | #define BOOST_MESSAGE(x) |
---|
26 | #endif |
---|
27 | |
---|
28 | // |
---|
29 | // This test verifies that the complex-algorithms that are |
---|
30 | // overloaded for scalar types produce the same result as casting |
---|
31 | // the argument to a complex type, and calling the complex version |
---|
32 | // of the algorithm. Relative errors must be within 2e in order for |
---|
33 | // the tests to pass. |
---|
34 | // |
---|
35 | |
---|
36 | template <class T, class U> |
---|
37 | void check(const T& t, const U& u) |
---|
38 | { |
---|
39 | static const T two = 2; |
---|
40 | static const T factor = std::pow(two, 1-std::numeric_limits<T>::digits) * 200; |
---|
41 | BOOST_STATIC_ASSERT((::boost::is_same<T,U>::value)); |
---|
42 | BOOST_CHECK_CLOSE(t, u, factor); |
---|
43 | } |
---|
44 | |
---|
45 | template <class T, class U> |
---|
46 | void check(const std::complex<T>& t, const std::complex<U>& u) |
---|
47 | { |
---|
48 | BOOST_STATIC_ASSERT((::boost::is_same<T,U>::value)); |
---|
49 | check(t.real(), u.real()); |
---|
50 | check(t.imag(), u.imag()); |
---|
51 | } |
---|
52 | |
---|
53 | template <class T> |
---|
54 | void check_val(const T& val) |
---|
55 | { |
---|
56 | typedef typename boost::mpl::if_< boost::is_floating_point<T>, T, double>::type real_type; |
---|
57 | typedef std::complex<real_type> complex_type; |
---|
58 | |
---|
59 | real_type rval = static_cast<real_type>(val); |
---|
60 | complex_type cval = rval; |
---|
61 | |
---|
62 | if(val) |
---|
63 | { |
---|
64 | std::cout << " Testing std::arg.\n"; |
---|
65 | check(std::arg(cval), std::arg(rval)); |
---|
66 | check(std::arg(cval), std::arg(val)); |
---|
67 | } |
---|
68 | std::cout << " Testing std::norm.\n"; |
---|
69 | check(std::norm(cval), std::norm(rval)); |
---|
70 | check(std::norm(cval), std::norm(val)); |
---|
71 | std::cout << " Testing std::conj.\n"; |
---|
72 | check(std::conj(cval), std::conj(rval)); |
---|
73 | check(std::conj(cval), std::conj(val)); |
---|
74 | std::cout << " Testing std::polar.\n"; |
---|
75 | check(std::polar(val), std::polar(rval)); |
---|
76 | check(std::polar(val, 0), std::polar(rval, 0)); |
---|
77 | check(std::polar(val, val), std::polar(rval, rval)); |
---|
78 | check(std::polar(val, rval), std::polar(rval, val)); |
---|
79 | std::cout << " Testing std::real.\n"; |
---|
80 | check(std::real(cval), std::real(rval)); |
---|
81 | check(std::real(cval), std::real(val)); |
---|
82 | std::cout << " Testing std::imaj.\n"; |
---|
83 | check(std::imag(cval), std::imag(rval)); |
---|
84 | check(std::imag(cval), std::imag(val)); |
---|
85 | if(val && !boost::is_floating_point<T>::value) |
---|
86 | { |
---|
87 | // |
---|
88 | // Note that these tests are not run for floating point |
---|
89 | // types as that would only test the std lib vendor's |
---|
90 | // implementation of pow, not our additional overloads. |
---|
91 | // Note that some std lib's do fail these tests, gcc on |
---|
92 | // Darwin is a particularly bad example ! |
---|
93 | // |
---|
94 | std::cout << " Testing std::pow.\n"; |
---|
95 | check(std::pow(cval, cval), std::pow(cval, val)); |
---|
96 | check(std::pow(cval, cval), std::pow(cval, rval)); |
---|
97 | check(std::pow(cval, cval), std::pow(val, cval)); |
---|
98 | check(std::pow(cval, cval), std::pow(rval, cval)); |
---|
99 | } |
---|
100 | } |
---|
101 | |
---|
102 | void check(double i) |
---|
103 | { |
---|
104 | std::cout << "Checking type double with value " << i << std::endl; |
---|
105 | check_val(i); |
---|
106 | std::cout << "Checking type float with value " << i << std::endl; |
---|
107 | check_val(static_cast<float>(i)); |
---|
108 | std::cout << "Checking type long double with value " << i << std::endl; |
---|
109 | check_val(static_cast<long double>(i)); |
---|
110 | } |
---|
111 | |
---|
112 | void check(int i) |
---|
113 | { |
---|
114 | std::cout << "Checking type char with value " << i << std::endl; |
---|
115 | check_val(static_cast<char>(i)); |
---|
116 | std::cout << "Checking type unsigned char with value " << i << std::endl; |
---|
117 | check_val(static_cast<unsigned char>(i)); |
---|
118 | std::cout << "Checking type signed char with value " << i << std::endl; |
---|
119 | check_val(static_cast<signed char>(i)); |
---|
120 | std::cout << "Checking type short with value " << i << std::endl; |
---|
121 | check_val(static_cast<short>(i)); |
---|
122 | std::cout << "Checking type unsigned short with value " << i << std::endl; |
---|
123 | check_val(static_cast<unsigned short>(i)); |
---|
124 | std::cout << "Checking type int with value " << i << std::endl; |
---|
125 | check_val(static_cast<int>(i)); |
---|
126 | std::cout << "Checking type unsigned int with value " << i << std::endl; |
---|
127 | check_val(static_cast<unsigned int>(i)); |
---|
128 | std::cout << "Checking type long with value " << i << std::endl; |
---|
129 | check_val(static_cast<long>(i)); |
---|
130 | std::cout << "Checking type unsigned long with value " << i << std::endl; |
---|
131 | check_val(static_cast<unsigned long>(i)); |
---|
132 | #ifdef BOOST_HAS_LONG_LONG |
---|
133 | std::cout << "Checking type long long with value " << i << std::endl; |
---|
134 | check_val(static_cast<long long>(i)); |
---|
135 | std::cout << "Checking type unsigned long long with value " << i << std::endl; |
---|
136 | check_val(static_cast<unsigned long long>(i)); |
---|
137 | #elif defined(BOOST_HAS_MS_INT64) |
---|
138 | std::cout << "Checking type __int64 with value " << i << std::endl; |
---|
139 | check_val(static_cast<__int64>(i)); |
---|
140 | std::cout << "Checking type unsigned __int64 with value " << i << std::endl; |
---|
141 | check_val(static_cast<unsigned __int64>(i)); |
---|
142 | #endif |
---|
143 | check(static_cast<double>(i)); |
---|
144 | } |
---|
145 | |
---|
146 | int test_main(int, char*[]) |
---|
147 | { |
---|
148 | check(0); |
---|
149 | check(0.0); |
---|
150 | check(1); |
---|
151 | check(1.5); |
---|
152 | check(0.5); |
---|
153 | return 0; |
---|
154 | } |
---|
155 | |
---|