Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:03

0001 /*!
0002 @file
0003 Defines `boost::hana::hash`.
0004 
0005 Copyright Jason Rice 2016
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
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     //! @cond
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     //! @endcond
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 }} // end namespace boost::hana
0113 
0114 #endif // !BOOST_HANA_HASH_HPP