File indexing completed on 2025-01-18 09:38:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_HANA_HASH_HPP
0011 #define BOOST_HANA_HASH_HPP
0012
0013 #include <boost/hana/fwd/hash.hpp>
0014
0015 #include <boost/hana/concept/hashable.hpp>
0016 #include <boost/hana/concept/integral_constant.hpp>
0017 #include <boost/hana/config.hpp>
0018 #include <boost/hana/core/dispatch.hpp>
0019 #include <boost/hana/fwd/integral_constant.hpp>
0020 #include <boost/hana/type.hpp>
0021
0022 #include <type_traits>
0023
0024
0025 namespace boost { namespace hana {
0026
0027 template <typename X>
0028 constexpr auto hash_t::operator()(X const& x) const {
0029 using Tag = typename hana::tag_of<X>::type;
0030 using Hash = BOOST_HANA_DISPATCH_IF(hash_impl<Tag>,
0031 hana::Hashable<Tag>::value
0032 );
0033
0034 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
0035 static_assert(hana::Hashable<Tag>::value,
0036 "hana::hash(x) requires 'x' to be Hashable");
0037 #endif
0038
0039 return Hash::apply(x);
0040 }
0041
0042
0043 template <typename Tag, bool condition>
0044 struct hash_impl<Tag, when<condition>> : default_ {
0045 template <typename X>
0046 static constexpr auto apply(X const&) = delete;
0047 };
0048
0049 namespace detail {
0050 template <typename T, typename = void>
0051 struct hash_integral_helper;
0052
0053 template <typename Member, typename T>
0054 struct hash_integral_helper<Member T::*> {
0055 template <typename X>
0056 static constexpr auto apply(X const&) {
0057 return hana::type_c<hana::integral_constant<Member T::*, X::value>>;
0058 }
0059 };
0060
0061 template <typename T>
0062 struct hash_integral_helper<T,
0063 typename std::enable_if<std::is_signed<T>::value>::type
0064 > {
0065 template <typename X>
0066 static constexpr auto apply(X const&) {
0067 constexpr signed long long x = X::value;
0068 return hana::type_c<hana::integral_constant<signed long long, x>>;
0069 }
0070 };
0071
0072 template <typename T>
0073 struct hash_integral_helper<T,
0074 typename std::enable_if<std::is_unsigned<T>::value>::type
0075 > {
0076 template <typename X>
0077 static constexpr auto apply(X const&) {
0078 constexpr unsigned long long x = X::value;
0079 return hana::type_c<hana::integral_constant<unsigned long long, x>>;
0080 }
0081 };
0082
0083 template <>
0084 struct hash_integral_helper<bool> {
0085 template <typename X>
0086 static constexpr auto apply(X const&) {
0087 return hana::type_c<hana::integral_constant<bool, X::value>>;
0088 }
0089 };
0090
0091 template <>
0092 struct hash_integral_helper<char> {
0093 template <typename X>
0094 static constexpr auto apply(X const&) {
0095 using T = std::conditional<std::is_signed<char>::value,
0096 signed long long, unsigned long long
0097 >::type;
0098 constexpr T x = X::value;
0099 return hana::type_c<hana::integral_constant<T, x>>;
0100 }
0101 };
0102 }
0103
0104 template <typename Tag>
0105 struct hash_impl<Tag, when<hana::IntegralConstant<Tag>::value>> {
0106 template <typename X>
0107 static constexpr auto apply(X const& x) {
0108 using T = typename std::remove_cv<decltype(X::value)>::type;
0109 return detail::hash_integral_helper<T>::apply(x);
0110 }
0111 };
0112 }}
0113
0114 #endif