Add tests against Peter's spec.

[SVN r28281]
This commit is contained in:
Daniel James
2005-04-16 16:56:27 +00:00
parent 3bb76776e6
commit 1357e13c45
10 changed files with 207 additions and 28 deletions

View File

@@ -29,36 +29,40 @@ BOOST_AUTO_UNIT_TEST(array_int_test)
8, -12, 23, 65, 45, 8, -12, 23, 65, 45,
-1, 93, -54, 987, 3 -1, 93, -54, 987, 3
}; };
boost::hash<int[25]> hasher1; HASH_NAMESPACE::hash<int[25]> hasher1;
const int length2 = 1; const int length2 = 1;
int array2[1] = {3}; int array2[1] = {3};
boost::hash<int[1]> hasher2; HASH_NAMESPACE::hash<int[1]> hasher2;
const int length3 = 2; const int length3 = 2;
int array3[2] = {2, 3}; int array3[2] = {2, 3};
boost::hash<int[2]> hasher3; HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_CHECK(hasher1(array1) == boost::hash_range(array1, array1 + length1)); BOOST_CHECK(hasher1(array1)
BOOST_CHECK(hasher2(array2) == boost::hash_range(array2, array2 + length2)); == HASH_NAMESPACE::hash_range(array1, array1 + length1));
BOOST_CHECK(hasher3(array3) == boost::hash_range(array3, array3 + length3)); BOOST_CHECK(hasher2(array2)
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
BOOST_CHECK(hasher3(array3)
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
} }
BOOST_AUTO_UNIT_TEST(two_dimensional_array_test) BOOST_AUTO_UNIT_TEST(two_dimensional_array_test)
{ {
int array4[3][2] = {{-5, 6}, {7, -3}, {26, 1}}; int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
boost::hash<int[3][2]> hasher4; HASH_NAMESPACE::hash<int[3][2]> hasher;
std::size_t seed1 = 0; std::size_t seed1 = 0;
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
std::size_t seed2 = 0; std::size_t seed2 = 0;
for(int j = 0; j < 2; ++j) for(int j = 0; j < 2; ++j)
boost::hash_combine(seed2, array4[i][j]); HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
boost::hash_combine(seed1, seed2); HASH_NAMESPACE::hash_combine(seed1, seed2);
} }
BOOST_CHECK(hasher4(array4) == seed1); BOOST_CHECK(hasher(array) == seed1);
BOOST_CHECK(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
} }
#endif // TEST_EXTENSIONS #endif // TEST_EXTENSIONS

View File

@@ -53,6 +53,11 @@ BOOST_AUTO_UNIT_TEST(custom_tests)
test::custom x(55); test::custom x(55);
BOOST_CHECK(custom_hasher(x) == 550u); BOOST_CHECK(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
BOOST_CHECK(custom_hasher(x) == hash_value(x));
}
std::vector<test::custom> custom_vector; std::vector<test::custom> custom_vector;
custom_vector.push_back(5); custom_vector.push_back(5);
custom_vector.push_back(25); custom_vector.push_back(25);

View File

