Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53361 - in branches/release: . boost/functional/hash boost/functional/hash/detail libs/functional/hash/doc libs/functional/hash/test
From: daniel_james_at_[hidden]
Date: 2009-05-28 16:42:57


Author: danieljames
Date: 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
New Revision: 53361
URL: http://svn.boost.org/trac/boost/changeset/53361

Log:
Automatically detect what float functions the compiler/library supports
in hash and seperate out some of the detail headers.

Merged revisions 53159-53161,53167-53169,53175,53185,53205,53247-53248,53254 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r53159 | danieljames | 2009-05-21 22:21:11 +0100 (Thu, 21 May 2009) | 1 line
  
  Move the hash limits workaround into its own file.
........
  r53160 | danieljames | 2009-05-21 22:21:44 +0100 (Thu, 21 May 2009) | 1 line
  
  Move the two different hash float implementation into their own header.
........
  r53161 | danieljames | 2009-05-21 22:22:04 +0100 (Thu, 21 May 2009) | 1 line
  
  Try to automatically detect which float functions are available.
........
  r53167 | danieljames | 2009-05-22 07:00:56 +0100 (Fri, 22 May 2009) | 1 line
  
  Fix a typo.
........
  r53168 | danieljames | 2009-05-22 07:01:19 +0100 (Fri, 22 May 2009) | 3 lines
  
  Spell out exactly which functions can be used with which types.
  
  I was hitting some ambiguity errors when the function was for the wrong type.
........
  r53169 | danieljames | 2009-05-22 07:01:35 +0100 (Fri, 22 May 2009) | 1 line
  
  Some STLport fixes for hash.
........
  r53175 | danieljames | 2009-05-22 14:35:56 +0100 (Fri, 22 May 2009) | 2 lines
  
  Rename struct to avoid using 'type::'type' which confuses some
  compilers.
........
  r53185 | danieljames | 2009-05-22 20:00:35 +0100 (Fri, 22 May 2009) | 1 line
  
  Explicitly qualify 'none' to avoid confusion with boost::none.
........
  r53205 | danieljames | 2009-05-23 16:21:38 +0100 (Sat, 23 May 2009) | 4 lines
  
  Try to deal with macros for frexpl and ldexpl.
  
  The error message for msvc-9.0~wm5~stlport5.2 suggests that frexpl and ldexpl
  are macros.
........
  r53247 | danieljames | 2009-05-25 14:45:16 +0100 (Mon, 25 May 2009) | 4 lines
  
  Check for float functions with less templates.
  
  The only template mechanism now used is full specialization, so this should
  hopefully be more portable to compilers we don't test.
........
  r53248 | danieljames | 2009-05-25 15:27:00 +0100 (Mon, 25 May 2009) | 1 line
  
  Fix a couple of clumsy errors in the last commit.
........
  r53254 | danieljames | 2009-05-25 20:44:52 +0100 (Mon, 25 May 2009) | 1 line
  
  Hash change log.
........

Added:
   branches/release/boost/functional/hash/detail/hash_float_generic.hpp
      - copied unchanged from r53169, /trunk/boost/functional/hash/detail/hash_float_generic.hpp
   branches/release/boost/functional/hash/detail/hash_float_x86.hpp
      - copied unchanged from r53169, /trunk/boost/functional/hash/detail/hash_float_x86.hpp
   branches/release/boost/functional/hash/detail/limits.hpp
      - copied, changed from r53169, /trunk/boost/functional/hash/detail/limits.hpp
Properties modified:
   branches/release/ (props changed)
Text files modified:
   branches/release/boost/functional/hash/detail/float_functions.hpp | 320 ++++++++++++++++++++++++---------------
   branches/release/boost/functional/hash/detail/hash_float.hpp | 162 ++++---------------
   branches/release/boost/functional/hash/detail/limits.hpp | 2
   branches/release/boost/functional/hash/hash.hpp | 1
   branches/release/libs/functional/hash/doc/changes.qbk | 6
   branches/release/libs/functional/hash/test/hash_float_test.hpp | 23 ++
   branches/release/libs/functional/hash/test/hash_function_pointer_test.cpp | 1
   branches/release/libs/functional/hash/test/hash_number_test.cpp | 2
   branches/release/libs/functional/hash/test/hash_string_test.cpp | 1
   9 files changed, 266 insertions(+), 252 deletions(-)

