hash_number_test.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Copyright 2005-2009 Daniel James.
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #include "./config.hpp"
  5. #ifdef BOOST_HASH_TEST_STD_INCLUDES
  6. # include <functional>
  7. #else
  8. # include <boost/container_hash/hash.hpp>
  9. #endif
  10. #include <iostream>
  11. #include <boost/core/lightweight_test.hpp>
  12. #include <boost/container_hash/detail/limits.hpp>
  13. #include <boost/core/enable_if.hpp>
  14. #include "./compile_time.hpp"
  15. #if defined(BOOST_MSVC)
  16. #pragma warning(push)
  17. #pragma warning(disable:4127) // conditional expression is constant
  18. #pragma warning(disable:4309) // truncation of constant value
  19. #pragma warning(disable:4310) // cast truncates constant value
  20. #endif
  21. #if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
  22. #pragma GCC diagnostic ignored "-Wfloat-equal"
  23. #endif
  24. template <class T>
  25. void numeric_extra_tests(typename
  26. boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
  27. void*>::type = 0)
  28. {
  29. typedef boost::hash_detail::limits<T> limits;
  30. if(limits::is_signed ||
  31. limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
  32. {
  33. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
  34. }
  35. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
  36. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
  37. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
  38. }
  39. template <class T>
  40. void numeric_extra_tests(typename
  41. boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
  42. void*>::type = 0)
  43. {
  44. }
  45. template <class T>
  46. void numeric_test(T*)
  47. {
  48. compile_time_tests((T*) 0);
  49. BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
  50. BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
  51. T v1 = (T) -5;
  52. BOOST_TEST(x1(v1) == x2(v1));
  53. BOOST_TEST(x1(T(-5)) == x2(T(-5)));
  54. BOOST_TEST(x1(T(0)) == x2(T(0)));
  55. BOOST_TEST(x1(T(10)) == x2(T(10)));
  56. BOOST_TEST(x1(T(25)) == x2(T(25)));
  57. BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
  58. BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
  59. #if defined(BOOST_HASH_TEST_EXTENSIONS)
  60. BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
  61. BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
  62. BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
  63. BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
  64. numeric_extra_tests<T>();
  65. #endif
  66. }
  67. template <class T>
  68. void limits_test(T*)
  69. {
  70. typedef boost::hash_detail::limits<T> limits;
  71. if(limits::is_specialized)
  72. {
  73. BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
  74. BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
  75. T min_value = (limits::min)();
  76. T max_value = (limits::max)();
  77. BOOST_TEST(x1(min_value) == x2((limits::min)()));
  78. BOOST_TEST(x1(max_value) == x2((limits::max)()));
  79. #if defined(BOOST_HASH_TEST_EXTENSIONS)
  80. BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
  81. BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
  82. if (limits::is_integer)
  83. {
  84. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
  85. == std::size_t(min_value));
  86. BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
  87. == std::size_t(max_value));
  88. }
  89. #endif
  90. }
  91. }
  92. template <class T>
  93. void poor_quality_tests(T*)
  94. {
  95. typedef boost::hash_detail::limits<T> limits;
  96. BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
  97. BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
  98. // A hash function can legally fail these tests, but it'll not be a good
  99. // sign.
  100. if(T(1) != T(-1))
  101. BOOST_TEST(x1(T(1)) != x2(T(-1)));
  102. if(T(1) != T(2))
  103. BOOST_TEST(x1(T(1)) != x2(T(2)));
  104. // TODO: This test is useless for floating point numbers.
  105. T max_number = static_cast<T>((limits::max)());
  106. T max_minus_one = static_cast<T>(max_number - 1);
  107. if (max_number != max_minus_one) {
  108. BOOST_TEST(x1(max_number) != x1(max_minus_one));
  109. }
  110. }
  111. void bool_test()
  112. {
  113. BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
  114. BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
  115. BOOST_TEST(x1(true) == x2(true));
  116. BOOST_TEST(x1(false) == x2(false));
  117. BOOST_TEST(x1(true) != x2(false));
  118. BOOST_TEST(x1(false) != x2(true));
  119. }
  120. #define NUMERIC_TEST(type, name) \
  121. std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
  122. numeric_test((type*) 0); \
  123. limits_test((type*) 0); \
  124. poor_quality_tests((type*) 0);
  125. #define NUMERIC_TEST_NO_LIMITS(type, name) \
  126. std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
  127. numeric_test((type*) 0); \
  128. poor_quality_tests((type*) 0);
  129. int main()
  130. {
  131. NUMERIC_TEST(char, char)
  132. NUMERIC_TEST(signed char, schar)
  133. NUMERIC_TEST(unsigned char, uchar)
  134. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  135. NUMERIC_TEST(wchar_t, wchar)
  136. #endif
  137. #ifndef BOOST_NO_CXX11_CHAR16_T
  138. NUMERIC_TEST(char16_t, char16)
  139. #endif
  140. #ifndef BOOST_NO_CXX11_CHAR32_T
  141. NUMERIC_TEST(char32_t, char32)
  142. #endif
  143. NUMERIC_TEST(short, short)
  144. NUMERIC_TEST(unsigned short, ushort)
  145. NUMERIC_TEST(int, int)
  146. NUMERIC_TEST(unsigned int, uint)
  147. NUMERIC_TEST(long, hash_long)
  148. NUMERIC_TEST(unsigned long, ulong)
  149. #if !defined(BOOST_NO_LONG_LONG)
  150. NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
  151. NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
  152. #endif
  153. #if defined(BOOST_HAS_INT128)
  154. NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
  155. NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
  156. #endif
  157. NUMERIC_TEST(float, float)
  158. NUMERIC_TEST(double, double)
  159. NUMERIC_TEST(std::size_t, size_t)
  160. NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
  161. bool_test();
  162. return boost::report_errors();
  163. }
  164. #if defined(BOOST_MSVC)
  165. #pragma warning(pop)
  166. #endif