diff --git a/include/boost/functional/detail/container_fwd.hpp b/include/boost/functional/detail/container_fwd.hpp index d01420a..5961bc5 100644 --- a/include/boost/functional/detail/container_fwd.hpp +++ b/include/boost/functional/detail/container_fwd.hpp @@ -10,6 +10,12 @@ #include #include +#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) +#define BOOST_HASH_CHAR_TRAITS string_char_traits +#else +#define BOOST_HASH_CHAR_TRAITS char_traits +#endif + #if (defined(__GLIBCXX__) && defined(_GLIBCXX_DEBUG)) \ || BOOST_WORKAROUND(__BORLANDC__, > 0x551) \ || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) @@ -46,12 +52,6 @@ #include #endif -#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) -#define BOOST_HASH_CHAR_TRAITS string_char_traits -#else -#define BOOST_HASH_CHAR_TRAITS char_traits -#endif - #if defined(BOOST_MSVC) #pragma warning(push) #pragma warning(disable:4099) // struct/class mismatch in fwd declarations diff --git a/include/boost/functional/hash.hpp b/include/boost/functional/hash.hpp index ceebe66..81d26ac 100644 --- a/include/boost/functional/hash.hpp +++ b/include/boost/functional/hash.hpp @@ -7,13 +7,4 @@ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf // issue 6.18. -#if !defined(BOOST_FUNCTIONAL_HASH_HPP) -#define BOOST_FUNCTIONAL_HASH_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - #include - -#endif diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index f28052d..30be81d 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -11,14 +11,15 @@ #if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP) #define BOOST_FUNCTIONAL_HASH_HASH_HPP -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - #include #include #include #include +#include + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#include +#endif #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include @@ -55,13 +56,8 @@ namespace boost std::size_t hash_value(double v); std::size_t hash_value(long double v); -#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) template - std::size_t hash_value(std::basic_string, A> const&); -#else - template - std::size_t hash_value(std::basic_string, A> const&); -#endif + std::size_t hash_value(std::basic_string, A> const&); template std::size_t hash_value(std::pair const&); @@ -117,50 +113,6 @@ namespace boost return x + (x >> 3); } -#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - namespace hash_detail - { - template - struct call_hash_impl - { - template - struct inner - { - static std::size_t call(T const& v) - { - using namespace boost; - return hash_value(v); - } - }; - }; - - template <> - struct call_hash_impl - { - template - struct inner - { -#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) - static std::size_t call(Array& v) -#else - static std::size_t call(Array const& v) -#endif - { - const int size = sizeof(v) / sizeof(*v); - return boost::hash_range(v, v + size); - } - }; - }; - - template - struct call_hash - : public call_hash_impl::value> - ::BOOST_NESTED_TEMPLATE inner - { - }; - } -#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING - #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) template inline void hash_combine(std::size_t& seed, T& v) @@ -235,13 +187,8 @@ namespace boost } #endif -#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) template - inline std::size_t hash_value(std::basic_string, A> const& v) -#else - template - inline std::size_t hash_value(std::basic_string, A> const& v) -#endif + inline std::size_t hash_value(std::basic_string, A> const& v) { return hash_range(v.begin(), v.end()); } @@ -312,9 +259,191 @@ namespace boost return hash_range(v.begin(), v.end()); } + // // boost::hash + // #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) +#define BOOST_HASH_SPECIALIZE(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_REF(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; +#else +#define BOOST_HASH_SPECIALIZE(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; \ + \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(const type v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; + +#define BOOST_HASH_SPECIALIZE_REF(type) \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; \ + \ + template <> struct hash \ + : public std::unary_function \ + { \ + std::size_t operator()(type const& v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; +#endif + + BOOST_HASH_SPECIALIZE(bool) + BOOST_HASH_SPECIALIZE(char) + BOOST_HASH_SPECIALIZE(signed char) + BOOST_HASH_SPECIALIZE(unsigned char) +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) + BOOST_HASH_SPECIALIZE(wchar_t) +#endif + BOOST_HASH_SPECIALIZE(short) +//TODO: Why did I disable this overload?? +//#if !(defined(BOOST_MSVC) && BOOST_MSVC < 1300) + BOOST_HASH_SPECIALIZE(unsigned short) +//#endif + BOOST_HASH_SPECIALIZE(int) + BOOST_HASH_SPECIALIZE(unsigned int) + BOOST_HASH_SPECIALIZE(long) + BOOST_HASH_SPECIALIZE(unsigned long) + + BOOST_HASH_SPECIALIZE(float) + BOOST_HASH_SPECIALIZE(double) + BOOST_HASH_SPECIALIZE(long double) + + BOOST_HASH_SPECIALIZE_REF(std::string) +#if !defined(BOOST_NO_STD_WSTRING) + BOOST_HASH_SPECIALIZE_REF(std::wstring) +#endif + +#undef BOOST_HASH_SPECIALIZE +#undef BOOST_HASH_SPECIALIZE_REF + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template + struct hash + : public std::unary_function + { + std::size_t operator()(T* v) const \ + { \ + return boost::hash_value(v); \ + } \ + }; +#else + namespace hash_detail + { + template + struct hash_impl; + + template <> + struct hash_impl + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T val) const + { + return boost::hash_value(val); + } + }; + }; + } + + template struct hash + : public hash_detail::hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; +#endif +} + +#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP + +//////////////////////////////////////////////////////////////////////////////// + +#if !defined(BOOST_HASH_NO_EXTENSIONS) \ + && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) +#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP + +namespace boost +{ + +#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + namespace hash_detail + { + template + struct call_hash_impl + { + template + struct inner + { + static std::size_t call(T const& v) + { + using namespace boost; + return hash_value(v); + } + }; + }; + + template <> + struct call_hash_impl + { + template + struct inner + { + static std::size_t call(Array& v) + { + const int size = sizeof(v) / sizeof(*v); + return boost::hash_range(v, v + size); + } + }; + }; + + template + struct call_hash + : public call_hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; + } +#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + template struct hash : std::unary_function { @@ -330,57 +459,89 @@ namespace boost } #endif }; - + +#elif !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + // On compilers without partial specialization, boost::hash + // has already been declared to deal with pointers, so just + // need to supply the non-pointer version. + + namespace hash_detail + { + template <> + struct hash_impl + { + template + struct inner + : std::unary_function + { +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + std::size_t operator()(T const& val) const + { + return hash_value(val); + } +#else + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } +#endif + }; + }; + } + #else // Visual C++ 6.5 + // There's probably a more elegant way to Visual C++ 6.5 to work // but I don't know what it is. namespace hash_detail { - template - struct hash_impl_base - : std::unary_function - { - std::size_t operator()(T const& val) const - { - return hash_detail::call_hash::call(val); - } - }; - template - struct hash_impl; - - template <> - struct hash_impl + struct hash_impl_msvc { template - struct inner : public hash_impl_base {}; - }; - - template <> - struct hash_impl - { - template - struct inner : public hash_impl_base + struct inner + : public std::unary_function { std::size_t operator()(T const& val) const { - return hash_impl_base::operator()(val); + return hash_detail::call_hash::call(val); } std::size_t operator()(T& val) const { - return hash_impl_base::operator()(val); + return hash_detail::call_hash::call(val); } }; }; + + template <> + struct hash_impl_msvc + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T const& val) const + { + return hash_detail::call_hash::call(val); + } + }; + }; + + template + struct hash_impl_msvc2 + : public hash_impl_msvc::value> + ::BOOST_NESTED_TEMPLATE inner {}; + + template <> + struct hash_impl + { + template + struct inner : public hash_impl_msvc2 {}; + }; } - - template struct hash - : public hash_detail::hash_impl::value> - ::BOOST_NESTED_TEMPLATE inner - { - }; #endif }