Modified: branches/release/boost/functional/hash/detail/float_functions.hpp
==============================================================================
--- branches/release/boost/functional/hash/detail/float_functions.hpp (original)
+++ branches/release/boost/functional/hash/detail/float_functions.hpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -6,6 +6,7 @@
 #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
 #define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
 
+#include <boost/config.hpp>
 #include <boost/config/no_tr1/cmath.hpp>
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -17,146 +18,221 @@
 // 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
+// The following tries to automatically detect which are available.
 
-// Roguewave:
+namespace boost {
+ namespace hash_detail {
+
+ // Returned by dummy versions of the float functions.
+
+ struct not_found {
+ // Implicitly convertible to float and long double in order to avoid
+ // a compile error when the dummy float functions are used.
+
+ inline operator float() const { return 0; }
+ inline operator long double() const { return 0; }
+ };
+
+ // A type for detecting the return type of functions.
+
+ template <typename T> struct is;
+ template <> struct is<float> { char x[10]; };
+ template <> struct is<double> { char x[20]; };
+ template <> struct is<long double> { char x[30]; };
+ template <> struct is<boost::hash_detail::not_found> { char x[40]; };
+
+ // Used to convert the return type of a function to a type for sizeof.
+
+ template <typename T> is<T> float_type(T);
+
+ // call_ldexp
+ //
+ // This will get specialized for float and long double
+
+ template <typename Float> struct call_ldexp
+ {
+ typedef double float_type;
+
+ inline double operator()(double a, int b) const
+ {
+ using namespace std;
+ return ldexp(a, b);
+ }
+ };
+
+ // call_frexp
+ //
+ // This will get specialized for float and long double
+
+ template <typename Float> struct call_frexp
+ {
+ typedef double float_type;
+
+ inline double operator()(double a, int* b) const
+ {
+ using namespace std;
+ return frexp(a, b);
+ }
+ };
+ }
+}
+
+// A namespace for dummy functions to detect when the actual function we want
+// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
 //
-// 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
+// AFAICT these have to be outside of the boost namespace, as if they're in
+// the boost namespace they'll always be preferable to any other function
+// (since the arguments are built in types, ADL can't be used).
+
+namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
+ template <class Float> boost::hash_detail::not_found ldexp(Float, int);
+ template <class Float> boost::hash_detail::not_found frexp(Float, int*);
+}
 
-// Use overloaded float functions by default.
-#else
-# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
-#endif
+// Macros for generating specializations of call_ldexp and call_frexp.
+//
+// check_cpp and check_c99 check if the C++ or C99 functions are available.
+//
+// Then the call_* functions select an appropriate implementation.
+//
+// I used c99_func in a few places just to get a unique name.
 
-namespace boost
-{
- namespace hash_detail
- {
+#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
+namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \
+ boost::hash_detail::not_found c99_func(int, type2); \
+} \
+ \
+namespace boost { \
+ namespace hash_detail { \
+ namespace c99_func##_detect { \
+ using namespace std; \
+ using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \
+ \
+ struct check { \
+ static type1 x; \
+ static type2 y; \
+ BOOST_STATIC_CONSTANT(bool, cpp = \
+ sizeof(float_type(cpp_func(x,y))) \
+ == sizeof(is<type1>)); \
+ BOOST_STATIC_CONSTANT(bool, c99 = \
+ sizeof(float_type(c99_func(x,y))) \
+ == sizeof(is<type1>)); \
+ }; \
+ \
+ template <bool x> \
+ struct call_c99 : \
+ boost::hash_detail::call_##cpp_func<double> {}; \
+ \
+ template <> \
+ struct call_c99<true> { \
+ typedef type1 float_type; \
+ \
+ template <typename T> \
+ inline type1 operator()(type1 a, T b) const \
+ { \
+ return c99_func(a, b); \
+ } \
+ }; \
+ \
+ template <bool x> \
+ struct call_cpp : \
+ call_c99< \
+ ::boost::hash_detail::c99_func##_detect::check::c99 \
+ > {}; \
+ \
+ template <> \
+ struct call_cpp<true> { \
+ typedef type1 float_type; \
+ \
+ template <typename T> \
+ inline type1 operator()(type1 a, T b) const \
+ { \
+ return cpp_func(a, b); \
+ } \
+ }; \
+ } \
+ \
+ template <> \
+ struct call_##cpp_func<type1> : \
+ c99_func##_detect::call_cpp< \
+ ::boost::hash_detail::c99_func##_detect::check::cpp \
+ > {}; \
+ } \
+}
 
