text: 
  // Copyright 2005-2012 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_HASH_FLOAT_HEADER)
  #define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
  
  #include <boost/config.hpp>
  #if defined(BOOST_HAS_PRAGMA_ONCE)
  #pragma once
  #endif
  
  #include <boost/functional/hash/detail/float_functions.hpp>
  #include <boost/functional/hash/detail/limits.hpp>
  #include <boost/utility/enable_if.hpp>
  #include <boost/integer/static_log2.hpp>
  #include <boost/cstdint.hpp>
  #include <boost/assert.hpp>
  #include <boost/limits.hpp>
  #include <cstring>
  
  #if defined(BOOST_MSVC)
  #pragma warning(push)
  #if BOOST_MSVC >= 1400
  #pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
                                // not satisfy test. Loop body not executed
  #endif
  #endif
  
  // Can we use fpclassify?
  
  // 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 1
  #  else
  #    define BOOST_HASH_USE_FPCLASSIFY 0
  #  endif
  
  // Everything else
  #else
  #  define BOOST_HASH_USE_FPCLASSIFY 0
  #endif
  
  namespace boost
  {
      namespace hash_detail
      {
          inline void hash_float_combine(std::size_t& seed, std::size_t value)
          {
              seed ^= value + (seed<<6) + (seed>>2);
          }
  
          ////////////////////////////////////////////////////////////////////////
          // Binary hash function
          //
          // Only used for floats with known iec559 floats, and certain values in
          // numeric_limits
  
          inline std::size_t hash_binary(char* ptr, std::size_t length)
          {
              std::size_t seed = 0;
  
              if (length >= sizeof(std::size_t)) {
                  std::memcpy(&seed, ptr, sizeof(std::size_t));
                  length -= sizeof(std::size_t);
                  ptr += sizeof(std::size_t);
  
                  while(length >= sizeof(std::size_t)) {
                      std::size_t buffer = 0;
                      std::memcpy(&buffer, ptr, sizeof(std::size_t));
                      hash_float_combine(seed, buffer);
                      length -= sizeof(std::size_t);
                      ptr += sizeof(std::size_t);
                  }
              }
  
              if (length > 0) {
                  std::size_t buffer = 0;
                  std::memcpy(&buffer, ptr, length);
                  hash_float_combine(seed, buffer);
              }
  
              return seed;
          }
  
          template <typename Float, unsigned digits, unsigned max_exponent>
          struct enable_binary_hash
          {
              BOOST_STATIC_CONSTANT(bool, value =
                  std::numeric_limits<Float>::is_iec559 &&
                  std::numeric_limits<Float>::digits == digits &&
                  std::numeric_limits<Float>::radix == 2 &&
                  std::numeric_limits<Float>::max_exponent == max_exponent);
          };
  
          template <typename Float>
          inline std::size_t float_hash_impl(Float v,
              BOOST_DEDUCED_TYPENAME boost::enable_if_c<
                  enable_binary_hash<Float, 24, 128>::value,
                  std::size_t>::type)
          {
              return hash_binary((char*) &v, 4);
          }
  
  
          template <typename Float>
          inline std::size_t float_hash_impl(Float v,
              BOOST_DEDUCED_TYPENAME boost::enable_if_c<
                  enable_binary_hash<Float, 53, 1024>::value,
                  std::size_t>::type)
          {
              return hash_binary((char*) &v, 8);
          }
  
          template <typename Float>
          inline std::size_t float_hash_impl(Float v,
              BOOST_DEDUCED_TYPENAME boost::enable_if_c<
                  enable_binary_hash<Float, 64, 16384>::value,
                  std::size_t>::type)
          {
              return hash_binary((char*) &v, 10);
          }
  
          template <typename Float>
          inline std::size_t float_hash_impl(Float v,
              BOOST_DEDUCED_TYPENAME boost::enable_if_c<
                  enable_binary_hash<Float, 113, 16384>::value,
                  std::size_t>::type)
          {
              return hash_binary((char*) &v, 16);
          }
  
          ////////////////////////////////////////////////////////////////////////
          // Portable hash function
          //
          // Used as a fallback when the binary hash function isn't supported.
  
          template <class T>
          inline std::size_t float_hash_impl2(T v)
          {
              boost::hash_detail::call_frexp<T> frexp;
              boost::hash_detail::call_ldexp<T> ldexp;
  
              int exp = 0;
  
              v = frexp(v, &exp);
  
              // A postive value is easier to hash, so combine the
              // sign with the exponent and use the absolute value.
              if(v < 0) {
                  v = -v;
                  exp += limits<T>::max_exponent -
                      limits<T>::min_exponent;
              }
  
              v = ldexp(v, limits<std::size_t>::digits);
              std::size_t seed = static_cast<std::size_t>(v);
              v -= static_cast<T>(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
                          + limits<std::size_t>::digits - 1)
                  / limits<std::size_t>::digits;
  
              for(std::size_t i = 0; i != length; ++i)
              {
                  v = ldexp(v, limits<std::size_t>::digits);
                  std::size_t part = static_cast<std::size_t>(v);
                  v -= static_cast<T>(part);
                  hash_float_combine(seed, part);
              }
  
              hash_float_combine(seed, exp);
  
              return seed;
          }
  
  #if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
          template <class T>
          inline std::size_t float_hash_impl(T v, ...)
          {
              typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
              return float_hash_impl2(static_cast<type>(v));
          }
  #endif
      }
  }
  
  #if BOOST_HASH_USE_FPCLASSIFY
  
  #include <boost/config/no_tr1/cmath.hpp>
  
  namespace boost
  {
      namespace hash_detail
      {
          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))
  #endif
              {
              case FP_ZERO:
                  return 0;
              case FP_INFINITE:
                  return (std::size_t)(v > 0 ? -1 : -2);
              case FP_NAN:
                  return (std::size_t)(-3);
              case FP_NORMAL:
              case FP_SUBNORMAL:
                  return float_hash_impl(v, 0);
              default:
                  BOOST_ASSERT(0);
                  return 0;
              }
          }
      }
  }
  
  #else // !BOOST_HASH_USE_FPCLASSIFY
  
  namespace boost
  {
      namespace hash_detail
      {
          template <class T>
          inline bool is_zero(T v)
          {
  #if !defined(__GNUC__)
              return v == 0;
  #else
              // GCC's '-Wfloat-equal' will complain about comparing
              // v to 0, but because it disables warnings for system
              // headers it won't complain if you use std::equal_to to
              // compare with 0. Resulting in this silliness:
              return std::equal_to<T>()(v, 0);
  #endif
          }
  
          template <class T>
          inline std::size_t float_hash_value(T v)
          {
              return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
          }
      }
  }
  
  #endif // BOOST_HASH_USE_FPCLASSIFY
  
  #undef BOOST_HASH_USE_FPCLASSIFY
  
  #if defined(BOOST_MSVC)
  #pragma warning(pop)
  #endif
  
  #endif
  