Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81677 - in trunk: boost/functional/hash/detail libs/functional/hash/doc
From: dnljms_at_[hidden]
Date: 2012-12-02 16:11:46


Author: danieljames
Date: 2012-12-02 16:11:45 EST (Sun, 02 Dec 2012)
New Revision: 81677
URL: http://svn.boost.org/trac/boost/changeset/81677

Log:
Hash: Don't use workarounds with recent compilers. #7221, #7470
Text files modified:
   trunk/boost/functional/hash/detail/float_functions.hpp | 90 ++++++++++++++++++++++++++++++++++++++++
   trunk/boost/functional/hash/detail/hash_float.hpp | 9 +++
   trunk/libs/functional/hash/doc/changes.qbk | 3 +
   3 files changed, 101 insertions(+), 1 deletions(-)

Modified: trunk/boost/functional/hash/detail/float_functions.hpp
==============================================================================
--- trunk/boost/functional/hash/detail/float_functions.hpp (original)
+++ trunk/boost/functional/hash/detail/float_functions.hpp 2012-12-02 16:11:45 EST (Sun, 02 Dec 2012)
@@ -13,6 +13,94 @@
 # pragma once
 #endif
 
+// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
+// sufficiently good floating point support to not require any
+// workarounds.
+//
+// When set to 0, the library tries to automatically
+// use the best available implementation. This normally works well, but
+// breaks when ambiguities are created by odd namespacing of the functions.
+//
+// Note that if this is set to 0, the library should still take full
+// advantage of the platform's floating point support.
+
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__LIBCOMO__)
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+// Rogue Wave library:
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(_LIBCPP_VERSION)
+// libc++
+# define BOOST_HASH_CONFORMANT_FLOATS 1
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+// GNU libstdc++ 3
+# if defined(__GNUC__) && __GNUC__ >= 4
+# define BOOST_HASH_CONFORMANT_FLOATS 1
+# else
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+# endif
+#elif defined(__STL_CONFIG_H)
+// generic SGI STL
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__MSL_CPP__)
+// MSL standard lib:
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif defined(__IBMCPP__)
+// VACPP std lib (probably conformant for much earlier version).
+# if __IBMCPP__ >= 1210
+# define BOOST_HASH_CONFORMANT_FLOATS 1
+# else
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+# endif
+#elif defined(MSIPL_COMPILE_H)
+// Modena C++ standard library
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
+// Dinkumware Library (this has to appear after any possible replacement libraries):
+# if _CPPLIB_VER >= 405
+# define BOOST_HASH_CONFORMANT_FLOATS 1
+# else
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+# endif
+#else
+# define BOOST_HASH_CONFORMANT_FLOATS 0
+#endif
+
+#if BOOST_HASH_CONFORMANT_FLOATS
+
+// The standard library is known to be compliant, so don't use the
+// configuration mechanism.
+
+namespace boost {
+ namespace hash_detail {
+ template <typename Float>
+ struct call_ldexp {
+ typedef Float float_type;
+ inline Float operator()(Float x, int y) const {
+ return std::ldexp(x, y);
+ }
+ };
+
+ template <typename Float>
+ struct call_frexp {
+ typedef Float float_type;
+ inline Float operator()(Float x, int* y) const {
+ return std::frexp(x, y);
+ }
+ };
+
+ template <typename Float>
+ struct select_hash_type
+ {
+ typedef Float type;
+ };
+ }
+}
+
+#else // BOOST_HASH_CONFORMANT_FLOATS == 0
+
 // 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
@@ -243,4 +331,6 @@
     }
 }
 
+#endif // BOOST_HASH_CONFORMANT_FLOATS
+
 #endif

Modified: trunk/boost/functional/hash/detail/hash_float.hpp
==============================================================================
--- trunk/boost/functional/hash/detail/hash_float.hpp (original)
+++ trunk/boost/functional/hash/detail/hash_float.hpp 2012-12-02 16:11:45 EST (Sun, 02 Dec 2012)
@@ -210,8 +210,15 @@
         template <class T>
         inline std::size_t float_hash_value(T v)
         {
+#if defined(fpclassify)
+ switch (fpclassify(v))
+#elif BOOST_HASH_CONFORMANT_FLOATS
+ switch (std::fpclassify(v))
+#else
             using namespace std;
- switch (fpclassify(v)) {
+ switch (fpclassify(v))
+#endif
+ {
             case FP_ZERO:
                 return 0;
             case FP_INFINITE:

Modified: trunk/libs/functional/hash/doc/changes.qbk
==============================================================================
--- trunk/libs/functional/hash/doc/changes.qbk (original)
+++ trunk/libs/functional/hash/doc/changes.qbk 2012-12-02 16:11:45 EST (Sun, 02 Dec 2012)
@@ -144,5 +144,8 @@
 * Restore `enum` support, which was accidentally removed in the last version.
 * New floating point hasher - will hash the binary representation on more
   platforms, which should be faster.
+* On platforms that are known to have standard floating point, don't use the
+ automatic detection of floating point functions - which can break if there
+ are ambiguous overloads.
 
 [endsect]


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