#ifndef SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP #define SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP #include #include #include #include #include #include #include #include #include namespace sprout_adl { sprout::not_found_via_adl hash_value(...); } // namespace sprout_adl namespace sprout_hash_detail { using sprout::hash_value; using sprout_adl::hash_value; template struct has_adl_hash_value_test { public: template< typename U = T, typename sprout::enabler_if< sprout::is_found_via_adl()))>::value >::type = sprout::enabler > static std::true_type test(int); static std::false_type test(...); }; #if defined(_MSC_VER) template::test(0))> struct has_adl_hash_value : public Base_ {}; #else template struct has_adl_hash_value : public decltype(sprout_hash_detail::has_adl_hash_value_test::test(0)) {}; #endif template struct select_adl_hash_value; template struct select_adl_hash_value< T, typename std::enable_if< sprout_hash_detail::has_adl_hash_value::value >::type > : public std::true_type {}; template struct select_adl_hash_value< T, typename std::enable_if::value )>::type > : public std::false_type {}; template struct select_std_hash; template struct select_std_hash< T, typename std::enable_if< !sprout_hash_detail::has_adl_hash_value::value >::type > : public std::true_type {}; template struct select_std_hash< T, typename std::enable_if::value )>::type > : public std::false_type {}; template struct noexcept_to_hash; template struct noexcept_to_hash::value>::type> : public std::integral_constant()), false)> {}; template struct noexcept_to_hash::value>::type> : public std::integral_constant::type>()(std::declval()), false)> {}; template struct to_hash_result; template struct to_hash_result::value>::type> { public: typedef decltype(hash_value(std::declval())) type; }; template struct to_hash_result::value>::type> { public: typedef decltype(std::hash::type>()(std::declval())) type; }; template< typename T, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout_hash_detail::to_hash_result::type to_hash_impl(T&& t) SPROUT_NOEXCEPT_EXPR((sprout_hash_detail::noexcept_to_hash::value)) { return hash_value(sprout::forward(t)); } template< typename T, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR typename sprout_hash_detail::to_hash_result::type to_hash_impl(T&& t) SPROUT_NOEXCEPT_EXPR((sprout_hash_detail::noexcept_to_hash::value)) { return std::hash::type>()(sprout::forward(t)); } } // namespace sprout_hash_detail namespace sprout { // // to_hash // template inline SPROUT_CONSTEXPR std::size_t to_hash(T const& v) { return sprout_hash_detail::to_hash_impl(v); } } // namespace sprout #endif // #ifndef SPROUT_FUNCTIONAL_HASH_TO_HASH_HPP