Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r78391 - in trunk: boost/functional/hash libs/functional/hash/test
From: dnljms_at_[hidden]
Date: 2012-05-08 18:24:48


Author: danieljames
Date: 2012-05-08 18:24:46 EDT (Tue, 08 May 2012)
New Revision: 78391
URL: http://svn.boost.org/trac/boost/changeset/78391

Log:
Hash: Use SFINAE to avoid implicit casts to numbers.
Added:
   trunk/libs/functional/hash/test/implicit_test.cpp (contents, props changed)
      - copied, changed from r78390, /trunk/libs/functional/hash/test/implicit_fail_test.cpp
Removed:
   trunk/libs/functional/hash/test/implicit_fail_test.cpp
Text files modified:
   trunk/boost/functional/hash/hash.hpp | 162 +++++++++++++++------------------------
   trunk/libs/functional/hash/test/Jamfile.v2 | 76 +++++++-----------
   2 files changed, 92 insertions(+), 146 deletions(-)

Modified: trunk/boost/functional/hash/hash.hpp
==============================================================================
--- trunk/boost/functional/hash/hash.hpp (original)
+++ trunk/boost/functional/hash/hash.hpp 2012-05-08 18:24:46 EDT (Tue, 08 May 2012)
@@ -16,10 +16,6 @@
 #include <string>
 #include <boost/limits.hpp>
 
-#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
-#include <boost/static_assert.hpp>
-#endif
-
 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 #include <boost/type_traits/is_pointer.hpp>
 #endif
@@ -37,38 +33,63 @@
 
 namespace boost
 {
-#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
-
- // If you get a static assertion here, it's because hash_value
- // isn't declared for your type.
- template <typename T>
- std::size_t hash_value(T const&) {
- BOOST_STATIC_ASSERT((T*) 0 && false);
- return 0;
- }
-
-#endif
+ namespace hash_detail
+ {
+ struct enable_hash_value { typedef std::size_t type; };
 
- 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 <typename T> struct basic_numbers {};
+ template <typename T> struct long_numbers {};
+ template <typename T> struct ulong_numbers {};
+ template <typename T> struct float_numbers {};
+
+ template <> struct basic_numbers<bool> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<signed char> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<short> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned short> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<int> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned int> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<long> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct basic_numbers<unsigned long> :
+ boost::hash_detail::enable_hash_value {};
 
 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- std::size_t hash_value(wchar_t);
+ template <> struct basic_numbers<wchar_t> :
+ 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::long_long_type> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct ulong_numbers<boost::ulong_long_type> :
+ boost::hash_detail::enable_hash_value {};
 #endif
 
+ template <> struct float_numbers<float> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct float_numbers<double> :
+ boost::hash_detail::enable_hash_value {};
+ template <> struct float_numbers<long double> :
+ boost::hash_detail::enable_hash_value {};
+ }
+
+ template <typename T>
+ typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
+ template <typename T>
+ typename boost::hash_detail::long_numbers<T>::type hash_value(T);
+ template <typename T>
+ typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
+
 #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
     template <class T> std::size_t hash_value(T* const&);
 #else
@@ -83,14 +104,13 @@
     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 <class Ch, class A>
     std::size_t hash_value(
         std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
 
+ template <typename T>
+ typename boost::hash_detail::float_numbers<T>::type hash_value(T);
+
 #if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
     std::size_t hash_value(std::type_index);
 #endif
@@ -141,74 +161,23 @@
         }
     }
 
- inline std::size_t hash_value(bool v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(signed char v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(short v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned short v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(int v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned int v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(long v)
- {
- return static_cast<std::size_t>(v);
- }
-
- inline std::size_t hash_value(unsigned long v)
- {
- return static_cast<std::size_t>(v);
- }
-
-#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
- inline std::size_t hash_value(wchar_t v)
+ template <typename T>
+ typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
     {
         return static_cast<std::size_t>(v);
     }
-#endif
 
-#if !defined(BOOST_NO_LONG_LONG)
- inline std::size_t hash_value(boost::long_long_type v)
+ template <typename T>
+ typename boost::hash_detail::long_numbers<T>::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 T>
+ typename boost::hash_detail::ulong_numbers<T>::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 @@
         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 T>
+ typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
     {
         return boost::hash_detail::float_hash_value(v);
     }

Modified: trunk/libs/functional/hash/test/Jamfile.v2
==============================================================================
--- trunk/libs/functional/hash/test/Jamfile.v2 (original)
+++ trunk/libs/functional/hash/test/Jamfile.v2 2012-05-08 18:24:46 EDT (Tue, 08 May 2012)
@@ -19,51 +19,37 @@
 
 test-suite functional/hash
     :
- [ run hash_fwd_test_1.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_fwd_test_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_range_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_custom_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_global_namespace_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_friend_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_built_in_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_value_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_vector_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_list_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_deque_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_set_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_map_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_complex_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_type_index_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_std_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_std_tuple_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run link_ext_test.cpp link_no_ext_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run extensions_hpp_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ compile-fail hash_no_ext_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ compile-fail namespace_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ compile-fail implicit_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_no_ext_macro_1.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- [ run hash_no_ext_macro_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
- ;
-
-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 ]
+ [ 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 ]
     ;
 
 test-suite functional/hash_no_ext

Deleted: trunk/libs/functional/hash/test/implicit_fail_test.cpp
==============================================================================
--- trunk/libs/functional/hash/test/implicit_fail_test.cpp 2012-05-08 18:24:46 EDT (Tue, 08 May 2012)
+++ (empty file)
@@ -1,21 +0,0 @@
-
-// Copyright 2010 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 <boost/functional/hash.hpp>
-
-namespace test
-{
- struct base {};
- std::size_t hash_value(base const&) { return 0; }
-
- struct converts { operator base() const { return base(); } };
-}
-
-int main() {
- boost::hash<test::converts> hash;
- test::converts x;
-
- hash(x);
-}

Copied: trunk/libs/functional/hash/test/implicit_test.cpp (from r78390, /trunk/libs/functional/hash/test/implicit_fail_test.cpp)
==============================================================================


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk