$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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]