Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:33:43

0001 #ifndef BOOST_HASH2_GET_INTEGRAL_RESULT_HPP_INCLUDED
0002 #define BOOST_HASH2_GET_INTEGRAL_RESULT_HPP_INCLUDED
0003 
0004 // Copyright 2017, 2018 Peter Dimov.
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #include <boost/hash2/detail/read.hpp>
0009 #include <type_traits>
0010 #include <limits>
0011 #include <cstddef>
0012 
0013 namespace boost
0014 {
0015 namespace hash2
0016 {
0017 
0018 namespace detail
0019 {
0020 
0021 // contraction
0022 
0023 // 2 -> 1, 4 -> x
0024 template<class R>
0025 constexpr typename std::enable_if<sizeof(R) <= 4, std::uint32_t>::type
0026     get_result_multiplier()
0027 {
0028     return 0xBF3D6763u;
0029 }
0030 
0031 // 8 -> x
0032 template<class R>
0033 constexpr typename std::enable_if<sizeof(R) == 8, std::uint64_t>::type
0034     get_result_multiplier()
0035 {
0036     return 0x99EBE72FE70129CBull;
0037 }
0038 
0039 } // namespace detail
0040 
0041 // contraction
0042 
0043 template<class T, class Hash, class R = typename Hash::result_type>
0044     typename std::enable_if<std::is_integral<R>::value && (sizeof(R) > sizeof(T)), T>::type
0045     get_integral_result( Hash& h )
0046 {
0047     static_assert( std::is_integral<T>::value, "T must be integral" );
0048     static_assert( !std::is_same<typename std::remove_cv<T>::type, bool>::value, "T must not be bool" );
0049 
0050     static_assert( std::is_unsigned<R>::value, "Hash::result_type must be unsigned" );
0051 
0052     typedef typename std::make_unsigned<T>::type U;
0053 
0054     constexpr auto m = detail::get_result_multiplier<R>();
0055 
0056     auto r = h.result();
0057     return static_cast<T>( static_cast<U>( ( r * m ) >> ( std::numeric_limits<R>::digits - std::numeric_limits<U>::digits ) ) );
0058 }
0059 
0060 // identity
0061 
0062 template<class T, class Hash, class R = typename Hash::result_type>
0063     typename std::enable_if<std::is_integral<R>::value && sizeof(R) == sizeof(T), T>::type
0064     get_integral_result( Hash& h )
0065 {
0066     static_assert( std::is_integral<T>::value, "T must be integral" );
0067     static_assert( !std::is_same<typename std::remove_cv<T>::type, bool>::value, "T must not be bool" );
0068 
0069     static_assert( std::is_unsigned<R>::value, "Hash::result_type must be unsigned" );
0070 
0071     typedef typename std::make_unsigned<T>::type U;
0072 
0073     auto r = h.result();
0074     return static_cast<T>( static_cast<U>( r ) );
0075 }
0076 
0077 // expansion
0078 
0079 template<class T, class Hash, class R = typename Hash::result_type>
0080     typename std::enable_if<std::is_integral<R>::value && (sizeof(R) < sizeof(T)), T>::type
0081     get_integral_result( Hash& h )
0082 {
0083     static_assert( std::is_integral<T>::value, "T must be integral" );
0084     static_assert( !std::is_same<typename std::remove_cv<T>::type, bool>::value, "T must not be bool" );
0085 
0086     static_assert( std::is_unsigned<R>::value, "Hash::result_type must be unsigned" );
0087 
0088     typedef typename std::make_unsigned<T>::type U;
0089 
0090     constexpr auto rd = std::numeric_limits<R>::digits;
0091     constexpr auto ud = std::numeric_limits<U>::digits;
0092 
0093     U u = 0;
0094 
0095     for( int i = 0; i < ud; i += rd )
0096     {
0097         auto r = h.result();
0098         u += static_cast<U>( r ) << i;
0099     }
0100 
0101     return static_cast<T>( u );
0102 }
0103 
0104 // array-like R
0105 
0106 template<class T, class Hash, class R = typename Hash::result_type>
0107     typename std::enable_if< !std::is_integral<R>::value, T >::type
0108     get_integral_result( Hash& h )
0109 {
0110     static_assert( std::is_integral<T>::value, "T must be integral" );
0111     static_assert( !std::is_same<typename std::remove_cv<T>::type, bool>::value, "T must not be bool" );
0112 
0113     static_assert( R().size() >= 8, "Array-like result type is too short" );
0114 
0115     auto r = h.result();
0116     return static_cast<T>( detail::read64le( r.data() ) );
0117 }
0118 
0119 } // namespace hash2
0120 } // namespace boost
0121 
0122 #endif // #ifndef BOOST_HASH2_GET_INTEGRAL_RESULT_HPP_INCLUDED