~tsarev/boostdc/cmake

« back to all changes in this revision

Viewing changes to boost/boost/functional/hash/detail/hash_float_generic.hpp

  • Committer: bigmuscle
  • Date: 2010-05-08 08:47:15 UTC
  • Revision ID: svn-v4:5fb55d53-692c-0410-a46a-e90ab66e00ee:trunk:497
removed old boost version

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
// Copyright 2005-2009 Daniel James.
3
 
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4
 
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
 
 
6
 
// A general purpose hash function for non-zero floating point values.
7
 
 
8
 
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
9
 
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
10
 
 
11
 
#include <boost/functional/hash/detail/float_functions.hpp>
12
 
#include <boost/integer/static_log2.hpp>
13
 
#include <boost/functional/hash/detail/limits.hpp>
14
 
 
15
 
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
16
 
# pragma once
17
 
#endif
18
 
 
19
 
#if defined(BOOST_MSVC)
20
 
#pragma warning(push)
21
 
#if BOOST_MSVC >= 1400
22
 
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
23
 
                              // not satisfy test. Loop body not executed 
24
 
#endif
25
 
#endif
26
 
 
27
 
namespace boost
28
 
{
29
 
    namespace hash_detail
30
 
    {
31
 
        inline void hash_float_combine(std::size_t& seed, std::size_t value)
32
 
        {
33
 
            seed ^= value + (seed<<6) + (seed>>2);
34
 
        }
35
 
 
36
 
        template <class T>
37
 
        inline std::size_t float_hash_impl2(T v)
38
 
        {
39
 
            boost::hash_detail::call_frexp<T> frexp;
40
 
            boost::hash_detail::call_ldexp<T> ldexp;
41
 
        
42
 
            int exp = 0;
43
 
 
44
 
            v = frexp(v, &exp);
45
 
 
46
 
            // A postive value is easier to hash, so combine the
47
 
            // sign with the exponent and use the absolute value.
48
 
            if(v < 0) {
49
 
                v = -v;
50
 
                exp += limits<T>::max_exponent -
51
 
                    limits<T>::min_exponent;
52
 
            }
53
 
 
54
 
            // The result of frexp is always between 0.5 and 1, so its
55
 
            // top bit will always be 1. Subtract by 0.5 to remove that.
56
 
            v -= T(0.5);
57
 
            v = ldexp(v, limits<std::size_t>::digits + 1);
58
 
            std::size_t seed = static_cast<std::size_t>(v);
59
 
            v -= seed;
60
 
 
61
 
            // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
62
 
            std::size_t const length
63
 
                = (limits<T>::digits *
64
 
                        boost::static_log2<limits<T>::radix>::value - 1)
65
 
                / limits<std::size_t>::digits;
66
 
 
67
 
            for(std::size_t i = 0; i != length; ++i)
68
 
            {
69
 
                v = ldexp(v, limits<std::size_t>::digits);
70
 
                std::size_t part = static_cast<std::size_t>(v);
71
 
                v -= part;
72
 
                hash_float_combine(seed, part);
73
 
            }
74
 
 
75
 
            hash_float_combine(seed, exp);
76
 
 
77
 
            return seed;
78
 
        }
79
 
 
80
 
        template <class T>
81
 
        inline std::size_t float_hash_impl(T v)
82
 
        {
83
 
            typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
84
 
            return float_hash_impl2(static_cast<type>(v));
85
 
        }
86
 
    }
87
 
}
88
 
 
89
 
#if defined(BOOST_MSVC)
90
 
#pragma warning(pop)
91
 
#endif
92
 
 
93
 
#endif