diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index 7d416f1..3c587a3 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -13,12 +13,13 @@ #if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP +#include +#include + #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif -#include - #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include #endif @@ -29,6 +30,85 @@ namespace boost { + template + std::size_t hash_value(std::pair const&); + template + std::size_t hash_value(std::vector const&); + template + std::size_t hash_value(std::list const& v); + template + std::size_t hash_value(std::deque const& v); + template + std::size_t hash_value(std::set const& v); + template + std::size_t hash_value(std::multiset const& v); + template + std::size_t hash_value(std::map const& v); + template + std::size_t hash_value(std::multimap const& v); + + template + std::size_t hash_value(std::complex const&); + + template + std::size_t hash_value(std::pair const& v) + { + std::size_t seed = 0; + hash_combine(seed, v.first); + hash_combine(seed, v.second); + return seed; + } + + template + std::size_t hash_value(std::vector const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::list const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::deque const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::set const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multiset const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::map const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::multimap const& v) + { + return hash_range(v.begin(), v.end()); + } + + template + std::size_t hash_value(std::complex const& v) + { + boost::hash hasher; + std::size_t seed = hasher(v.imag()); + seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); + return seed; + } // // call_hash_impl diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 17cee1e..89196bc 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -70,26 +69,6 @@ namespace boost template std::size_t hash_value(std::basic_string, A> const&); - template - std::size_t hash_value(std::pair const&); - template - std::size_t hash_value(std::vector const&); - template - std::size_t hash_value(std::list const& v); - template - std::size_t hash_value(std::deque const& v); - template - std::size_t hash_value(std::set const& v); - template - std::size_t hash_value(std::multiset const& v); - template - std::size_t hash_value(std::map const& v); - template - std::size_t hash_value(std::multimap const& v); - - template - std::size_t hash_value(std::complex const&); - // Implementation namespace hash_detail @@ -313,66 +292,6 @@ namespace boost return boost::hash_detail::float_hash_value(v); } - template - std::size_t hash_value(std::pair const& v) - { - std::size_t seed = 0; - hash_combine(seed, v.first); - hash_combine(seed, v.second); - return seed; - } - - template - std::size_t hash_value(std::vector const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::list const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::deque const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::set const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multiset const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::map const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::multimap const& v) - { - return hash_range(v.begin(), v.end()); - } - - template - std::size_t hash_value(std::complex const& v) - { - boost::hash hasher; - std::size_t seed = hasher(v.imag()); - seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); - return seed; - } - // // boost::hash // @@ -472,6 +391,11 @@ namespace boost BOOST_HASH_SPECIALIZE_REF(std::wstring) #endif +#if defined(BOOST_HAS_LONG_LONG) + BOOST_HASH_SPECIALIZE(boost::long_long_type); + BOOST_HASH_SPECIALIZE(boost::ulong_long_type); +#endif + #undef BOOST_HASH_SPECIALIZE #undef BOOST_HASH_SPECIALIZE_REF diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 0f43439..9004724 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -44,4 +44,15 @@ test-suite functional/hash [ run hash_no_ext_macro_2.cpp ] ; -build-project ../examples ; +test-suite functional/hash_no_ext + : + [ run hash_number_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ] + [ run hash_pointer_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ] + [ run hash_function_pointer_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ] + [ run hash_float_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ] + [ run hash_long_double_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ] + [ run hash_string_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ] + [ run link_test.cpp link_test_2.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ] + ; + +# build-project ../examples ; diff --git a/test/config.hpp b/test/config.hpp index 0f84cc7..1fd0f5f 100644 --- a/test/config.hpp +++ b/test/config.hpp @@ -5,7 +5,7 @@ #if defined(TEST_STD) # define TEST_STD_INCLUDES -# define HASH_NAMESPACE std::tr1 +# define HASH_NAMESPACE std #else # define HASH_NAMESPACE boost # if !defined(BOOST_HASH_NO_EXTENSIONS) diff --git a/test/hash_complex_test.cpp b/test/hash_complex_test.cpp index 686b25a..f791391 100644 --- a/test/hash_complex_test.cpp +++ b/test/hash_complex_test.cpp @@ -5,18 +5,20 @@ #include "./config.hpp" -#ifdef TEST_EXTENSIONS -# ifdef TEST_STD_INCLUDES -# include -# else -# include -# endif +#if !defined(TEST_EXTENSIONS) + +int main() {} + +#else + +#ifdef TEST_STD_INCLUDES +# include +#else +# include #endif #include -#ifdef TEST_EXTENSIONS - #include #include #include @@ -91,4 +93,4 @@ int main() return boost::report_errors(); } -#endif +#endif // TEST_EXTENSIONS diff --git a/test/hash_float_test.hpp b/test/hash_float_test.hpp index 77c652c..b1c19fc 100644 --- a/test/hash_float_test.hpp +++ b/test/hash_float_test.hpp @@ -15,6 +15,8 @@ #include #include +#include +#include #include @@ -42,8 +44,6 @@ void float_tests(char const* name, T* = 0) <<"\n" <<"boost::hash_detail::call_ldexp::float_type = " <::float_type*)0)<<"\n" - <<"boost::call_frexp::float_type = " - <::float_type*)0)<<"\n" <<"boost::hash_detail::call_frexp::float_type = " <::float_type*)0)<<"\n" <<"boost::hash_detail::select_hash_type::type = " @@ -59,8 +59,10 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(zero == minus_zero); BOOST_TEST(x1(zero) == x1(minus_zero)); +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero)); BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); +#endif using namespace std; @@ -78,9 +80,11 @@ void float_tests(char const* name, T* = 0) T minus_infinity2 = (T) -1. / zero; T minus_infinity3 = (T) 1. / minus_zero; +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity)); BOOST_TEST(x1(minus_infinity) == HASH_NAMESPACE::hash_value(minus_infinity)); +#endif if(infinity == infinity2) BOOST_TEST(x1(infinity) == x1(infinity2)); @@ -134,10 +138,12 @@ void float_tests(char const* name, T* = 0) BOOST_TEST(half_max != three_quarter_max); BOOST_TEST(quarter_max != three_quarter_max); +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max)); +#endif // The '!=' tests could legitimately fail, but with my hash it indicates a bug. BOOST_TEST(x1(max) == x1(max)); @@ -159,12 +165,18 @@ void float_tests(char const* name, T* = 0) T v2 = acos((T) 0); if(v1 == v2) BOOST_TEST(x1(v1) == x1(v2)); + +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1)); BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2)); #endif + +#endif +#if defined(TEST_EXTENSIONS) BOOST_TEST(x1(boost::hash_detail::limits::epsilon()) == HASH_NAMESPACE::hash_value(boost::hash_detail::limits::epsilon())); +#endif BOOST_TEST(boost::hash_detail::limits::epsilon() != (T) 0); if(x1(boost::hash_detail::limits::epsilon()) == x1((T) 0)) @@ -195,7 +207,7 @@ void float_tests(char const* name, T* = 0) if(x1(boost::hash_detail::limits::denorm_min()) == x1(zero)) { std::cerr<<"x1(denorm_min) == x1(zero) == "<::has_quiet_NaN) { if(x1(boost::hash_detail::limits::quiet_NaN()) == x1(1.0)) { std::cerr<<"x1(quiet_NaN) == x1(1.0) == "< template void unused(T const&) {} @@ -30,10 +35,11 @@ void fwd_test() unused(y1); unused(y2); unused(y3); } - int main() { fwd_test(); + return boost::report_errors(); } +#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) diff --git a/test/hash_no_ext_macro_1.cpp b/test/hash_no_ext_macro_1.cpp index 640c36a..1d238c0 100644 --- a/test/hash_no_ext_macro_1.cpp +++ b/test/hash_no_ext_macro_1.cpp @@ -4,9 +4,17 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define HASH_NAMESPACE boost + +// Include header without BOOST_HASH_NO_EXTENSIONS defined +#if defined(BOOST_HASH_NO_EXTENSIONS) +#undef BOOST_HASH_NO_EXTENSIONS +#endif #include + +// Include header with BOOST_HASH_NO_EXTENSIONS defined #define BOOST_HASH_NO_EXTENSIONS #include + #include #include #include diff --git a/test/hash_no_ext_macro_2.cpp b/test/hash_no_ext_macro_2.cpp index 2f53779..6ab083e 100644 --- a/test/hash_no_ext_macro_2.cpp +++ b/test/hash_no_ext_macro_2.cpp @@ -4,10 +4,17 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define HASH_NAMESPACE boost + +// Include header with BOOST_HASH_NO_EXTENSIONS defined +#if !defined(BOOST_HASH_NO_EXTENSIONS) #define BOOST_HASH_NO_EXTENSIONS +#endif #include + +// Include header without BOOST_HASH_NO_EXTENSIONS defined #undef BOOST_HASH_NO_EXTENSIONS #include + #include #include diff --git a/test/hash_range_test.cpp b/test/hash_range_test.cpp index 66aad26..7d71f45 100644 --- a/test/hash_range_test.cpp +++ b/test/hash_range_test.cpp @@ -5,18 +5,20 @@ #include "./config.hpp" -#ifdef TEST_EXTENSIONS -# ifdef TEST_STD_INCLUDES -# include -# else -# include -# endif +#if !defined(TEST_EXTENSIONS) + +int main() {} + +#else + +#ifdef TEST_STD_INCLUDES +# include +#else +# include #endif #include -#ifdef TEST_EXTENSIONS - #include #include #include @@ -74,8 +76,6 @@ void hash_range_tests() BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end())); } -#endif - int main() { hash_range_tests(); @@ -83,3 +83,4 @@ int main() return boost::report_errors(); } +#endif // TEST_EXTESNIONS diff --git a/test/link_ext_test.cpp b/test/link_ext_test.cpp index ca4c8f3..d334035 100644 --- a/test/link_ext_test.cpp +++ b/test/link_ext_test.cpp @@ -9,14 +9,23 @@ #include int f(std::size_t hash1, int* x1) { + // Check that HASH_NAMESPACE::hash works in both files. HASH_NAMESPACE::hash ptr_hasher; BOOST_TEST(hash1 == ptr_hasher(x1)); +#if defined(TEST_EXTENSIONS) + // Check that std::vector is avaiable in this file. std::vector x; x.push_back(*x1); HASH_NAMESPACE::hash > vector_hasher; return vector_hasher(x) != HASH_NAMESPACE::hash_value(x); + +#else + + return 0; + +#endif }