annotate DEPENDENCIES/generic/include/boost/functional/hash/hash.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1
Chris@101 2 // Copyright 2005-2014 Daniel James.
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 // Based on Peter Dimov's proposal
Chris@16 7 // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
Chris@16 8 // issue 6.18.
Chris@101 9 //
Chris@101 10 // This also contains public domain code from MurmurHash. From the
Chris@101 11 // MurmurHash header:
Chris@101 12
Chris@101 13 // MurmurHash3 was written by Austin Appleby, and is placed in the public
Chris@101 14 // domain. The author hereby disclaims copyright to this source code.
Chris@16 15
Chris@16 16 #if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
Chris@16 17 #define BOOST_FUNCTIONAL_HASH_HASH_HPP
Chris@16 18
Chris@16 19 #include <boost/functional/hash/hash_fwd.hpp>
Chris@16 20 #include <functional>
Chris@16 21 #include <boost/functional/hash/detail/hash_float.hpp>
Chris@16 22 #include <string>
Chris@16 23 #include <boost/limits.hpp>
Chris@16 24 #include <boost/type_traits/is_enum.hpp>
Chris@16 25 #include <boost/type_traits/is_integral.hpp>
Chris@16 26 #include <boost/utility/enable_if.hpp>
Chris@101 27 #include <boost/cstdint.hpp>
Chris@16 28
Chris@16 29 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 30 #include <boost/type_traits/is_pointer.hpp>
Chris@16 31 #endif
Chris@16 32
Chris@16 33 #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
Chris@16 34 #include <typeindex>
Chris@16 35 #endif
Chris@16 36
Chris@16 37 #if defined(BOOST_MSVC)
Chris@16 38 #pragma warning(push)
Chris@101 39
Chris@101 40 #if BOOST_MSVC >= 1400
Chris@16 41 #pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
Chris@16 42 // are always of range '0' to '4294967295'.
Chris@16 43 // Loop executes infinitely.
Chris@16 44 #endif
Chris@16 45
Chris@101 46 #endif
Chris@101 47
Chris@16 48 #if BOOST_WORKAROUND(__GNUC__, < 3) \
Chris@16 49 && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
Chris@16 50 #define BOOST_HASH_CHAR_TRAITS string_char_traits
Chris@16 51 #else
Chris@16 52 #define BOOST_HASH_CHAR_TRAITS char_traits
Chris@16 53 #endif
Chris@16 54
Chris@101 55 #if defined(_MSC_VER)
Chris@101 56 # define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
Chris@101 57 #else
Chris@101 58 # define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
Chris@101 59 #endif
Chris@101 60
Chris@16 61 namespace boost
Chris@16 62 {
Chris@16 63 namespace hash_detail
Chris@16 64 {
Chris@16 65 struct enable_hash_value { typedef std::size_t type; };
Chris@16 66
Chris@16 67 template <typename T> struct basic_numbers {};
Chris@16 68 template <typename T> struct long_numbers;
Chris@16 69 template <typename T> struct ulong_numbers;
Chris@16 70 template <typename T> struct float_numbers {};
Chris@16 71
Chris@16 72 template <> struct basic_numbers<bool> :
Chris@16 73 boost::hash_detail::enable_hash_value {};
Chris@16 74 template <> struct basic_numbers<char> :
Chris@16 75 boost::hash_detail::enable_hash_value {};
Chris@16 76 template <> struct basic_numbers<unsigned char> :
Chris@16 77 boost::hash_detail::enable_hash_value {};
Chris@16 78 template <> struct basic_numbers<signed char> :
Chris@16 79 boost::hash_detail::enable_hash_value {};
Chris@16 80 template <> struct basic_numbers<short> :
Chris@16 81 boost::hash_detail::enable_hash_value {};
Chris@16 82 template <> struct basic_numbers<unsigned short> :
Chris@16 83 boost::hash_detail::enable_hash_value {};
Chris@16 84 template <> struct basic_numbers<int> :
Chris@16 85 boost::hash_detail::enable_hash_value {};
Chris@16 86 template <> struct basic_numbers<unsigned int> :
Chris@16 87 boost::hash_detail::enable_hash_value {};
Chris@16 88 template <> struct basic_numbers<long> :
Chris@16 89 boost::hash_detail::enable_hash_value {};
Chris@16 90 template <> struct basic_numbers<unsigned long> :
Chris@16 91 boost::hash_detail::enable_hash_value {};
Chris@16 92
Chris@16 93 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
Chris@16 94 template <> struct basic_numbers<wchar_t> :
Chris@16 95 boost::hash_detail::enable_hash_value {};
Chris@16 96 #endif
Chris@16 97
Chris@16 98 // long_numbers is defined like this to allow for separate
Chris@16 99 // specialization for long_long and int128_type, in case
Chris@16 100 // they conflict.
Chris@16 101 template <typename T> struct long_numbers2 {};
Chris@16 102 template <typename T> struct ulong_numbers2 {};
Chris@16 103 template <typename T> struct long_numbers : long_numbers2<T> {};
Chris@16 104 template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
Chris@16 105
Chris@16 106 #if !defined(BOOST_NO_LONG_LONG)
Chris@16 107 template <> struct long_numbers<boost::long_long_type> :
Chris@16 108 boost::hash_detail::enable_hash_value {};
Chris@16 109 template <> struct ulong_numbers<boost::ulong_long_type> :
Chris@16 110 boost::hash_detail::enable_hash_value {};
Chris@16 111 #endif
Chris@16 112
Chris@16 113 #if defined(BOOST_HAS_INT128)
Chris@16 114 template <> struct long_numbers2<boost::int128_type> :
Chris@16 115 boost::hash_detail::enable_hash_value {};
Chris@16 116 template <> struct ulong_numbers2<boost::uint128_type> :
Chris@16 117 boost::hash_detail::enable_hash_value {};
Chris@16 118 #endif
Chris@16 119
Chris@16 120 template <> struct float_numbers<float> :
Chris@16 121 boost::hash_detail::enable_hash_value {};
Chris@16 122 template <> struct float_numbers<double> :
Chris@16 123 boost::hash_detail::enable_hash_value {};
Chris@16 124 template <> struct float_numbers<long double> :
Chris@16 125 boost::hash_detail::enable_hash_value {};
Chris@16 126 }
Chris@16 127
Chris@16 128 template <typename T>
Chris@16 129 typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
Chris@16 130 template <typename T>
Chris@16 131 typename boost::hash_detail::long_numbers<T>::type hash_value(T);
Chris@16 132 template <typename T>
Chris@16 133 typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
Chris@16 134
Chris@16 135 template <typename T>
Chris@16 136 typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
Chris@16 137 hash_value(T);
Chris@16 138
Chris@16 139 #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
Chris@16 140 template <class T> std::size_t hash_value(T* const&);
Chris@16 141 #else
Chris@16 142 template <class T> std::size_t hash_value(T*);
Chris@16 143 #endif
Chris@16 144
Chris@16 145 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
Chris@16 146 template< class T, unsigned N >
Chris@16 147 std::size_t hash_value(const T (&x)[N]);
Chris@16 148
Chris@16 149 template< class T, unsigned N >
Chris@16 150 std::size_t hash_value(T (&x)[N]);
Chris@16 151 #endif
Chris@16 152
Chris@16 153 template <class Ch, class A>
Chris@16 154 std::size_t hash_value(
Chris@16 155 std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
Chris@16 156
Chris@16 157 template <typename T>
Chris@16 158 typename boost::hash_detail::float_numbers<T>::type hash_value(T);
Chris@16 159
Chris@16 160 #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
Chris@16 161 std::size_t hash_value(std::type_index);
Chris@16 162 #endif
Chris@16 163
Chris@16 164 // Implementation
Chris@16 165
Chris@16 166 namespace hash_detail
Chris@16 167 {
Chris@16 168 template <class T>
Chris@16 169 inline std::size_t hash_value_signed(T val)
Chris@16 170 {
Chris@16 171 const int size_t_bits = std::numeric_limits<std::size_t>::digits;
Chris@16 172 // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
Chris@16 173 const int length = (std::numeric_limits<T>::digits - 1)
Chris@16 174 / size_t_bits;
Chris@16 175
Chris@16 176 std::size_t seed = 0;
Chris@16 177 T positive = val < 0 ? -1 - val : val;
Chris@16 178
Chris@16 179 // Hopefully, this loop can be unrolled.
Chris@16 180 for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
Chris@16 181 {
Chris@16 182 seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
Chris@16 183 }
Chris@16 184 seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
Chris@16 185
Chris@16 186 return seed;
Chris@16 187 }
Chris@16 188
Chris@16 189 template <class T>
Chris@16 190 inline std::size_t hash_value_unsigned(T val)
Chris@16 191 {
Chris@16 192 const int size_t_bits = std::numeric_limits<std::size_t>::digits;
Chris@16 193 // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
Chris@16 194 const int length = (std::numeric_limits<T>::digits - 1)
Chris@16 195 / size_t_bits;
Chris@16 196
Chris@16 197 std::size_t seed = 0;
Chris@16 198
Chris@16 199 // Hopefully, this loop can be unrolled.
Chris@16 200 for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
Chris@16 201 {
Chris@16 202 seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
Chris@16 203 }
Chris@16 204 seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
Chris@16 205
Chris@16 206 return seed;
Chris@16 207 }
Chris@101 208
Chris@101 209 template <typename SizeT>
Chris@101 210 inline void hash_combine_impl(SizeT& seed, SizeT value)
Chris@101 211 {
Chris@101 212 seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
Chris@101 213 }
Chris@101 214
Chris@101 215 template <typename SizeT>
Chris@101 216 inline void hash_combine_impl(boost::uint32_t& h1,
Chris@101 217 boost::uint32_t k1)
Chris@101 218 {
Chris@101 219 const uint32_t c1 = 0xcc9e2d51;
Chris@101 220 const uint32_t c2 = 0x1b873593;
Chris@101 221
Chris@101 222 k1 *= c1;
Chris@101 223 k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
Chris@101 224 k1 *= c2;
Chris@101 225
Chris@101 226 h1 ^= k1;
Chris@101 227 h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
Chris@101 228 h1 = h1*5+0xe6546b64;
Chris@101 229 }
Chris@101 230
Chris@101 231
Chris@101 232 // Don't define 64-bit hash combine on platforms with 64 bit integers,
Chris@101 233 // and also not for 32-bit gcc as it warns about the 64-bit constant.
Chris@101 234 #if !defined(BOOST_NO_INT64_T) && \
Chris@101 235 !(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
Chris@101 236
Chris@101 237 template <typename SizeT>
Chris@101 238 inline void hash_combine_impl(boost::uint64_t& h,
Chris@101 239 boost::uint64_t k)
Chris@101 240 {
Chris@101 241 const uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
Chris@101 242 const int r = 47;
Chris@101 243
Chris@101 244 k *= m;
Chris@101 245 k ^= k >> r;
Chris@101 246 k *= m;
Chris@101 247
Chris@101 248 h ^= k;
Chris@101 249 h *= m;
Chris@101 250 }
Chris@101 251
Chris@101 252 #endif // BOOST_NO_INT64_T
Chris@16 253 }
Chris@16 254
Chris@16 255 template <typename T>
Chris@16 256 typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
Chris@16 257 {
Chris@16 258 return static_cast<std::size_t>(v);
Chris@16 259 }
Chris@16 260
Chris@16 261 template <typename T>
Chris@16 262 typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
Chris@16 263 {
Chris@16 264 return hash_detail::hash_value_signed(v);
Chris@16 265 }
Chris@16 266
Chris@16 267 template <typename T>
Chris@16 268 typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
Chris@16 269 {
Chris@16 270 return hash_detail::hash_value_unsigned(v);
Chris@16 271 }
Chris@16 272
Chris@16 273 template <typename T>
Chris@16 274 typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
Chris@16 275 hash_value(T v)
Chris@16 276 {
Chris@16 277 return static_cast<std::size_t>(v);
Chris@16 278 }
Chris@16 279
Chris@16 280 // Implementation by Alberto Barbati and Dave Harris.
Chris@16 281 #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
Chris@16 282 template <class T> std::size_t hash_value(T* const& v)
Chris@16 283 #else
Chris@16 284 template <class T> std::size_t hash_value(T* v)
Chris@16 285 #endif
Chris@16 286 {
Chris@16 287 #if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
Chris@16 288 // for some reason ptrdiff_t on OpenVMS compiler with
Chris@16 289 // 64 bit is not 64 bit !!!
Chris@16 290 std::size_t x = static_cast<std::size_t>(
Chris@16 291 reinterpret_cast<long long int>(v));
Chris@16 292 #else
Chris@16 293 std::size_t x = static_cast<std::size_t>(
Chris@16 294 reinterpret_cast<std::ptrdiff_t>(v));
Chris@16 295 #endif
Chris@16 296 return x + (x >> 3);
Chris@16 297 }
Chris@16 298
Chris@16 299 #if defined(BOOST_MSVC)
Chris@16 300 #pragma warning(push)
Chris@16 301 #if BOOST_MSVC <= 1400
Chris@16 302 #pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
Chris@16 303 // 'unsigned int', possible loss of data
Chris@16 304 // A misguided attempt to detect 64-bit
Chris@16 305 // incompatability.
Chris@16 306 #endif
Chris@16 307 #endif
Chris@16 308
Chris@16 309 template <class T>
Chris@16 310 inline void hash_combine(std::size_t& seed, T const& v)
Chris@16 311 {
Chris@16 312 boost::hash<T> hasher;
Chris@101 313 return boost::hash_detail::hash_combine_impl(seed, hasher(v));
Chris@16 314 }
Chris@16 315
Chris@16 316 #if defined(BOOST_MSVC)
Chris@16 317 #pragma warning(pop)
Chris@16 318 #endif
Chris@16 319
Chris@16 320 template <class It>
Chris@16 321 inline std::size_t hash_range(It first, It last)
Chris@16 322 {
Chris@16 323 std::size_t seed = 0;
Chris@16 324
Chris@16 325 for(; first != last; ++first)
Chris@16 326 {
Chris@16 327 hash_combine(seed, *first);
Chris@16 328 }
Chris@16 329
Chris@16 330 return seed;
Chris@16 331 }
Chris@16 332
Chris@16 333 template <class It>
Chris@16 334 inline void hash_range(std::size_t& seed, It first, It last)
Chris@16 335 {
Chris@16 336 for(; first != last; ++first)
Chris@16 337 {
Chris@16 338 hash_combine(seed, *first);
Chris@16 339 }
Chris@16 340 }
Chris@16 341
Chris@16 342 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
Chris@16 343 template <class T>
Chris@16 344 inline std::size_t hash_range(T* first, T* last)
Chris@16 345 {
Chris@16 346 std::size_t seed = 0;
Chris@16 347
Chris@16 348 for(; first != last; ++first)
Chris@16 349 {
Chris@16 350 boost::hash<T> hasher;
Chris@16 351 seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
Chris@16 352 }
Chris@16 353
Chris@16 354 return seed;
Chris@16 355 }
Chris@16 356
Chris@16 357 template <class T>
Chris@16 358 inline void hash_range(std::size_t& seed, T* first, T* last)
Chris@16 359 {
Chris@16 360 for(; first != last; ++first)
Chris@16 361 {
Chris@16 362 boost::hash<T> hasher;
Chris@16 363 seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
Chris@16 364 }
Chris@16 365 }
Chris@16 366 #endif
Chris@16 367
Chris@16 368 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
Chris@16 369 template< class T, unsigned N >
Chris@16 370 inline std::size_t hash_value(const T (&x)[N])
Chris@16 371 {
Chris@16 372 return hash_range(x, x + N);
Chris@16 373 }
Chris@16 374
Chris@16 375 template< class T, unsigned N >
Chris@16 376 inline std::size_t hash_value(T (&x)[N])
Chris@16 377 {
Chris@16 378 return hash_range(x, x + N);
Chris@16 379 }
Chris@16 380 #endif
Chris@16 381
Chris@16 382 template <class Ch, class A>
Chris@16 383 inline std::size_t hash_value(
Chris@16 384 std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
Chris@16 385 {
Chris@16 386 return hash_range(v.begin(), v.end());
Chris@16 387 }
Chris@16 388
Chris@16 389 template <typename T>
Chris@16 390 typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
Chris@16 391 {
Chris@16 392 return boost::hash_detail::float_hash_value(v);
Chris@16 393 }
Chris@16 394
Chris@16 395 #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
Chris@16 396 inline std::size_t hash_value(std::type_index v)
Chris@16 397 {
Chris@16 398 return v.hash_code();
Chris@16 399 }
Chris@16 400 #endif
Chris@16 401
Chris@16 402 //
Chris@16 403 // boost::hash
Chris@16 404 //
Chris@16 405
Chris@16 406 // Define the specializations required by the standard. The general purpose
Chris@16 407 // boost::hash is defined later in extensions.hpp if
Chris@16 408 // BOOST_HASH_NO_EXTENSIONS is not defined.
Chris@16 409
Chris@16 410 // BOOST_HASH_SPECIALIZE - define a specialization for a type which is
Chris@16 411 // passed by copy.
Chris@16 412 //
Chris@16 413 // BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
Chris@16 414 // passed by copy.
Chris@16 415 //
Chris@16 416 // These are undefined later.
Chris@16 417
Chris@16 418 #define BOOST_HASH_SPECIALIZE(type) \
Chris@16 419 template <> struct hash<type> \
Chris@16 420 : public std::unary_function<type, std::size_t> \
Chris@16 421 { \
Chris@16 422 std::size_t operator()(type v) const \
Chris@16 423 { \
Chris@16 424 return boost::hash_value(v); \
Chris@16 425 } \
Chris@16 426 };
Chris@16 427
Chris@16 428 #define BOOST_HASH_SPECIALIZE_REF(type) \
Chris@16 429 template <> struct hash<type> \
Chris@16 430 : public std::unary_function<type, std::size_t> \
Chris@16 431 { \
Chris@16 432 std::size_t operator()(type const& v) const \
Chris@16 433 { \
Chris@16 434 return boost::hash_value(v); \
Chris@16 435 } \
Chris@16 436 };
Chris@16 437
Chris@16 438 BOOST_HASH_SPECIALIZE(bool)
Chris@16 439 BOOST_HASH_SPECIALIZE(char)
Chris@16 440 BOOST_HASH_SPECIALIZE(signed char)
Chris@16 441 BOOST_HASH_SPECIALIZE(unsigned char)
Chris@16 442 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
Chris@16 443 BOOST_HASH_SPECIALIZE(wchar_t)
Chris@16 444 #endif
Chris@16 445 BOOST_HASH_SPECIALIZE(short)
Chris@16 446 BOOST_HASH_SPECIALIZE(unsigned short)
Chris@16 447 BOOST_HASH_SPECIALIZE(int)
Chris@16 448 BOOST_HASH_SPECIALIZE(unsigned int)
Chris@16 449 BOOST_HASH_SPECIALIZE(long)
Chris@16 450 BOOST_HASH_SPECIALIZE(unsigned long)
Chris@16 451
Chris@16 452 BOOST_HASH_SPECIALIZE(float)
Chris@16 453 BOOST_HASH_SPECIALIZE(double)
Chris@16 454 BOOST_HASH_SPECIALIZE(long double)
Chris@16 455
Chris@16 456 BOOST_HASH_SPECIALIZE_REF(std::string)
Chris@16 457 #if !defined(BOOST_NO_STD_WSTRING)
Chris@16 458 BOOST_HASH_SPECIALIZE_REF(std::wstring)
Chris@16 459 #endif
Chris@16 460
Chris@16 461 #if !defined(BOOST_NO_LONG_LONG)
Chris@16 462 BOOST_HASH_SPECIALIZE(boost::long_long_type)
Chris@16 463 BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
Chris@16 464 #endif
Chris@16 465
Chris@16 466 #if defined(BOOST_HAS_INT128)
Chris@16 467 BOOST_HASH_SPECIALIZE(boost::int128_type)
Chris@16 468 BOOST_HASH_SPECIALIZE(boost::uint128_type)
Chris@16 469 #endif
Chris@16 470
Chris@16 471 #if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
Chris@16 472 BOOST_HASH_SPECIALIZE(std::type_index)
Chris@16 473 #endif
Chris@16 474
Chris@16 475 #undef BOOST_HASH_SPECIALIZE
Chris@16 476 #undef BOOST_HASH_SPECIALIZE_REF
Chris@16 477
Chris@16 478 // Specializing boost::hash for pointers.
Chris@16 479
Chris@16 480 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
Chris@16 481
Chris@16 482 template <class T>
Chris@16 483 struct hash<T*>
Chris@16 484 : public std::unary_function<T*, std::size_t>
Chris@16 485 {
Chris@16 486 std::size_t operator()(T* v) const
Chris@16 487 {
Chris@16 488 #if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
Chris@16 489 return boost::hash_value(v);
Chris@16 490 #else
Chris@16 491 std::size_t x = static_cast<std::size_t>(
Chris@16 492 reinterpret_cast<std::ptrdiff_t>(v));
Chris@16 493
Chris@16 494 return x + (x >> 3);
Chris@16 495 #endif
Chris@16 496 }
Chris@16 497 };
Chris@16 498
Chris@16 499 #else
Chris@16 500
Chris@16 501 // For compilers without partial specialization, we define a
Chris@16 502 // boost::hash for all remaining types. But hash_impl is only defined
Chris@16 503 // for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
Chris@16 504 // is defined there will still be a compile error for types not supported
Chris@16 505 // in the standard.
Chris@16 506
Chris@16 507 namespace hash_detail
Chris@16 508 {
Chris@16 509 template <bool IsPointer>
Chris@16 510 struct hash_impl;
Chris@16 511
Chris@16 512 template <>
Chris@16 513 struct hash_impl<true>
Chris@16 514 {
Chris@16 515 template <class T>
Chris@16 516 struct inner
Chris@16 517 : public std::unary_function<T, std::size_t>
Chris@16 518 {
Chris@16 519 std::size_t operator()(T val) const
Chris@16 520 {
Chris@16 521 #if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
Chris@16 522 return boost::hash_value(val);
Chris@16 523 #else
Chris@16 524 std::size_t x = static_cast<std::size_t>(
Chris@16 525 reinterpret_cast<std::ptrdiff_t>(val));
Chris@16 526
Chris@16 527 return x + (x >> 3);
Chris@16 528 #endif
Chris@16 529 }
Chris@16 530 };
Chris@16 531 };
Chris@16 532 }
Chris@16 533
Chris@16 534 template <class T> struct hash
Chris@16 535 : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
Chris@16 536 ::BOOST_NESTED_TEMPLATE inner<T>
Chris@16 537 {
Chris@16 538 };
Chris@16 539
Chris@16 540 #endif
Chris@16 541 }
Chris@16 542
Chris@16 543 #undef BOOST_HASH_CHAR_TRAITS
Chris@101 544 #undef BOOST_FUNCTIONAL_HASH_ROTL32
Chris@16 545
Chris@16 546 #if defined(BOOST_MSVC)
Chris@16 547 #pragma warning(pop)
Chris@16 548 #endif
Chris@16 549
Chris@16 550 #endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
Chris@16 551
Chris@16 552 // Include this outside of the include guards in case the file is included
Chris@16 553 // twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
Chris@16 554 // undefined.
Chris@16 555
Chris@16 556 #if !defined(BOOST_HASH_NO_EXTENSIONS) \
Chris@16 557 && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
Chris@16 558 #include <boost/functional/hash/extensions.hpp>
Chris@16 559 #endif