From be710a76bec50d4cf0777d968ebc8da37e1a8136 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 9 Jul 2012 20:53:36 +0000 Subject: [PATCH] Hash: Merge using SFINAE to avoid implicit casts. [SVN r79394] --- hash/test/Jamfile.v2 | 76 ++++----- ...plicit_fail_test.cpp => implicit_test.cpp} | 0 include/boost/functional/hash/hash.hpp | 160 +++++++----------- 3 files changed, 91 insertions(+), 145 deletions(-) rename hash/test/{implicit_fail_test.cpp => implicit_test.cpp} (100%) diff --git a/hash/test/Jamfile.v2 b/hash/test/Jamfile.v2 index 77ac13f..47f0a95 100644 --- a/hash/test/Jamfile.v2 +++ b/hash/test/Jamfile.v2 @@ -19,54 +19,40 @@ project hash-tests test-suite functional/hash : - [ run hash_fwd_test_1.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_fwd_test_2.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_number_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_pointer_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_function_pointer_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_float_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_long_double_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_string_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_range_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_custom_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_global_namespace_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_friend_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_built_in_array_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_value_array_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_vector_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_list_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_deque_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_set_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_map_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_complex_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_type_index_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_std_array_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_std_tuple_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run link_test.cpp link_test_2.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run link_ext_test.cpp link_no_ext_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run extensions_hpp_test.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ compile-fail hash_no_ext_fail_test.cpp : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ compile-fail namespace_fail_test.cpp : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ compile-fail implicit_fail_test.cpp : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_no_ext_macro_1.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] - [ run hash_no_ext_macro_2.cpp : : : BOOST_HASH_NO_IMPLICIT_CASTS ] + [ run hash_fwd_test_1.cpp ] + [ run hash_fwd_test_2.cpp ] + [ run hash_number_test.cpp ] + [ run hash_pointer_test.cpp ] + [ run hash_function_pointer_test.cpp ] + [ run hash_float_test.cpp ] + [ run hash_long_double_test.cpp ] + [ run hash_string_test.cpp ] + [ run hash_range_test.cpp ] + [ run hash_custom_test.cpp ] + [ run hash_global_namespace_test.cpp ] + [ run hash_friend_test.cpp ] + [ run hash_built_in_array_test.cpp ] + [ run hash_value_array_test.cpp ] + [ run hash_vector_test.cpp ] + [ run hash_list_test.cpp ] + [ run hash_deque_test.cpp ] + [ run hash_set_test.cpp ] + [ run hash_map_test.cpp ] + [ run hash_complex_test.cpp ] + [ run hash_type_index_test.cpp ] + [ run hash_std_array_test.cpp ] + [ run hash_std_tuple_test.cpp ] + [ run link_test.cpp link_test_2.cpp ] + [ run link_ext_test.cpp link_no_ext_test.cpp ] + [ run extensions_hpp_test.cpp ] + [ compile-fail hash_no_ext_fail_test.cpp ] + [ compile-fail namespace_fail_test.cpp ] + [ run implicit_test.cpp ] + [ run hash_no_ext_macro_1.cpp ] + [ run hash_no_ext_macro_2.cpp ] [ compile deprecated_container_fwd.cpp ] ; -test-suite functional/hash_implicit_casts - : - [ run hash_number_test.cpp : : : : implicit_number ] - [ run hash_pointer_test.cpp : : : : implicit_pointer ] - [ run hash_function_pointer_test.cpp : : : : implicit_function_pointer ] - [ run hash_float_test.cpp : : : : implicit_float ] - [ run hash_string_test.cpp : : : : implicit_string ] - [ run hash_range_test.cpp : : : : implicit_range ] - [ run hash_custom_test.cpp : : : : implicit_custom ] - [ run hash_built_in_array_test.cpp : : : : implicit_built_in_array ] - [ run link_test.cpp link_test_2.cpp : : : : implicit_link ] - [ run implicit_fail_test.cpp : : : : implicit_test ] - ; - test-suite functional/hash_no_ext : [ run hash_number_test.cpp : : : BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ] diff --git a/hash/test/implicit_fail_test.cpp b/hash/test/implicit_test.cpp similarity index 100% rename from hash/test/implicit_fail_test.cpp rename to hash/test/implicit_test.cpp diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 51ec860..7559e56 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -16,10 +16,6 @@ #include #include -#if defined(BOOST_HASH_NO_IMPLICIT_CASTS) -#include -#endif - #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) #include #endif @@ -37,38 +33,63 @@ namespace boost { -#if defined(BOOST_HASH_NO_IMPLICIT_CASTS) + namespace hash_detail + { + struct enable_hash_value { typedef std::size_t type; }; - // If you get a static assertion here, it's because hash_value - // isn't declared for your type. - template - std::size_t hash_value(T const&) { - BOOST_STATIC_ASSERT((T*) 0 && false); - return 0; - } + template struct basic_numbers {}; + template struct long_numbers {}; + template struct ulong_numbers {}; + template struct float_numbers {}; -#endif - - std::size_t hash_value(bool); - std::size_t hash_value(char); - std::size_t hash_value(unsigned char); - std::size_t hash_value(signed char); - std::size_t hash_value(short); - std::size_t hash_value(unsigned short); - std::size_t hash_value(int); - std::size_t hash_value(unsigned int); - std::size_t hash_value(long); - std::size_t hash_value(unsigned long); + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) - std::size_t hash_value(wchar_t); + template <> struct basic_numbers : + boost::hash_detail::enable_hash_value {}; #endif - + #if !defined(BOOST_NO_LONG_LONG) - std::size_t hash_value(boost::long_long_type); - std::size_t hash_value(boost::ulong_long_type); + template <> struct long_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct ulong_numbers : + boost::hash_detail::enable_hash_value {}; #endif + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + template <> struct float_numbers : + boost::hash_detail::enable_hash_value {}; + } + + template + typename boost::hash_detail::basic_numbers::type hash_value(T); + template + typename boost::hash_detail::long_numbers::type hash_value(T); + template + typename boost::hash_detail::ulong_numbers::type hash_value(T); + #if !BOOST_WORKAROUND(__DMC__, <= 0x848) template std::size_t hash_value(T* const&); #else @@ -83,14 +104,13 @@ namespace boost std::size_t hash_value(T (&x)[N]); #endif - std::size_t hash_value(float v); - std::size_t hash_value(double v); - std::size_t hash_value(long double v); - template std::size_t hash_value( std::basic_string, A> const&); + template + typename boost::hash_detail::float_numbers::type hash_value(T); + #if !defined(BOOST_NO_0X_HDR_TYPEINDEX) std::size_t hash_value(std::type_index); #endif @@ -141,74 +161,23 @@ namespace boost } } - inline std::size_t hash_value(bool v) + template + typename boost::hash_detail::basic_numbers::type hash_value(T v) { return static_cast(v); } - inline std::size_t hash_value(char v) - { - return static_cast(v); - } - - inline std::size_t hash_value(unsigned char v) - { - return static_cast(v); - } - - inline std::size_t hash_value(signed char v) - { - return static_cast(v); - } - - inline std::size_t hash_value(short v) - { - return static_cast(v); - } - - inline std::size_t hash_value(unsigned short v) - { - return static_cast(v); - } - - inline std::size_t hash_value(int v) - { - return static_cast(v); - } - - inline std::size_t hash_value(unsigned int v) - { - return static_cast(v); - } - - inline std::size_t hash_value(long v) - { - return static_cast(v); - } - - inline std::size_t hash_value(unsigned long v) - { - return static_cast(v); - } - -#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) - inline std::size_t hash_value(wchar_t v) - { - return static_cast(v); - } -#endif - -#if !defined(BOOST_NO_LONG_LONG) - inline std::size_t hash_value(boost::long_long_type v) + template + typename boost::hash_detail::long_numbers::type hash_value(T v) { return hash_detail::hash_value_signed(v); } - inline std::size_t hash_value(boost::ulong_long_type v) + template + typename boost::hash_detail::ulong_numbers::type hash_value(T v) { return hash_detail::hash_value_unsigned(v); } -#endif // Implementation by Alberto Barbati and Dave Harris. #if !BOOST_WORKAROUND(__DMC__, <= 0x848) @@ -324,17 +293,8 @@ namespace boost return hash_range(v.begin(), v.end()); } - inline std::size_t hash_value(float v) - { - return boost::hash_detail::float_hash_value(v); - } - - inline std::size_t hash_value(double v) - { - return boost::hash_detail::float_hash_value(v); - } - - inline std::size_t hash_value(long double v) + template + typename boost::hash_detail::float_numbers::type hash_value(T v) { return boost::hash_detail::float_hash_value(v); }