diff --git a/include/boost/functional/detail/float_functions.hpp b/include/boost/functional/detail/float_functions.hpp index 9de3186..3b6ee85 100644 --- a/include/boost/functional/detail/float_functions.hpp +++ b/include/boost/functional/detail/float_functions.hpp @@ -6,6 +6,8 @@ #if !defined(BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP) #define BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP +#include + #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/functional/detail/hash_float.hpp b/include/boost/functional/detail/hash_float.hpp new file mode 100644 index 0000000..56e1464 --- /dev/null +++ b/include/boost/functional/detail/hash_float.hpp @@ -0,0 +1,54 @@ + +// (C) Copyright Daniel James 2005. +// Use, modification and distribution are subject to 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) +// +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER) +#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +namespace boost +{ + namespace hash_detail + { + template + inline std::size_t float_hash_value(T v) + { + int exp = 0; + errno = 0; + v = boost::hash_detail::call_frexp(v, &exp); + if(errno) return 0; + + std::size_t seed = 0; + + std::size_t const length + = (std::numeric_limits::digits + + std::numeric_limits::digits - 1) + / std::numeric_limits::digits; + + for(std::size_t i = 0; i < length; ++i) + { + v = boost::hash_detail::call_ldexp(v, std::numeric_limits::digits); + int const part = static_cast(v); + v -= part; + boost::hash_combine(seed, part); + } + + boost::hash_combine(seed, exp); + + return seed; + } + } +} + +#endif diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 9103095..621da84 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -16,11 +16,10 @@ #endif #include -#include #include #include #include -#include +#include #include #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) @@ -244,37 +243,6 @@ namespace boost return hash_range(v.begin(), v.end()); } - namespace hash_detail - { - template - inline std::size_t float_hash_value(T v) - { - int exp = 0; - errno = 0; - v = boost::hash_detail::call_frexp(v, &exp); - if(errno) return 0; - - std::size_t seed = 0; - - std::size_t const length - = (std::numeric_limits::digits + - std::numeric_limits::digits - 1) - / std::numeric_limits::digits; - - for(std::size_t i = 0; i < length; ++i) - { - v = boost::hash_detail::call_ldexp(v, std::numeric_limits::digits); - int const part = static_cast(v); - v -= part; - boost::hash_combine(seed, part); - } - - boost::hash_combine(seed, exp); - - return seed; - } - } - inline std::size_t hash_value(float v) { return boost::hash_detail::float_hash_value(v);