- 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);
+#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
+namespace boost { \
+ namespace hash_detail { \
+ \
+ template <> \
+ struct call_##cpp_func<type1> { \
+ typedef type1 float_type; \
+ inline type1 operator()(type1 x, type2 y) const { \
+ return c99_func(x, y); \
+ } \
+ }; \
+ } \
+}
+
+#if defined(ldexpf)
+BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
 #else
- return ldexpf(v, exp);
+BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
 #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);
+#if defined(ldexpl)
+BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
 #else
- return ldexpl(v, exp);
+BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
 #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);
+#if defined(frexpf)
+BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
 #else
- return frexpf(v, exp);
+BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
 #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);
+#if defined(frexpl)
+BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
 #else
- return frexpl(v, exp);
+BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
 #endif
- }
- }
-}
 
-#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS)
-#undef BOOST_HASH_USE_C99_FLOAT_FUNCS
-#endif
+#undef BOOST_HASH_CALL_FLOAT_MACRO
+#undef BOOST_HASH_CALL_FLOAT_FUNC
 
-#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
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <typename Float1, typename Float2>
+ struct select_hash_type_impl {
+ typedef double type;
+ };
+
+ template <>
+ struct select_hash_type_impl<float, float> {
+ typedef float type;
+ };
+
+ template <>
+ struct select_hash_type_impl<long double, long double> {
+ typedef long double type;
+ };
+
+
+ // select_hash_type
+ //
+ // If there is support for a particular floating point type, use that
+ // otherwise use double (there's always support for double).
+
+ template <typename Float>
+ struct select_hash_type : select_hash_type_impl<
+ BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
+ BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
+ > {};
+ }
+}
 
 #endif

Modified: branches/release/boost/functional/hash/detail/hash_float.hpp
==============================================================================
--- branches/release/boost/functional/hash/detail/hash_float.hpp (original)
+++ branches/release/boost/functional/hash/detail/hash_float.hpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -18,156 +18,57 @@
 #endif
 #endif
 
+#include <boost/config.hpp>
 #include <boost/functional/hash/detail/float_functions.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
 #include <boost/integer/static_log2.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/limits.hpp>
 #include <boost/assert.hpp>
 
-// Select implementation for the current platform.
+// Include hash implementation for the current platform.
 
 // Cygwn
 #if defined(__CYGWIN__)
 # if defined(__i386__) || defined(_M_IX86)
-# define BOOST_HASH_USE_x86_BINARY_HASH
+# include <boost/functional/hash/detail/hash_float_x86.hpp>
+# else
+# include <boost/functional/hash/detail/hash_float_generic.hpp>
 # endif
+#else
+# include <boost/functional/hash/detail/hash_float_generic.hpp>
+#endif
+
+// Can we use fpclassify?
 
 // STLport
-#elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
-// fpclassify aren't good enough on STLport.
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+#define BOOST_HASH_USE_FPCLASSIFY 0
 
 // GNU libstdc++ 3
 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
 # if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
       !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
-# define BOOST_HASH_USE_FPCLASSIFY
+# define BOOST_HASH_USE_FPCLASSIFY 1
+# else
+# define BOOST_HASH_USE_FPCLASSIFY 0
 # endif
 
-// Dinkumware Library, on Visual C++
-#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
-
-// Not using _fpclass because it is only available for double.
-
+// Everything else
+#else
+# define BOOST_HASH_USE_FPCLASSIFY 0
 #endif
 
-// On OpenBSD, numeric_limits is not reliable for long doubles, but
-// the macros defined in <float.h> are.
+#if BOOST_HASH_USE_FPCLASSIFY
 
