Chris@16: Chris@16: // Copyright 2005-2009 Daniel James. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // Based on Peter Dimov's proposal Chris@16: // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf Chris@16: // issue 6.18. Chris@16: Chris@16: // This implements the extensions to the standard. Chris@16: // It's undocumented, so you shouldn't use it.... Chris@16: Chris@16: #if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP) Chris@16: #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP Chris@16: Chris@101: #include Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: #pragma once Chris@101: #endif Chris@101: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_HDR_ARRAY) Chris@16: # include Chris@16: #endif Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_HDR_TUPLE) Chris@16: # include Chris@16: #endif Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_HDR_MEMORY) Chris@16: # include Chris@16: #endif Chris@16: Chris@16: #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: #include Chris@16: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: template Chris@16: std::size_t hash_value(std::pair const&); Chris@16: template Chris@16: std::size_t hash_value(std::vector const&); Chris@16: template Chris@16: std::size_t hash_value(std::list const& v); Chris@16: template Chris@16: std::size_t hash_value(std::deque const& v); Chris@16: template Chris@16: std::size_t hash_value(std::set const& v); Chris@16: template Chris@16: std::size_t hash_value(std::multiset const& v); Chris@16: template Chris@16: std::size_t hash_value(std::map const& v); Chris@16: template Chris@16: std::size_t hash_value(std::multimap const& v); Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::complex const&); Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::pair const& v) Chris@16: { Chris@16: std::size_t seed = 0; Chris@16: boost::hash_combine(seed, v.first); Chris@16: boost::hash_combine(seed, v.second); Chris@16: return seed; Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::vector const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::list const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::deque const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::set const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::multiset const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::map const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::multimap const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: Chris@16: template Chris@16: std::size_t hash_value(std::complex const& v) Chris@16: { Chris@16: boost::hash hasher; Chris@16: std::size_t seed = hasher(v.imag()); Chris@16: seed ^= hasher(v.real()) + (seed<<6) + (seed>>2); Chris@16: return seed; Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_HDR_ARRAY) Chris@16: template Chris@16: std::size_t hash_value(std::array const& v) Chris@16: { Chris@16: return boost::hash_range(v.begin(), v.end()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_HDR_TUPLE) Chris@16: namespace hash_detail { Chris@16: template Chris@16: inline typename boost::enable_if_c<(I == std::tuple_size::value), Chris@16: void>::type Chris@16: hash_combine_tuple(std::size_t&, T const&) Chris@16: { Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename boost::enable_if_c<(I < std::tuple_size::value), Chris@16: void>::type Chris@16: hash_combine_tuple(std::size_t& seed, T const& v) Chris@16: { Chris@16: boost::hash_combine(seed, std::get(v)); Chris@16: boost::hash_detail::hash_combine_tuple(seed, v); Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t hash_tuple(T const& v) Chris@16: { Chris@16: std::size_t seed = 0; Chris@16: boost::hash_detail::hash_combine_tuple<0>(seed, v); Chris@16: return seed; Chris@16: } Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) Chris@16: template Chris@16: inline std::size_t hash_value(std::tuple const& v) Chris@16: { Chris@16: return boost::hash_detail::hash_tuple(v); Chris@16: } Chris@16: #else Chris@16: Chris@16: inline std::size_t hash_value(std::tuple<> const& v) Chris@16: { Chris@16: return boost::hash_detail::hash_tuple(v); Chris@16: } Chris@16: Chris@16: # define BOOST_HASH_TUPLE_F(z, n, _) \ Chris@16: template< \ Chris@16: BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \ Chris@16: > \ Chris@16: inline std::size_t hash_value(std::tuple< \ Chris@16: BOOST_PP_ENUM_PARAMS_Z(z, n, A) \ Chris@16: > const& v) \ Chris@16: { \ Chris@16: return boost::hash_detail::hash_tuple(v); \ Chris@16: } Chris@16: Chris@16: BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _) Chris@16: # undef BOOST_HASH_TUPLE_F Chris@16: #endif Chris@16: Chris@16: #endif Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_SMART_PTR) Chris@16: template Chris@16: inline std::size_t hash_value(std::shared_ptr const& x) { Chris@16: return boost::hash_value(x.get()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline std::size_t hash_value(std::unique_ptr const& x) { Chris@16: return boost::hash_value(x.get()); Chris@16: } Chris@16: #endif Chris@16: Chris@16: // Chris@16: // call_hash_impl Chris@16: // Chris@16: Chris@16: // On compilers without function template ordering, this deals with arrays. Chris@16: Chris@16: #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: namespace hash_detail Chris@16: { Chris@16: template Chris@16: struct call_hash_impl Chris@16: { Chris@16: template Chris@16: struct inner Chris@16: { Chris@16: static std::size_t call(T const& v) Chris@16: { Chris@16: using namespace boost; Chris@16: return hash_value(v); Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct call_hash_impl Chris@16: { Chris@16: template Chris@16: struct inner Chris@16: { Chris@16: static std::size_t call(Array const& v) Chris@16: { Chris@16: const int size = sizeof(v) / sizeof(*v); Chris@16: return boost::hash_range(v, v + size); Chris@16: } Chris@16: }; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct call_hash Chris@16: : public call_hash_impl::value> Chris@16: ::BOOST_NESTED_TEMPLATE inner Chris@16: { Chris@16: }; Chris@16: } Chris@16: #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING Chris@16: Chris@16: // Chris@16: // boost::hash Chris@16: // Chris@16: Chris@16: Chris@16: #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) Chris@16: Chris@16: template struct hash Chris@16: : std::unary_function Chris@16: { Chris@16: #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: std::size_t operator()(T const& val) const Chris@16: { Chris@16: return hash_value(val); Chris@16: } Chris@16: #else Chris@16: std::size_t operator()(T const& val) const Chris@16: { Chris@16: return hash_detail::call_hash::call(val); Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: Chris@16: #if BOOST_WORKAROUND(__DMC__, <= 0x848) Chris@16: template struct hash Chris@16: : std::unary_function Chris@16: { Chris@16: std::size_t operator()(const T* val) const Chris@16: { Chris@16: return boost::hash_range(val, val+n); Chris@16: } Chris@16: }; Chris@16: #endif Chris@16: Chris@16: #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Chris@16: Chris@16: // On compilers without partial specialization, boost::hash Chris@16: // has already been declared to deal with pointers, so just Chris@16: // need to supply the non-pointer version of hash_impl. Chris@16: Chris@16: namespace hash_detail Chris@16: { Chris@16: template Chris@16: struct hash_impl; Chris@16: Chris@16: template <> Chris@16: struct hash_impl Chris@16: { Chris@16: template Chris@16: struct inner Chris@16: : std::unary_function Chris@16: { Chris@16: #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) Chris@16: std::size_t operator()(T const& val) const Chris@16: { Chris@16: return hash_value(val); Chris@16: } Chris@16: #else Chris@16: std::size_t operator()(T const& val) const Chris@16: { Chris@16: return hash_detail::call_hash::call(val); Chris@16: } Chris@16: #endif Chris@16: }; Chris@16: }; Chris@16: } Chris@16: #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION Chris@16: } Chris@16: Chris@16: #endif