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
11 # include <boost/functional/hash.hpp>
14 #include <boost/detail/lightweight_test.hpp>
17 #include <boost/limits.hpp>
22 void float_tests(char const* name
, T
* = 0)
25 <<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE
) "::hash<"<<name
<<">\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"
36 HASH_NAMESPACE::hash
<T
> x1
;
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
));
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";
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";
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__)))
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
));
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";
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";
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()));
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);
224 hash_long_double_tests();
226 return boost::report_errors();