-#if defined(__OpenBSD__)
-#include <float.h>
-#endif
+#include <boost/config/no_tr1/cmath.hpp>
 
 namespace boost
 {
     namespace hash_detail
     {
         template <class T>
- struct limits : std::numeric_limits<T> {};
-
-#if defined(__OpenBSD__)
- template <>
- struct limits<long double>
- : std::numeric_limits<long double>
- {
- static long double epsilon() {
- return LDBL_EPSILON;
- }
-
- static long double (max)() {
- return LDBL_MAX;
- }
-
- static long double (min)() {
- return LDBL_MIN;
- }
-
- BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
- BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
- BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
- };
-#endif // __OpenBSD__
-
- inline void hash_float_combine(std::size_t& seed, std::size_t value)
- {
- seed ^= value + (seed<<6) + (seed>>2);
- }
-
-// A simple, non-portable hash algorithm for x86.
-#if defined(BOOST_HASH_USE_x86_BINARY_HASH)
- inline std::size_t float_hash_impl(float v)
- {
- boost::uint32_t* ptr = (boost::uint32_t*)&v;
- std::size_t seed = *ptr;
- return seed;
- }
-
- inline std::size_t float_hash_impl(double v)
- {
- boost::uint32_t* ptr = (boost::uint32_t*)&v;
- std::size_t seed = *ptr++;
- hash_float_combine(seed, *ptr);
- return seed;
- }
-
- inline std::size_t float_hash_impl(long double v)
- {
- boost::uint32_t* ptr = (boost::uint32_t*)&v;
- std::size_t seed = *ptr++;
- hash_float_combine(seed, *ptr++);
- hash_float_combine(seed, *(boost::uint16_t*)ptr);
- return seed;
- }
-
-#else
-
- template <class T>
- inline std::size_t float_hash_impl(T v)
- {
- int exp = 0;
-
- v = boost::hash_detail::call_frexp(v, &exp);
-
- // A postive value is easier to hash, so combine the
- // sign with the exponent.
- if(v < 0) {
- v = -v;
- exp += limits<T>::max_exponent -
- limits<T>::min_exponent;
- }
-
- // The result of frexp is always between 0.5 and 1, so its
- // top bit will always be 1. Subtract by 0.5 to remove that.
- v -= T(0.5);
- v = boost::hash_detail::call_ldexp(v,
- limits<std::size_t>::digits + 1);
- std::size_t seed = static_cast<std::size_t>(v);
- v -= seed;
-
- // ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
- std::size_t const length
- = (limits<T>::digits *
- boost::static_log2<limits<T>::radix>::value - 1)
- / limits<std::size_t>::digits;
-
- for(std::size_t i = 0; i != length; ++i)
- {
- v = boost::hash_detail::call_ldexp(v,
- limits<std::size_t>::digits);
- std::size_t part = static_cast<std::size_t>(v);
- v -= part;
- hash_float_combine(seed, part);
- }
-
- hash_float_combine(seed, exp);
-
- return seed;
- }
-#endif
-
- template <class T>
         inline std::size_t float_hash_value(T v)
         {
-#if defined(BOOST_HASH_USE_FPCLASSIFY)
             using namespace std;
             switch (fpclassify(v)) {
             case FP_ZERO:
@@ -183,15 +84,26 @@
                 BOOST_ASSERT(0);
                 return 0;
             }
-#else
+ }
+ }
+}
+
+#else // !BOOST_HASH_USE_FPCLASSIFY
+
+namespace boost
+{
+ namespace hash_detail
+ {
+ template <class T>
+ inline std::size_t float_hash_value(T v)
+ {
             return v == 0 ? 0 : float_hash_impl(v);
-#endif
         }
     }
 }
 
-#if defined(BOOST_MSVC)
-#pragma warning(pop)
-#endif
+#endif // BOOST_HASH_USE_FPCLASSIFY
+
+#undef BOOST_HASH_USE_FPCLASSIFY
 
 #endif

Copied: branches/release/boost/functional/hash/detail/limits.hpp (from r53169, /trunk/boost/functional/hash/detail/limits.hpp)
==============================================================================
--- /trunk/boost/functional/hash/detail/limits.hpp (original)
+++ branches/release/boost/functional/hash/detail/limits.hpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -58,4 +58,4 @@
     }
 }
 
-#endif
\ No newline at end of file
+#endif

