// Copyright 2005-2008 Daniel James. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include "./config.hpp" #ifdef TEST_STD_INCLUDES # include #else # include #endif #include #include #include #include #include #include #include "./compile_time.hpp" #if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable:4309) // truncation of constant value #pragma warning(disable:4310) // cast truncates constant value #endif template void numeric_test(T*) { typedef boost::hash_detail::limits limits; compile_time_tests((T*) 0); HASH_NAMESPACE::hash x1; HASH_NAMESPACE::hash x2; T v1 = (T) -5; BOOST_TEST(x1(v1) == x2(v1)); BOOST_TEST(x1(T(-5)) == x2(T(-5))); BOOST_TEST(x1(T(0)) == x2(T(0))); BOOST_TEST(x1(T(10)) == x2(T(10))); BOOST_TEST(x1(T(25)) == x2(T(25))); BOOST_TEST(x1(T(5) - T(5)) == x2(T(0))); BOOST_TEST(x1(T(6) + T(4)) == x2(T(10))); #if defined(TEST_EXTENSIONS) BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5))); BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0))); BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10))); BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25))); if (limits::is_integer) { if(limits::is_signed || limits::digits <= boost::hash_detail::limits::digits) BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5)); BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u)); BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u)); BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u)); } #endif } template void limits_test(T*) { typedef boost::hash_detail::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_TEST(x1(min_value) == x2((limits::min)())); BOOST_TEST(x1(max_value) == x2((limits::max)())); #if defined(TEST_EXTENSIONS) BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value)); BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value)); if (limits::is_integer) { BOOST_TEST(HASH_NAMESPACE::hash_value(min_value) == std::size_t(min_value)); BOOST_TEST(HASH_NAMESPACE::hash_value(max_value) == std::size_t(max_value)); } #endif } } template void poor_quality_tests(T*) { typedef boost::hash_detail::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. if(T(1) != T(-1)) BOOST_TEST(x1(T(1)) != x2(T(-1))); if(T(1) != T(2)) BOOST_TEST(x1(T(1)) != x2(T(2))); if((limits::max)() != (limits::max)() - 1) BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1)); } void bool_test() { HASH_NAMESPACE::hash x1; HASH_NAMESPACE::hash x2; BOOST_TEST(x1(true) == x2(true)); BOOST_TEST(x1(false) == x2(false)); BOOST_TEST(x1(true) != x2(false)); BOOST_TEST(x1(false) != x2(true)); } #define NUMERIC_TEST(type, name) \ std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \ numeric_test((type*) 0); \ limits_test((type*) 0); \ poor_quality_tests((type*) 0); #define NUMERIC_TEST_NO_LIMITS(type, name) \ std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \ numeric_test((type*) 0); \ poor_quality_tests((type*) 0); int main() { NUMERIC_TEST(char, char) NUMERIC_TEST(signed char, schar) NUMERIC_TEST(unsigned char, uchar) #ifndef BOOST_NO_INTRINSIC_WCHAR_T NUMERIC_TEST(wchar_t, wchar) #endif NUMERIC_TEST(short, short) NUMERIC_TEST(unsigned short, ushort) NUMERIC_TEST(int, int) NUMERIC_TEST(unsigned int, uint) NUMERIC_TEST(long, hash_long) NUMERIC_TEST(unsigned long, ulong) #if defined(BOOST_HAS_LONG_LONG) NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long) NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long) #endif NUMERIC_TEST(float, float) NUMERIC_TEST(double, double) bool_test(); return boost::report_errors(); } #if defined(BOOST_MSVC) #pragma warning(pop) #endif