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