Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/functional/detail/hash_float.hpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.6 KB
Line 
1
2//  Copyright Daniel James 2005-2006. Use, modification, and distribution are
3//  subject to 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//  Based on Peter Dimov's proposal
7//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
8//  issue 6.18.
9
10#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER)
11#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER
12
13#if defined(_MSC_VER) && (_MSC_VER >= 1020)
14# pragma once
15#endif
16
17#include <boost/functional/detail/float_functions.hpp>
18#include <boost/limits.hpp>
19#include <boost/assert.hpp>
20#include <errno.h>
21
22// Don't use fpclassify or _fpclass for stlport.
23#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
24#  if defined(__GLIBCPP__) || defined(__GLIBCXX__)
25// GNU libstdc++ 3
26#    if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
27        !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
28#      define BOOST_HASH_USE_FPCLASSIFY
29#    endif
30#  elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
31// Dinkumware Library, on Visual C++
32#    if defined(BOOST_MSVC)
33#      define BOOST_HASH_USE_FPCLASS
34#    endif
35#  endif
36#endif
37
38namespace boost
39{
40    namespace hash_detail
41    {
42        inline void hash_float_combine(std::size_t& seed, std::size_t value)
43        {
44            seed ^= value + (seed<<6) + (seed>>2);
45        }
46
47        template <class T>
48        inline std::size_t float_hash_impl(T v)
49        {
50            int exp = 0;
51            errno = 0;
52            v = boost::hash_detail::call_frexp(v, &exp);
53            if(errno) return 0;
54
55            std::size_t seed = 0;
56
57            std::size_t const length
58                = (std::numeric_limits<T>::digits +
59                        std::numeric_limits<int>::digits - 1)
60                / std::numeric_limits<int>::digits;
61
62            for(std::size_t i = 0; i < length; ++i)
63            {
64                v = boost::hash_detail::call_ldexp(v, std::numeric_limits<int>::digits);
65                int const part = static_cast<int>(v);
66                v -= part;
67                hash_float_combine(seed, part);
68            }
69
70            hash_float_combine(seed, exp);
71
72            return seed;
73        }
74
75        template <class T>
76        inline std::size_t float_hash_value(T v)
77        {
78#if defined(BOOST_HASH_USE_FPCLASSIFY)
79            using namespace std;
80            switch (fpclassify(v)) {
81            case FP_ZERO:
82                return 0;
83            case FP_INFINITE:
84                return (std::size_t)(v > 0 ? -1 : -2);
85            case FP_NAN:
86                return (std::size_t)(-3);
87            case FP_NORMAL:
88            case FP_SUBNORMAL:
89                return float_hash_impl(v);
90            default:
91                BOOST_ASSERT(0);
92                return 0;
93            }
94#elif defined(BOOST_HASH_USE_FPCLASS)
95            switch(_fpclass(v)) {
96            case _FPCLASS_NZ:
97            case _FPCLASS_PZ:
98                return 0;
99            case _FPCLASS_PINF:
100                return (std::size_t)(-1);
101            case _FPCLASS_NINF:
102                return (std::size_t)(-2);
103            case _FPCLASS_SNAN:
104            case _FPCLASS_QNAN:
105                return (std::size_t)(-3);
106            case _FPCLASS_NN:
107            case _FPCLASS_ND:
108                return float_hash_impl(v);
109            case _FPCLASS_PD:
110            case _FPCLASS_PN:
111                return float_hash_impl(v);
112            default:
113                BOOST_ASSERT(0);
114                return 0;
115            }
116#else
117            return float_hash_impl(v);
118#endif
119        }
120    }
121}
122
123#endif
Note: See TracBrowser for help on using the repository browser.