diff --git a/hash/test/hash_built_in_array_test.cpp b/hash/test/hash_built_in_array_test.cpp index 87baa1f..a63216e 100644 --- a/hash/test/hash_built_in_array_test.cpp +++ b/hash/test/hash_built_in_array_test.cpp @@ -29,36 +29,40 @@ BOOST_AUTO_UNIT_TEST(array_int_test) 8, -12, 23, 65, 45, -1, 93, -54, 987, 3 }; - boost::hash hasher1; + HASH_NAMESPACE::hash hasher1; const int length2 = 1; int array2[1] = {3}; - boost::hash hasher2; + HASH_NAMESPACE::hash hasher2; const int length3 = 2; int array3[2] = {2, 3}; - boost::hash hasher3; + HASH_NAMESPACE::hash hasher3; - BOOST_CHECK(hasher1(array1) == boost::hash_range(array1, array1 + length1)); - BOOST_CHECK(hasher2(array2) == boost::hash_range(array2, array2 + length2)); - BOOST_CHECK(hasher3(array3) == boost::hash_range(array3, array3 + length3)); + BOOST_CHECK(hasher1(array1) + == HASH_NAMESPACE::hash_range(array1, array1 + length1)); + 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) { - int array4[3][2] = {{-5, 6}, {7, -3}, {26, 1}}; - boost::hash hasher4; + int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}}; + HASH_NAMESPACE::hash hasher; std::size_t seed1 = 0; for(int i = 0; i < 3; ++i) { std::size_t seed2 = 0; for(int j = 0; j < 2; ++j) - boost::hash_combine(seed2, array4[i][j]); - boost::hash_combine(seed1, seed2); + HASH_NAMESPACE::hash_combine(seed2, array[i][j]); + 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 diff --git a/hash/test/hash_custom_test.cpp b/hash/test/hash_custom_test.cpp index eab9948..f11fba6 100644 --- a/hash/test/hash_custom_test.cpp +++ b/hash/test/hash_custom_test.cpp @@ -53,6 +53,11 @@ BOOST_AUTO_UNIT_TEST(custom_tests) test::custom x(55); BOOST_CHECK(custom_hasher(x) == 550u); + { + using namespace HASH_NAMESPACE; + BOOST_CHECK(custom_hasher(x) == hash_value(x)); + } + std::vector custom_vector; custom_vector.push_back(5); custom_vector.push_back(25); diff --git a/hash/test/hash_float_test.cpp b/hash/test/hash_float_test.cpp index 4a69bbc..8c13b36 100644 --- a/hash/test/hash_float_test.cpp +++ b/hash/test/hash_float_test.cpp @@ -30,6 +30,9 @@ void float_tests(T* = 0) BOOST_CHECK(zero == 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; if(std::numeric_limits::has_infinity) { @@ -42,6 +45,10 @@ void float_tests(T* = 0) T minus_infinity2 = log(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 == infinity3); BOOST_CHECK(infinity == infinity4); @@ -75,33 +82,47 @@ void float_tests(T* = 0) T max = (std::numeric_limits::max)(); T half_max = max / 2; - T quater_max = max / 4; - T three_quater_max = max - quater_max; + T quarter_max = max / 4; + 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(quater_max)); + BOOST_CHECK(x1(max) != x1(quarter_max)); BOOST_CHECK(x1(max) != x1(half_max)); - BOOST_CHECK(x1(max) != x1(three_quater_max)); - BOOST_CHECK(x1(quater_max) == x1(quater_max)); - BOOST_CHECK(x1(quater_max) != x1(half_max)); - BOOST_CHECK(x1(quater_max) != x1(three_quater_max)); + BOOST_CHECK(x1(max) != x1(three_quarter_max)); + BOOST_CHECK(x1(quarter_max) == x1(quarter_max)); + BOOST_CHECK(x1(quarter_max) != x1(half_max)); + BOOST_CHECK(x1(quarter_max) != x1(three_quarter_max)); BOOST_CHECK(x1(half_max) == x1(half_max)); - BOOST_CHECK(x1(half_max) != x1(three_quater_max)); - BOOST_CHECK(x1(three_quater_max) == x1(three_quater_max)); + BOOST_CHECK(x1(half_max) != x1(three_quarter_max)); + BOOST_CHECK(x1(three_quarter_max) == x1(three_quarter_max)); T v1 = asin((T) 1); T v2 = acos((T) 0); BOOST_CHECK(v1 == 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::epsilon()) != x1((T) 0)); + BOOST_CHECK(x1(std::numeric_limits::epsilon()) == + HASH_NAMESPACE::hash_value(std::numeric_limits::epsilon())); // As before. if(std::numeric_limits::has_denorm) { BOOST_CHECK(x1(std::numeric_limits::denorm_min()) != x1(zero)); + BOOST_CHECK(x1(std::numeric_limits::denorm_min()) == + HASH_NAMESPACE::hash_value(std::numeric_limits::denorm_min())); } if(std::numeric_limits::has_quiet_NaN) { BOOST_CHECK(x1(std::numeric_limits::quiet_NaN()) != x1(zero)); + BOOST_CHECK(x1(std::numeric_limits::quiet_NaN()) == + HASH_NAMESPACE::hash_value(std::numeric_limits::quiet_NaN())); } } diff --git a/hash/test/hash_map_test.hpp b/hash/test/hash_map_test.hpp index 09454e5..f4d6164 100644 --- a/hash/test/hash_map_test.hpp +++ b/hash/test/hash_map_test.hpp @@ -36,6 +36,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) for(int i2 = 0; i2 < number_of_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) { BOOST_CHECK( (containers[i2] == containers[j2]) == diff --git a/hash/test/hash_number_test.cpp b/hash/test/hash_number_test.cpp index b9a3a74..00f5f52 100644 --- a/hash/test/hash_number_test.cpp +++ b/hash/test/hash_number_test.cpp @@ -22,26 +22,78 @@ #include "./compile_time.hpp" template -void numeric_test() +void numeric_test(T*) { + typedef std::numeric_limits limits; + compile_time_tests((T*) 0); HASH_NAMESPACE::hash x1; HASH_NAMESPACE::hash 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(10)) == x2(T(10))); BOOST_CHECK(x1(T(25)) == x2(T(25))); - BOOST_CHECK(x1(T(5) - T(5)) == x2(T(0))); BOOST_CHECK(x1(T(6) + T(4)) == x2(T(10))); - typedef std::numeric_limits limits; - BOOST_CHECK(limits::is_specialized); +#if defined(TEST_EXTENSIONS) + 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)())); - BOOST_CHECK(x1((limits::max)()) == x2((limits::max)())); + if (limits::is_integer) + { + 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 +void limits_test(T*) +{ + typedef std::numeric_limits limits; + + if(limits::is_specialized) + { + HASH_NAMESPACE::hash x1; + HASH_NAMESPACE::hash 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 +void poor_quality_tests(T*) +{ + typedef std::numeric_limits limits; + + HASH_NAMESPACE::hash x1; + HASH_NAMESPACE::hash x2; // A hash function can legally fail these tests, but it'll not be a good // sign. @@ -55,7 +107,9 @@ void numeric_test() #define NUMERIC_TEST(type, name) \ BOOST_AUTO_UNIT_TEST(BOOST_PP_CAT(test_, name)) { \ - numeric_test(); \ + numeric_test((type*) 0); \ + limits_test((type*) 0); \ + poor_quality_tests((type*) 0); \ } NUMERIC_TEST(bool, bool) @@ -71,6 +125,7 @@ NUMERIC_TEST(int, int) NUMERIC_TEST(unsigned int, uint) NUMERIC_TEST(long, hash_long) NUMERIC_TEST(unsigned long, ulong) + NUMERIC_TEST(float, float) NUMERIC_TEST(double, double) NUMERIC_TEST(long double, ldouble) diff --git a/hash/test/hash_pointer_test.cpp b/hash/test/hash_pointer_test.cpp index 9fe1247..5511b5b 100644 --- a/hash/test/hash_pointer_test.cpp +++ b/hash/test/hash_pointer_test.cpp @@ -35,4 +35,43 @@ BOOST_AUTO_UNIT_TEST(pointer_tests) BOOST_CHECK(x1(0) == x2(0)); BOOST_CHECK(x1(&int1) == x2(&int1)); 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 hasher_void; + HASH_NAMESPACE::hash 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 } diff --git a/hash/test/hash_range_test.cpp b/hash/test/hash_range_test.cpp index 48105a9..e5a652c 100644 --- a/hash/test/hash_range_test.cpp +++ b/hash/test/hash_range_test.cpp @@ -39,18 +39,28 @@ BOOST_AUTO_UNIT_TEST(hash_range_tests) values5.push_back(20); std::vector 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()) == HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_CHECK(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) != HASH_NAMESPACE::hash_range(values1.begin(), values1.end())); 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()) != HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) == HASH_NAMESPACE::hash_range(x.begin(), x.end())); 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()) != HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_CHECK(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) diff --git a/hash/test/hash_sequence_test.hpp b/hash/test/hash_sequence_test.hpp index f6dbae7..6a9e8db 100644 --- a/hash/test/hash_sequence_test.hpp +++ b/hash/test/hash_sequence_test.hpp @@ -39,6 +39,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) for(int i2 = 0; i2 < number_of_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) { BOOST_CHECK( (containers[i2] == containers[j2]) == diff --git a/hash/test/hash_set_test.hpp b/hash/test/hash_set_test.hpp index 2681587..76fb820 100644 --- a/hash/test/hash_set_test.hpp +++ b/hash/test/hash_set_test.hpp @@ -37,6 +37,13 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) for(int i2 = 0; i2 < number_of_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) { BOOST_CHECK( (containers[i2] == containers[j2]) == diff --git a/hash/test/hash_string_test.cpp b/hash/test/hash_string_test.cpp index f1daf8d..a36f345 100644 --- a/hash/test/hash_string_test.cpp +++ b/hash/test/hash_string_test.cpp @@ -29,6 +29,18 @@ BOOST_AUTO_UNIT_TEST(string_tests) BOOST_CHECK(x1("Hello") == x2(std::string("Hel") + "lo")); 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) @@ -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"") == 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