Modified: branches/release/boost/functional/hash/hash.hpp
==============================================================================
--- branches/release/boost/functional/hash/hash.hpp (original)
+++ branches/release/boost/functional/hash/hash.hpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -15,6 +15,7 @@
 #include <boost/functional/hash/detail/hash_float.hpp>
 #include <boost/detail/container_fwd.hpp>
 #include <string>
+#include <boost/limits.hpp>
 
 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 #include <boost/type_traits/is_pointer.hpp>

Modified: branches/release/libs/functional/hash/doc/changes.qbk
==============================================================================
--- branches/release/libs/functional/hash/doc/changes.qbk (original)
+++ branches/release/libs/functional/hash/doc/changes.qbk 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -84,4 +84,10 @@
 * [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
   for vxworks.
 
+[h2 Boost 1.40.0]
+
+* Automatically configure the float functions using template metaprogramming
+ instead of trying to configure every possibility manually.
+* Workaround for when STLport doesn't support long double.
+
 [endsect]

Modified: branches/release/libs/functional/hash/test/hash_float_test.hpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_float_test.hpp (original)
+++ branches/release/libs/functional/hash/test/hash_float_test.hpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -14,7 +14,7 @@
 #include <boost/detail/lightweight_test.hpp>
 
 #include <cmath>
-#include <boost/limits.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
 
 #include <iostream>
 
@@ -23,6 +23,10 @@
 #pragma warning(disable:4127) // conditional expression is constant
 #endif
 
+char const* float_type(float*) { return "float"; }
+char const* float_type(double*) { return "double"; }
+char const* float_type(long double*) { return "long double"; }
+
 template <class T>
 void float_tests(char const* name, T* = 0)
 {
@@ -36,6 +40,15 @@
         <<"boost::hash_detail::limits<std::size_t>::digits = "
             <<boost::hash_detail::limits<std::size_t>::digits<<"\n"
         <<"\n"
+ <<"boost::hash_detail::call_ldexp<T>::float_type = "
+ <<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_ldexp<T>::float_type*)0)<<"\n"
+ <<"boost::call_frexp<T>::float_type = "
+ <<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n"
+ <<"boost::hash_detail::call_frexp<T>::float_type = "
+ <<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n"
+ <<"boost::hash_detail::select_hash_type<T>::type = "
+ <<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::select_hash_type<T>::type*)0)<<"\n"
+ <<"\n"
         ;
 
     HASH_NAMESPACE::hash<T> x1;
@@ -112,6 +125,14 @@
     T half_max = max / 2;
     T quarter_max = max / 4;
     T three_quarter_max = max - quarter_max;
+
+ // Check the limits::max is in range.
+ BOOST_TEST(max != half_max);
+ BOOST_TEST(max != quarter_max);
+ BOOST_TEST(max != three_quarter_max);
+ BOOST_TEST(half_max != quarter_max);
+ BOOST_TEST(half_max != three_quarter_max);
+ BOOST_TEST(quarter_max != three_quarter_max);
 
     BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
     BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));

Modified: branches/release/libs/functional/hash/test/hash_function_pointer_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_function_pointer_test.cpp (original)
+++ branches/release/libs/functional/hash/test/hash_function_pointer_test.cpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -13,7 +13,6 @@
 
 #include <boost/detail/lightweight_test.hpp>
 
-#include <boost/limits.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/type_traits/is_base_and_derived.hpp>
 

Modified: branches/release/libs/functional/hash/test/hash_number_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_number_test.cpp (original)
+++ branches/release/libs/functional/hash/test/hash_number_test.cpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -15,7 +15,7 @@
 #include <boost/detail/lightweight_test.hpp>
 
 #include <boost/preprocessor/cat.hpp>
-#include <boost/limits.hpp>
+#include <boost/functional/hash/detail/limits.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/type_traits/is_base_and_derived.hpp>
 

Modified: branches/release/libs/functional/hash/test/hash_string_test.cpp
==============================================================================
--- branches/release/libs/functional/hash/test/hash_string_test.cpp (original)
+++ branches/release/libs/functional/hash/test/hash_string_test.cpp 2009-05-28 16:42:55 EDT (Thu, 28 May 2009)
@@ -13,7 +13,6 @@
 
 #include <boost/detail/lightweight_test.hpp>
 
-#include <boost/limits.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/type_traits/is_base_and_derived.hpp>
 #include <string>


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