@@ -30,6 +30,9 @@ void float_tests(T* = 0)
BOOST_CHECK(zero == minus_zero); BOOST_CHECK(zero == minus_zero);
BOOST_CHECK(x1(zero) == x1(minus_zero)); BOOST_CHECK(x1(zero) == x1(minus_zero));
BOOST_CHECK(x1(zero) == HASH_NAMESPACE::hash_value(zero));
BOOST_CHECK(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
using namespace std; using namespace std;
if(std::numeric_limits<T>::has_infinity) { if(std::numeric_limits<T>::has_infinity) {
@@ -42,6 +45,10 @@ void float_tests(T* = 0)
T minus_infinity2 = log(zero); T minus_infinity2 = log(zero);
T minus_infinity3 = (T) 1. / minus_zero; T minus_infinity3 = (T) 1. / minus_zero;
BOOST_CHECK(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
BOOST_CHECK(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity));
BOOST_CHECK(infinity == infinity2); BOOST_CHECK(infinity == infinity2);
BOOST_CHECK(infinity == infinity3); BOOST_CHECK(infinity == infinity3);
BOOST_CHECK(infinity == infinity4); BOOST_CHECK(infinity == infinity4);
@@ -75,33 +82,47 @@ void float_tests(T* = 0)
T max = (std::numeric_limits<T>::max)(); T max = (std::numeric_limits<T>::max)();
T half_max = max / 2; T half_max = max / 2;
T quater_max = max / 4; T quarter_max = max / 4;
T three_quater_max = max - quater_max; T three_quarter_max = max - quarter_max;
BOOST_CHECK(x1(max) == HASH_NAMESPACE::hash_value(max));
BOOST_CHECK(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
BOOST_CHECK(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
BOOST_CHECK(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
BOOST_CHECK(x1(max) == x1(max)); BOOST_CHECK(x1(max) == x1(max));
BOOST_CHECK(x1(max) != x1(quater_max)); BOOST_CHECK(x1(max) != x1(quarter_max));
BOOST_CHECK(x1(max) != x1(half_max)); BOOST_CHECK(x1(max) != x1(half_max));
BOOST_CHECK(x1(max) != x1(three_quater_max)); BOOST_CHECK(x1(max) != x1(three_quarter_max));
BOOST_CHECK(x1(quater_max) == x1(quater_max)); BOOST_CHECK(x1(quarter_max) == x1(quarter_max));
BOOST_CHECK(x1(quater_max) != x1(half_max)); BOOST_CHECK(x1(quarter_max) != x1(half_max));
BOOST_CHECK(x1(quater_max) != x1(three_quater_max)); BOOST_CHECK(x1(quarter_max) != x1(three_quarter_max));
BOOST_CHECK(x1(half_max) == x1(half_max)); BOOST_CHECK(x1(half_max) == x1(half_max));
BOOST_CHECK(x1(half_max) != x1(three_quater_max)); BOOST_CHECK(x1(half_max) != x1(three_quarter_max));
BOOST_CHECK(x1(three_quater_max) == x1(three_quater_max)); BOOST_CHECK(x1(three_quarter_max) == x1(three_quarter_max));
T v1 = asin((T) 1); T v1 = asin((T) 1);
T v2 = acos((T) 0); T v2 = acos((T) 0);
BOOST_CHECK(v1 == v2); BOOST_CHECK(v1 == v2);
BOOST_CHECK(x1(v1) == x1(v2)); BOOST_CHECK(x1(v1) == x1(v2));
BOOST_CHECK(x1(v1) == HASH_NAMESPACE::hash_value(v1));
BOOST_CHECK(x1(v2) == HASH_NAMESPACE::hash_value(v2));
BOOST_CHECK(x1(std::numeric_limits<T>::epsilon()) != x1((T) 0)); BOOST_CHECK(x1(std::numeric_limits<T>::epsilon()) != x1((T) 0));
BOOST_CHECK(x1(std::numeric_limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
// As before. // As before.
if(std::numeric_limits<T>::has_denorm) { if(std::numeric_limits<T>::has_denorm) {
BOOST_CHECK(x1(std::numeric_limits<T>::denorm_min()) != x1(zero)); BOOST_CHECK(x1(std::numeric_limits<T>::denorm_min()) != x1(zero));
BOOST_CHECK(x1(std::numeric_limits<T>::denorm_min()) ==
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()));
} }
if(std::numeric_limits<T>::has_quiet_NaN) { if(std::numeric_limits<T>::has_quiet_NaN) {
BOOST_CHECK(x1(std::numeric_limits<T>::quiet_NaN()) != x1(zero)); BOOST_CHECK(x1(std::numeric_limits<T>::quiet_NaN()) != x1(zero));
BOOST_CHECK(x1(std::numeric_limits<T>::quiet_NaN()) ==
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
} }
} }

View File

@@ -36,6 +36,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2])); BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_CHECK(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_CHECK(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_CHECK( BOOST_CHECK(
(containers[i2] == containers[j2]) == (containers[i2] == containers[j2]) ==

View File

@@ -22,26 +22,78 @@
#include "./compile_time.hpp" #include "./compile_time.hpp"
template <class T> template <class T>
void numeric_test() void numeric_test(T*)
{ {
typedef std::numeric_limits<T> limits;
compile_time_tests((T*) 0); compile_time_tests((T*) 0);
HASH_NAMESPACE::hash<T> x1; HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2; HASH_NAMESPACE::hash<T> x2;
T v1 = -5;
BOOST_CHECK(x1(v1) == x2(v1));
BOOST_CHECK(x1(T(-5)) == x2(T(-5)));
BOOST_CHECK(x1(T(0)) == x2(T(0))); BOOST_CHECK(x1(T(0)) == x2(T(0)));
BOOST_CHECK(x1(T(10)) == x2(T(10))); BOOST_CHECK(x1(T(10)) == x2(T(10)));
BOOST_CHECK(x1(T(25)) == x2(T(25))); BOOST_CHECK(x1(T(25)) == x2(T(25)));
BOOST_CHECK(x1(T(5) - T(5)) == x2(T(0))); BOOST_CHECK(x1(T(5) - T(5)) == x2(T(0)));
BOOST_CHECK(x1(T(6) + T(4)) == x2(T(10))); BOOST_CHECK(x1(T(6) + T(4)) == x2(T(10)));
typedef std::numeric_limits<T> limits; #if defined(TEST_EXTENSIONS)
BOOST_CHECK(limits::is_specialized); BOOST_CHECK(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
BOOST_CHECK(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
BOOST_CHECK(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
BOOST_CHECK(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
BOOST_CHECK(x1((limits::min)()) == x2((limits::min)())); if (limits::is_integer)
BOOST_CHECK(x1((limits::max)()) == x2((limits::max)())); {
BOOST_CHECK(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
BOOST_CHECK(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_CHECK(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_CHECK(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
#endif
}
template <class T>
void limits_test(T*)
{
typedef std::numeric_limits<T> limits;
if(limits::is_specialized)
{
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
T min_value = (limits::min)();
T max_value = (limits::max)();
BOOST_CHECK(x1(min_value) == x2((limits::min)()));
BOOST_CHECK(x1(max_value) == x2((limits::max)()));
#if defined(TEST_EXTENSIONS)
BOOST_CHECK(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
BOOST_CHECK(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
if (limits::is_integer)
{
BOOST_CHECK(HASH_NAMESPACE::hash_value(min_value)
== std::size_t(min_value));
BOOST_CHECK(HASH_NAMESPACE::hash_value(max_value)
== std::size_t(max_value));
}
#endif
}
}
template <class T>
void poor_quality_tests(T*)
{
typedef std::numeric_limits<T> limits;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
// A hash function can legally fail these tests, but it'll not be a good // A hash function can legally fail these tests, but it'll not be a good
// sign. // sign.
@@ -55,7 +107,9 @@ void numeric_test()
#define NUMERIC_TEST(type, name) \ #define NUMERIC_TEST(type, name) \
BOOST_AUTO_UNIT_TEST(BOOST_PP_CAT(test_, name)) { \ BOOST_AUTO_UNIT_TEST(BOOST_PP_CAT(test_, name)) { \
numeric_test<type>(); \ numeric_test((type*) 0); \
limits_test((type*) 0); \
poor_quality_tests((type*) 0); \
} }
NUMERIC_TEST(bool, bool) NUMERIC_TEST(bool, bool)
@@ -71,6 +125,7 @@ NUMERIC_TEST(int, int)
NUMERIC_TEST(unsigned int, uint) NUMERIC_TEST(unsigned int, uint)
NUMERIC_TEST(long, hash_long) NUMERIC_TEST(long, hash_long)
NUMERIC_TEST(unsigned long, ulong) NUMERIC_TEST(unsigned long, ulong)
NUMERIC_TEST(float, float) NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double) NUMERIC_TEST(double, double)
NUMERIC_TEST(long double, ldouble) NUMERIC_TEST(long double, ldouble)

View File

@@ -35,4 +35,43 @@ BOOST_AUTO_UNIT_TEST(pointer_tests)
BOOST_CHECK(x1(0) == x2(0)); BOOST_CHECK(x1(0) == x2(0));
BOOST_CHECK(x1(&int1) == x2(&int1)); BOOST_CHECK(x1(&int1) == x2(&int1));
BOOST_CHECK(x1(&int2) == x2(&int2)); BOOST_CHECK(x1(&int2) == x2(&int2));
#if defined(TEST_EXTENSIONS)
BOOST_CHECK(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
BOOST_CHECK(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal:
BOOST_CHECK(x1(0) == 0);
#endif
}
void void_func1() {}
void void_func2() {}
int int_func1(int) { return 0; }
int int_func2(int) { return 0; }
BOOST_AUTO_UNIT_TEST(function_pointer_tests)
{
compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0);
HASH_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_CHECK(hasher_void(0) == hasher_void(0));
BOOST_CHECK(hasher_void(&void_func1) == hasher_void(&void_func1));
BOOST_CHECK(hasher_void(&void_func1) != hasher_void(&void_func2));
BOOST_CHECK(hasher_void(&void_func1) != hasher_void(0));
BOOST_CHECK(hasher_int(0) == hasher_int(0));
BOOST_CHECK(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_CHECK(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_CHECK(hasher_int(&int_func1) != hasher_int(0));
#if defined(TEST_EXTENSIONS)
BOOST_CHECK(hasher_void(&void_func1)
== HASH_NAMESPACE::hash_value(&void_func1));
BOOST_CHECK(hasher_int(&int_func1)
== HASH_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal:
BOOST_CHECK(hasher_void(0) == 0);
#endif
} }

View File

@@ -39,18 +39,28 @@ BOOST_AUTO_UNIT_TEST(hash_range_tests)
values5.push_back(20); values5.push_back(20);
std::vector<int> x; std::vector<int> x;
std::size_t x_seed = 0;
BOOST_CHECK(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end())); == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end())); != HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10); x.push_back(10);
HASH_NAMESPACE::hash_combine(x_seed, 10);
BOOST_CHECK(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end())); != HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end())); == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
x.push_back(20); x.push_back(20);
HASH_NAMESPACE::hash_combine(x_seed, 20);
BOOST_CHECK(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end())); != HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())

View File

@@ -39,6 +39,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2])); BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_CHECK(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_CHECK(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_CHECK( BOOST_CHECK(
(containers[i2] == containers[j2]) == (containers[i2] == containers[j2]) ==

View File

@@ -37,6 +37,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2])); BOOST_CHECK(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_CHECK(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_CHECK(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_CHECK( BOOST_CHECK(
(containers[i2] == containers[j2]) == (containers[i2] == containers[j2]) ==

View File

@@ -29,6 +29,18 @@ BOOST_AUTO_UNIT_TEST(string_tests)
BOOST_CHECK(x1("Hello") == x2(std::string("Hel") + "lo")); BOOST_CHECK(x1("Hello") == x2(std::string("Hel") + "lo"));
BOOST_CHECK(x1("") == x2(std::string())); BOOST_CHECK(x1("") == x2(std::string()));
#if defined(TEST_EXTENSIONS)
std::string value1;
std::string value2("Hello");
BOOST_CHECK(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_CHECK(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_CHECK(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
} }
#if !defined(BOOST_NO_STD_WSTRING) #if !defined(BOOST_NO_STD_WSTRING)
@@ -41,5 +53,17 @@ BOOST_AUTO_UNIT_TEST(wstring_tests)
BOOST_CHECK(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo")); BOOST_CHECK(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
BOOST_CHECK(x1(L"") == x2(std::wstring())); BOOST_CHECK(x1(L"") == x2(std::wstring()));
#if defined(TEST_EXTENSIONS)
std::wstring value1;
std::wstring value2(L"Hello");
BOOST_CHECK(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_CHECK(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_CHECK(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_CHECK(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
} }
#endif #endif