Improve vacpp support.
[boost.git] / boost / libs / functional / hash / test / hash_float_test.cpp
blob0bfacbb5b7ea816703491d7eed11bee72a7c8593
2 // Copyright Daniel James 2005-2006. Use, modification, and distribution are
3 // subject to the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #include "./config.hpp"
8 #ifdef TEST_STD_INCLUDES
9 # include <functional>
10 #else
11 # include <boost/functional/hash.hpp>
12 #endif
14 #include <boost/detail/lightweight_test.hpp>
16 #include <cmath>
17 #include <boost/limits.hpp>
19 #include <iostream>
21 template <class T>
22 void float_tests(char const* name, T* = 0)
24 std::cerr<<"\n"
25 <<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
26 <<"\n"
27 <<"std::numeric_limits<T>::digits = "
28 <<std::numeric_limits<T>::digits<<"\n"
29 <<"std::numeric_limits<int>::digits = "
30 <<std::numeric_limits<int>::digits<<"\n"
31 <<"std::numeric_limits<std::size_t>::digits = "
32 <<std::numeric_limits<std::size_t>::digits<<"\n"
33 <<"\n"
36 HASH_NAMESPACE::hash<T> x1;
38 T zero = 0;
39 T minus_zero = (T) -1 * zero;
41 BOOST_TEST(zero == minus_zero);
42 BOOST_TEST(x1(zero) == x1(minus_zero));
44 BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
45 BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
47 using namespace std;
49 // Doing anything with infinity causes borland to crash.
50 #if defined(__BORLANDC__)
51 std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n";
52 #else
53 if(std::numeric_limits<T>::has_infinity) {
54 T infinity = -log(zero);
55 T infinity2 = (T) 1. / zero;
56 T infinity3 = (T) -1. / minus_zero;
57 T infinity4 = std::numeric_limits<T>::infinity();
59 T minus_infinity = log(zero);
60 T minus_infinity2 = (T) -1. / zero;
61 T minus_infinity3 = (T) 1. / minus_zero;
63 BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
64 BOOST_TEST(x1(minus_infinity)
65 == HASH_NAMESPACE::hash_value(minus_infinity));
67 if(infinity == infinity2)
68 BOOST_TEST(x1(infinity) == x1(infinity2));
69 if(infinity == infinity3);
70 BOOST_TEST(x1(infinity) == x1(infinity3));
71 if(infinity == infinity4)
72 BOOST_TEST(x1(infinity) == x1(infinity4));
74 if(minus_infinity == minus_infinity2)
75 BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
76 if(minus_infinity == minus_infinity3)
77 BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
79 BOOST_TEST(infinity != minus_infinity);
81 if(x1(infinity) == x1(minus_infinity)) {
82 std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
85 // This should really be 'has_denorm == denorm_present' but some
86 // compilers don't have 'denorm_present'. See also a later use.
87 if(std::numeric_limits<T>::has_denorm) {
88 if(x1(std::numeric_limits<T>::denorm_min()) == x1(infinity)) {
89 std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
91 if(x1(std::numeric_limits<T>::denorm_min()) == x1(minus_infinity)) {
92 std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
95 if(std::numeric_limits<T>::has_quiet_NaN) {
96 if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(infinity)) {
97 std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
99 if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(minus_infinity)) {
100 std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
104 #endif
106 T max = (std::numeric_limits<T>::max)();
107 T half_max = max / 2;
108 T quarter_max = max / 4;
109 T three_quarter_max = max - quarter_max;
111 BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
112 BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
113 BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
114 BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
116 // The '!=' tests could legitimately fail, but with my hash it indicates a bug.
117 BOOST_TEST(x1(max) == x1(max));
118 BOOST_TEST(x1(max) != x1(quarter_max));
119 BOOST_TEST(x1(max) != x1(half_max));
120 BOOST_TEST(x1(max) != x1(three_quarter_max));
121 BOOST_TEST(x1(quarter_max) == x1(quarter_max));
122 BOOST_TEST(x1(quarter_max) != x1(half_max));
123 BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
124 BOOST_TEST(x1(half_max) == x1(half_max));
125 BOOST_TEST(x1(half_max) != x1(three_quarter_max));
126 BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
128 // Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
129 #if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
130 defined(__ICC) || defined(__ECC)) && \
131 (defined(__GLIBCPP__) || defined(__GLIBCXX__)))
132 T v1 = asin((T) 1);
133 T v2 = acos((T) 0);
134 if(v1 == v2)
135 BOOST_TEST(x1(v1) == x1(v2));
136 BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
137 BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
138 #endif
140 BOOST_TEST(x1(std::numeric_limits<T>::epsilon()) ==
141 HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
143 BOOST_TEST(std::numeric_limits<T>::epsilon() != (T) 0);
144 if(x1(std::numeric_limits<T>::epsilon()) == x1((T) 0))
145 std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
147 BOOST_TEST(-std::numeric_limits<T>::epsilon() != (T) 0);
148 if(x1(-std::numeric_limits<T>::epsilon()) == x1((T) 0))
149 std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
151 BOOST_TEST((T) 1 + std::numeric_limits<T>::epsilon() != (T) 1);
152 if(x1((T) 1 + std::numeric_limits<T>::epsilon()) == x1((T) 1))
153 std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
155 BOOST_TEST((T) 1 - std::numeric_limits<T>::epsilon() != (T) 1);
156 if(x1((T) 1 - std::numeric_limits<T>::epsilon()) == x1((T) 1))
157 std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
159 BOOST_TEST((T) -1 + std::numeric_limits<T>::epsilon() != (T) -1);
160 if(x1((T) -1 + std::numeric_limits<T>::epsilon()) == x1((T) -1))
161 std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
163 BOOST_TEST((T) -1 - std::numeric_limits<T>::epsilon() != (T) -1);
164 if(x1((T) -1 - std::numeric_limits<T>::epsilon()) == x1((T) -1))
165 std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
167 // As before.
168 if(std::numeric_limits<T>::has_denorm) {
169 if(x1(std::numeric_limits<T>::denorm_min()) == x1(zero)) {
170 std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
172 #if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
173 // The Tru64/CXX standard library prior to 7.1 contains a bug in the
174 // specialization of std::numeric_limits::denorm_min() for long
175 // doubles which causes this test to fail.
176 if(x1(std::numeric_limits<T>::denorm_min()) !=
177 HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()))
179 std::cerr<<"x1(std::numeric_limits<T>::denorm_min()) = "
180 << x1(std::numeric_limits<T>::denorm_min())
181 << "\nhash_value(std::numeric_limits<T>::denorm_min()) = "
182 << HASH_NAMESPACE::hash_value(
183 std::numeric_limits<T>::denorm_min())
184 << "\nx1(0) = "<<x1(0)<<"\n";
186 #endif
189 // NaN also causes borland to crash.
190 #if !defined(__BORLANDC__)
191 if(std::numeric_limits<T>::has_quiet_NaN) {
192 if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(1.0)) {
193 std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
195 BOOST_TEST(x1(std::numeric_limits<T>::quiet_NaN()) ==
196 HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
198 #endif
201 void hash_float_tests()
203 std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
204 std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
205 std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
207 float_tests("float", (float*) 0);
210 void hash_double_tests()
212 float_tests("double", (double*) 0);
215 void hash_long_double_tests()
217 float_tests("long double", (long double*) 0);
220 int main()
222 hash_float_tests();
223 hash_double_tests();
224 hash_long_double_tests();
226 return boost::report_errors();