Warning, file /include/boost/intrusive/detail/hash.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef BOOST_INTRUSIVE_HASH_HASH_HPP
0033 #define BOOST_INTRUSIVE_HASH_HASH_HPP
0034
0035 #include <boost/intrusive/detail/config_begin.hpp>
0036 #include <boost/intrusive/detail/workaround.hpp>
0037 #include <boost/intrusive/detail/hash_integral.hpp>
0038 #include <boost/intrusive/detail/hash_mix.hpp>
0039 #include <boost/intrusive/detail/hash_combine.hpp>
0040 #include <boost/cstdint.hpp>
0041 #include <climits>
0042 #include <cstring>
0043 #include <cfloat>
0044 #include <boost/intrusive/detail/mpl.hpp>
0045
0046 namespace boost {
0047
0048 template<class T>
0049 struct hash;
0050
0051 }
0052
0053
0054
0055
0056
0057 namespace boost_intrusive_adl
0058 {
0059 template<class T>
0060 inline std::size_t hash_value(const T& v)
0061 {
0062 return boost::hash<T>()(v);
0063 }
0064 }
0065
0066 namespace boost {
0067 namespace intrusive {
0068 namespace detail {
0069
0070
0071 template <class T>
0072 inline typename detail::disable_if_c<detail::is_scalar<T>::value, std::size_t>::type
0073 hash_value_dispatch(const T& v)
0074 {
0075
0076 using boost_intrusive_adl::hash_value;
0077 return hash_value(v);
0078 }
0079
0080 template <typename T>
0081 typename enable_if_c<is_enum<T>::value, std::size_t>::type
0082 hash_value( T v )
0083 {
0084 return static_cast<std::size_t>( v );
0085 }
0086
0087
0088
0089
0090
0091
0092
0093 template<class T, std::size_t Bits = sizeof(T) * CHAR_BIT>
0094 struct hash_float_impl;
0095
0096
0097 template<class T> struct hash_float_impl<T, 32>
0098 {
0099 static std::size_t fn( T v )
0100 {
0101 boost::uint32_t w;
0102 std::memcpy( &w, &v, sizeof( v ) );
0103
0104 return w;
0105 }
0106 };
0107
0108
0109 template<class T> struct hash_float_impl<T, 64>
0110 {
0111 static std::size_t fn( T v )
0112 {
0113 boost::uint64_t w;
0114 std::memcpy( &w, &v, sizeof( v ) );
0115
0116 return hash_value( w );
0117 }
0118 };
0119
0120
0121 template<class T> struct hash_float_impl<T, 96>
0122 {
0123 static std::size_t fn( T v )
0124 {
0125 boost::uint64_t w[ 2 ] = {};
0126 std::memcpy( &w, &v, 80 / CHAR_BIT );
0127
0128 std::size_t seed = 0;
0129
0130 seed = hash_value( w[0] ) + (hash_mix)( seed );
0131 seed = hash_value( w[1] ) + (hash_mix)( seed );
0132
0133 return seed;
0134 }
0135 };
0136
0137 #if (LDBL_MAX_10_EXP == 4932)
0138
0139
0140 template<class T> struct hash_float_impl<T, 128>
0141 {
0142 static std::size_t fn( T v )
0143 {
0144 boost::uint64_t w[ 2 ] = {};
0145 std::memcpy( &w, &v, 80 / CHAR_BIT );
0146
0147 std::size_t seed = 0;
0148
0149 seed = hash_value( w[0] ) + (hash_mix)( seed );
0150 seed = hash_value( w[1] ) + (hash_mix)( seed );
0151
0152 return seed;
0153 }
0154 };
0155
0156 #elif (LDBL_MAX_10_EXP > 4932)
0157
0158 template<class T> struct hash_float_impl<T, 128>
0159 {
0160 static std::size_t fn( T v )
0161 {
0162 boost::uint64_t w[ 2 ];
0163 std::memcpy( &w, &v, sizeof( v ) );
0164
0165 std::size_t seed = 0;
0166
0167 #if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
0168
0169 seed = hash_value( w[1] ) + (hash_mix)( seed );
0170 seed = hash_value( w[0] ) + (hash_mix)( seed );
0171
0172 #else
0173
0174 seed = hash_value( w[0] ) + (hash_mix)( seed );
0175 seed = hash_value( w[1] ) + (hash_mix)( seed );
0176
0177 #endif
0178 return seed;
0179 }
0180 };
0181 #endif
0182
0183 template <typename T>
0184 typename enable_if_c<is_floating_point<T>::value, std::size_t>::type
0185 hash_value( T v )
0186 {
0187 return boost::intrusive::detail::hash_float_impl<T>::fn( v + 0 );
0188 }
0189
0190
0191
0192
0193
0194
0195
0196 template <class T> std::size_t hash_value( T* const& v )
0197 {
0198 std::size_t x = reinterpret_cast<std::size_t>( v );
0199 return hash_value( x + (x >> 3) );
0200 }
0201
0202
0203
0204
0205
0206
0207 #if !defined(BOOST_NO_CXX11_NULLPTR)
0208 template <typename T>
0209 typename enable_if_c<is_same<T, std::nullptr_t>::value, std::size_t>::type
0210 hash_value( T const &)
0211 {
0212 return (hash_value)( static_cast<void*>( nullptr ) );
0213 }
0214 #endif
0215
0216
0217
0218
0219
0220
0221
0222
0223 template<class T>
0224 struct internal_hash_functor;
0225
0226 template<class T, std::size_t N>
0227 inline std::size_t hash_value_dispatch( T const (&x)[ N ] )
0228 {
0229 std::size_t seed = 0;
0230 for(std::size_t i = 0; i != N; ++i){
0231 hash_combine_size_t(seed, internal_hash_functor<T>()(x[i]));
0232 }
0233 return seed;
0234 }
0235
0236 template<class T, std::size_t N>
0237 inline std::size_t hash_value_dispatch( T (&x)[ N ] )
0238 {
0239 std::size_t seed = 0;
0240 for (std::size_t i = 0; i != N; ++i) {
0241 hash_combine_size_t(seed, internal_hash_functor<T>()(x[i]));
0242 }
0243 return seed;
0244 }
0245
0246
0247
0248
0249
0250
0251 template <class T>
0252 inline typename detail::enable_if_c<detail::is_scalar<T>::value, std::size_t>::type
0253 hash_value_dispatch(const T &v)
0254 {
0255 return boost::intrusive::detail::hash_value(v);
0256 }
0257
0258
0259
0260
0261 template<class T>
0262 struct internal_hash_functor
0263 {
0264 inline std::size_t operator()(T const& val) const
0265 {
0266 return ::boost::intrusive::detail::hash_value_dispatch(val);
0267 }
0268 };
0269
0270 }
0271 }
0272 }
0273
0274 #include <boost/intrusive/detail/config_end.hpp>
0275
0276 #endif
0277