summaryrefslogtreecommitdiffstats
blob: 69cf91a1515fe16b3d515f8db3a104124f0e0ba6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

// Copyright 2005-2009 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)

#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP

#include <boost/config/no_tr1/cmath.hpp>

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// Some of this is based on guess work. If I don't know any better I assume that
// the standard C++ overloaded functions are available. If they're not then this
// means that the argument is cast to a double and back, which is inefficient
// and will give pretty bad results for long doubles - so if you know better
// let me know.

// STLport:
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#  if (defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))) || defined(__DMC__)
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#  elif defined(BOOST_MSVC) && BOOST_MSVC < 1300
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#  else
#    define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#  endif

// Roguewave:
//
// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't
// defined, but for the same version of roguewave on sunpro they are.
#elif defined(_RWSTD_VER)
#  if defined(__BORLANDC__)
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#    define BOOST_HASH_C99_NO_FLOAT_FUNCS
#  elif defined(__DECCXX)
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#  else
#    define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#  endif

// libstdc++ (gcc 3.0 onwards, I think)
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
#  define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS

// SGI:
#elif defined(__STL_CONFIG_H)
#  if defined(linux) || defined(__linux) || defined(__linux__)
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#  else
#    define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#  endif

// vxWorks. It has its own math library, but uses Dinkumware STL
#elif defined(__VXWORKS__)
#  define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS

// Dinkumware.
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Some versions of Visual C++ don't seem to have the C++ overloads but they
// all seem to have the c99 float overloads
#  if defined(BOOST_MSVC)
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
// On other platforms the C++ overloads seem to have been introduced sometime
// before 402.
#  elif defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402)
#    define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#  else
#    define BOOST_HASH_USE_C99_FLOAT_FUNCS
#  endif

// Digital Mars
#elif defined(__DMC__)
#  define BOOST_HASH_USE_C99_FLOAT_FUNCS

// Use overloaded float functions by default.
#else
#  define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#endif

namespace boost
{
    namespace hash_detail
    {

        inline float call_ldexp(float v, int exp)
        {
            using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
    defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
            return ldexp(v, exp);
#else
            return ldexpf(v, exp);
#endif
        }

        inline double call_ldexp(double v, int exp)
        {
            using namespace std;
            return ldexp(v, exp);
        }

        inline long double call_ldexp(long double v, int exp)
        {
            using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
            return ldexp(v, exp);
#else
            return ldexpl(v, exp);
#endif
        }

        inline float call_frexp(float v, int* exp)
        {
            using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
    defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
            return frexp(v, exp);
#else
            return frexpf(v, exp);
#endif
        }

        inline double call_frexp(double v, int* exp)
        {
            using namespace std;
            return frexp(v, exp);
        }

        inline long double call_frexp(long double v, int* exp)
        {
            using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
            return frexp(v, exp);
#else
            return frexpl(v, exp);
#endif
        }
    }
}

#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS)
#undef BOOST_HASH_USE_C99_FLOAT_FUNCS
#endif

#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#endif

#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
#undef BOOST_HASH_C99_NO_FLOAT_FUNCS
#endif

#endif