mirror of
https://github.com/boostorg/functional.git
synced 2025-08-02 14:04:27 +02:00
Add tests against Peter's spec.
[SVN r28281]
This commit is contained in:
@@ -29,36 +29,40 @@ BOOST_AUTO_UNIT_TEST(array_int_test)
|
||||
8, -12, 23, 65, 45,
|
||||
-1, 93, -54, 987, 3
|
||||
};
|
||||
boost::hash<int[25]> hasher1;
|
||||
HASH_NAMESPACE::hash<int[25]> hasher1;
|
||||
|
||||
const int length2 = 1;
|
||||
int array2[1] = {3};
|
||||
boost::hash<int[1]> hasher2;
|
||||
HASH_NAMESPACE::hash<int[1]> hasher2;
|
||||
|
||||
const int length3 = 2;
|
||||
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(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<int[3][2]> hasher4;
|
||||
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||
HASH_NAMESPACE::hash<int[3][2]> 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
|
||||
|
@@ -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<test::custom> custom_vector;
|
||||
custom_vector.push_back(5);
|
||||
custom_vector.push_back(25);
|
||||
|
@@ -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<T>::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<T>::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<T>::epsilon()) != x1((T) 0));
|
||||
BOOST_CHECK(x1(std::numeric_limits<T>::epsilon()) ==
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
|
||||
|
||||
// As before.
|
||||
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()) ==
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()));
|
||||
}
|
||||
|
||||
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()) ==
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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]) ==
|
||||
|
@@ -22,26 +22,78 @@
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
template <class T>
|
||||
void numeric_test()
|
||||
void numeric_test(T*)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
|
||||
compile_time_tests((T*) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<T> x1;
|
||||
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(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<T> 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 <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
|
||||
// sign.
|
||||
@@ -55,7 +107,9 @@ void numeric_test()
|
||||
|
||||
#define NUMERIC_TEST(type, 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)
|
||||
@@ -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)
|
||||
|
@@ -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<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
|
||||
}
|
||||
|
@@ -39,18 +39,28 @@ BOOST_AUTO_UNIT_TEST(hash_range_tests)
|
||||
values5.push_back(20);
|
||||
|
||||
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())
|
||||
== 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())
|
||||
|
@@ -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]) ==
|
||||
|
@@ -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]) ==
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user