diff --git a/include/boost/functional.hpp b/include/boost/functional.hpp index c0cf503..b618485 100644 --- a/include/boost/functional.hpp +++ b/include/boost/functional.hpp @@ -18,6 +18,7 @@ namespace boost { +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // -------------------------------------------------------------------------- // The following traits classes allow us to avoid the need for ptr_fun // because the types of arguments and the result of a function can be @@ -115,6 +116,31 @@ namespace boost typedef A1 first_argument_type; typedef A2 second_argument_type; }; +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + // -------------------------------------------------------------------------- + // If we have no partial specialisation available, decay to a situation + // that is no worse than in the Standard, i.e., ptr_fun will be required. + // -------------------------------------------------------------------------- + + template + struct unary_traits + { + typedef Operation function_type; + typedef const Operation& param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::argument_type argument_type; + }; + + template + struct binary_traits + { + typedef Operation function_type; + typedef const Operation & param_type; + typedef typename Operation::result_type result_type; + typedef typename Operation::first_argument_type first_argument_type; + typedef typename Operation::second_argument_type second_argument_type; + }; +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // -------------------------------------------------------------------------- // unary_negate, not1 diff --git a/include/boost/functional/hash/detail/float_functions.hpp b/include/boost/functional/hash/detail/float_functions.hpp index f3db52f..4b8374d 100644 --- a/include/boost/functional/hash/detail/float_functions.hpp +++ b/include/boost/functional/hash/detail/float_functions.hpp @@ -7,12 +7,12 @@ #define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP #include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - #include +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# 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. diff --git a/include/boost/functional/hash/detail/hash_float.hpp b/include/boost/functional/hash/detail/hash_float.hpp index ee0ee87..7c3de31 100644 --- a/include/boost/functional/hash/detail/hash_float.hpp +++ b/include/boost/functional/hash/detail/hash_float.hpp @@ -6,11 +6,11 @@ #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER) #define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once #endif +#include #include #include #include diff --git a/include/boost/functional/hash/detail/limits.hpp b/include/boost/functional/hash/detail/limits.hpp index 4a971a6..f5b520e 100644 --- a/include/boost/functional/hash/detail/limits.hpp +++ b/include/boost/functional/hash/detail/limits.hpp @@ -9,9 +9,8 @@ #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER) #define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once #endif #include diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index ba34ca5..998c08e 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -13,11 +13,6 @@ #if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - #include #include #include @@ -37,10 +32,18 @@ # include #endif +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) #include #endif +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +#include +#endif + namespace boost { template @@ -229,7 +232,11 @@ namespace boost template struct inner { +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) static std::size_t call(Array const& v) +#else + static std::size_t call(Array& v) +#endif { const int size = sizeof(v) / sizeof(*v); return boost::hash_range(v, v + size); @@ -251,6 +258,7 @@ namespace boost // +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct hash : std::unary_function @@ -279,6 +287,93 @@ namespace boost }; #endif +#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + + // On compilers without partial specialization, boost::hash + // has already been declared to deal with pointers, so just + // need to supply the non-pointer version of hash_impl. + + namespace hash_detail + { + template + struct hash_impl; + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + + 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 + + // Visual C++ 6.5 has problems with nested member functions and + // applying const to const types in templates. So we get this: + + 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); + } + + std::size_t operator()(T& val) const + { + return hash_detail::call_hash::call(val); + } + }; + }; + + template <> + struct hash_impl_msvc + { + template + struct inner + : public std::unary_function + { + std::size_t operator()(T& 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 {}; + }; + +#endif // Visual C++ 6.5 + } +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION } #endif diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index e1aa245..42ea019 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -19,6 +19,9 @@ #include #include +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) +#include +#endif #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX) #include @@ -35,6 +38,13 @@ #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 + namespace boost { namespace hash_detail @@ -129,7 +139,7 @@ namespace boost template std::size_t hash_value( - std::basic_string, A> const&); + std::basic_string, A> const&); template typename boost::hash_detail::float_numbers::type hash_value(T); @@ -238,8 +248,13 @@ namespace boost #endif #endif +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template + inline void hash_combine(std::size_t& seed, T& v) +#else template inline void hash_combine(std::size_t& seed, T const& v) +#endif { boost::hash hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); @@ -313,7 +328,7 @@ namespace boost template inline std::size_t hash_value( - std::basic_string, A> const& v) + std::basic_string, A> const& v) { return hash_range(v.begin(), v.end()); } @@ -347,6 +362,7 @@ namespace boost // // These are undefined later. +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #define BOOST_HASH_SPECIALIZE(type) \ template <> struct hash \ : public std::unary_function \ @@ -366,6 +382,45 @@ namespace boost 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) @@ -409,6 +464,7 @@ namespace boost // Specializing boost::hash for pointers. +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct hash @@ -427,8 +483,52 @@ namespace boost } }; +#else + + // For compilers without partial specialization, we define a + // boost::hash for all remaining types. But hash_impl is only defined + // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS + // is defined there will still be a compile error for types not supported + // in the standard. + + 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 + { +#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590) + return boost::hash_value(val); +#else + std::size_t x = static_cast( + reinterpret_cast(val)); + + return x + (x >> 3); +#endif + } + }; + }; + } + + template struct hash + : public boost::hash_detail::hash_impl::value> + ::BOOST_NESTED_TEMPLATE inner + { + }; + +#endif } +#undef BOOST_HASH_CHAR_TRAITS + #if defined(BOOST_MSVC) #pragma warning(pop) #endif diff --git a/include/boost/functional/hash/hash_fwd.hpp b/include/boost/functional/hash/hash_fwd.hpp index 01fe012..1d51b07 100644 --- a/include/boost/functional/hash/hash_fwd.hpp +++ b/include/boost/functional/hash/hash_fwd.hpp @@ -10,11 +10,11 @@ #if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) #define BOOST_FUNCTIONAL_HASH_FWD_HPP -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once #endif +#include #include #include @@ -22,7 +22,11 @@ namespace boost { template struct hash; +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + template void hash_combine(std::size_t& seed, T& v); +#else template void hash_combine(std::size_t& seed, T const& v); +#endif template std::size_t hash_range(It, It); template void hash_range(std::size_t&, It, It); diff --git a/include/boost/functional/hash_fwd.hpp b/include/boost/functional/hash_fwd.hpp index eea9073..b640988 100644 --- a/include/boost/functional/hash_fwd.hpp +++ b/include/boost/functional/hash_fwd.hpp @@ -3,9 +3,5 @@ // 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) -#include -#if defined(BOOST_HAS_PRAGMA_ONCE) -#pragma once -#endif - #include +