Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
2 // Copyright Daniel James 2005-2006. Use, modification, and distribution are
3 // subject to the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 // Based on Peter Dimov's proposal
7 // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
10 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved.
12 #if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
13 #define BOOST_FUNCTIONAL_HASH_HASH_HPP
15 #include <boost/functional/hash_fwd.hpp>
17 #include <boost/functional/detail/hash_float.hpp>
18 #include <boost/functional/detail/container_fwd.hpp>
21 #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
22 #include <boost/type_traits/is_pointer.hpp>
25 #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
26 #include <boost/type_traits/is_array.hpp>
29 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
30 #include <boost/type_traits/is_const.hpp>
35 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
36 // Borland complains about an ambiguous function overload
37 // when compiling boost::hash<bool>.
38 std::size_t hash_value(bool);
41 std::size_t hash_value(int);
42 std::size_t hash_value(unsigned int);
43 std::size_t hash_value(long);
44 std::size_t hash_value(unsigned long);
46 #if defined(BOOST_MSVC) && defined(_WIN64)
47 // On 64-bit windows std::size_t is a typedef for unsigned long long, which
48 // isn't due to be supported until Boost 1.35. So add support here.
49 // (Technically, Boost.Hash isn't actually documented as supporting
50 // std::size_t. But it would be pretty silly not to).
51 std::size_t hash_value(std::size_t);
54 #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
55 template <class T> std::size_t hash_value(T* const&);
57 template <class T> std::size_t hash_value(T*);
60 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
61 template< class T, unsigned N >
62 std::size_t hash_value(const T (&array)[N]);
64 template< class T, unsigned N >
65 std::size_t hash_value(T (&array)[N]);
68 std::size_t hash_value(float v);
69 std::size_t hash_value(double v);
70 std::size_t hash_value(long double v);
72 template <class Ch, class A>
73 std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
75 template <class A, class B>
76 std::size_t hash_value(std::pair<A, B> const&);
77 template <class T, class A>
78 std::size_t hash_value(std::vector<T, A> const&);
79 template <class T, class A>
80 std::size_t hash_value(std::list<T, A> const& v);
81 template <class T, class A>
82 std::size_t hash_value(std::deque<T, A> const& v);
83 template <class K, class C, class A>
84 std::size_t hash_value(std::set<K, C, A> const& v);
85 template <class K, class C, class A>
86 std::size_t hash_value(std::multiset<K, C, A> const& v);
87 template <class K, class T, class C, class A>
88 std::size_t hash_value(std::map<K, T, C, A> const& v);
89 template <class K, class T, class C, class A>
90 std::size_t hash_value(std::multimap<K, T, C, A> const& v);
94 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
95 inline std::size_t hash_value(bool v)
97 return static_cast<std::size_t>(v);
101 inline std::size_t hash_value(int v)
103 return static_cast<std::size_t>(v);
106 inline std::size_t hash_value(unsigned int v)
108 return static_cast<std::size_t>(v);
111 inline std::size_t hash_value(long v)
113 return static_cast<std::size_t>(v);
116 inline std::size_t hash_value(unsigned long v)
118 return static_cast<std::size_t>(v);
121 #if defined(_M_X64) && defined(_WIN64)
122 inline std::size_t hash_value(long long v)
127 inline std::size_t hash_value(unsigned long long v)
133 // Implementation by Alberto Barbati and Dave Harris.
134 #if !BOOST_WORKAROUND(__DMC__, <= 0x848)
135 template <class T> std::size_t hash_value(T* const& v)
137 template <class T> std::size_t hash_value(T* v)
140 std::size_t x = static_cast<std::size_t>(
141 reinterpret_cast<std::ptrdiff_t>(v));
145 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
147 inline void hash_combine(std::size_t& seed, T& v)
150 inline void hash_combine(std::size_t& seed, T const& v)
153 boost::hash<T> hasher;
154 seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
158 inline std::size_t hash_range(It first, It last)
160 std::size_t seed = 0;
162 for(; first != last; ++first)
164 hash_combine(seed, *first);
171 inline void hash_range(std::size_t& seed, It first, It last)
173 for(; first != last; ++first)
175 hash_combine(seed, *first);
179 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
181 inline std::size_t hash_range(T* first, T* last)
183 std::size_t seed = 0;
185 for(; first != last; ++first)
187 boost::hash<T> hasher;
188 seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
195 inline void hash_range(std::size_t& seed, T* first, T* last)
197 for(; first != last; ++first)
199 boost::hash<T> hasher;
200 seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
205 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
206 template< class T, unsigned N >
207 inline std::size_t hash_value(const T (&array)[N])
209 return hash_range(array, array + N);
212 template< class T, unsigned N >
213 inline std::size_t hash_value(T (&array)[N])
215 return hash_range(array, array + N);
219 template <class Ch, class A>
220 inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
222 return hash_range(v.begin(), v.end());
225 inline std::size_t hash_value(float v)
227 return boost::hash_detail::float_hash_value(v);
230 inline std::size_t hash_value(double v)
232 return boost::hash_detail::float_hash_value(v);
235 #ifndef __SYMBIAN32__ //long double not supported
236 inline std::size_t hash_value(long double v)
238 return boost::hash_detail::float_hash_value(v);
241 template <class A, class B>
242 std::size_t hash_value(std::pair<A, B> const& v)
244 std::size_t seed = 0;
245 hash_combine(seed, v.first);
246 hash_combine(seed, v.second);
250 template <class T, class A>
251 std::size_t hash_value(std::vector<T, A> const& v)
253 return hash_range(v.begin(), v.end());
256 template <class T, class A>
257 std::size_t hash_value(std::list<T, A> const& v)
259 return hash_range(v.begin(), v.end());
262 template <class T, class A>
263 std::size_t hash_value(std::deque<T, A> const& v)
265 return hash_range(v.begin(), v.end());
268 template <class K, class C, class A>
269 std::size_t hash_value(std::set<K, C, A> const& v)
271 return hash_range(v.begin(), v.end());
274 template <class K, class C, class A>
275 std::size_t hash_value(std::multiset<K, C, A> const& v)
277 return hash_range(v.begin(), v.end());
280 template <class K, class T, class C, class A>
281 std::size_t hash_value(std::map<K, T, C, A> const& v)
283 return hash_range(v.begin(), v.end());
286 template <class K, class T, class C, class A>
287 std::size_t hash_value(std::multimap<K, T, C, A> const& v)
289 return hash_range(v.begin(), v.end());
296 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
297 #define BOOST_HASH_SPECIALIZE(type) \
298 template <> struct hash<type> \
299 : public std::unary_function<type, std::size_t> \
301 std::size_t operator()(type v) const \
303 return boost::hash_value(v); \
307 #define BOOST_HASH_SPECIALIZE_REF(type) \
308 template <> struct hash<type> \
309 : public std::unary_function<type, std::size_t> \
311 std::size_t operator()(type const& v) const \
313 return boost::hash_value(v); \
317 #define BOOST_HASH_SPECIALIZE(type) \
318 template <> struct hash<type> \
319 : public std::unary_function<type, std::size_t> \
321 std::size_t operator()(type v) const \
323 return boost::hash_value(v); \
327 template <> struct hash<const type> \
328 : public std::unary_function<const type, std::size_t> \
330 std::size_t operator()(const type v) const \
332 return boost::hash_value(v); \
336 #define BOOST_HASH_SPECIALIZE_REF(type) \
337 template <> struct hash<type> \
338 : public std::unary_function<type, std::size_t> \
340 std::size_t operator()(type const& v) const \
342 return boost::hash_value(v); \
346 template <> struct hash<const type> \
347 : public std::unary_function<const type, std::size_t> \
349 std::size_t operator()(type const& v) const \
351 return boost::hash_value(v); \
356 BOOST_HASH_SPECIALIZE(bool)
357 BOOST_HASH_SPECIALIZE(char)
358 BOOST_HASH_SPECIALIZE(signed char)
359 BOOST_HASH_SPECIALIZE(unsigned char)
360 #if !defined(BOOST_NO_INTRINSIC_WCHAR_T) || defined(__SYMBIAN32__)
361 BOOST_HASH_SPECIALIZE(wchar_t)
363 BOOST_HASH_SPECIALIZE(short)
364 BOOST_HASH_SPECIALIZE(unsigned short)
365 BOOST_HASH_SPECIALIZE(int)
366 BOOST_HASH_SPECIALIZE(unsigned int)
367 BOOST_HASH_SPECIALIZE(long)
368 BOOST_HASH_SPECIALIZE(unsigned long)
370 BOOST_HASH_SPECIALIZE(float)
371 BOOST_HASH_SPECIALIZE(double)
372 BOOST_HASH_SPECIALIZE(long double)
374 BOOST_HASH_SPECIALIZE_REF(std::string)
375 #if !defined(BOOST_NO_STD_WSTRING)
376 BOOST_HASH_SPECIALIZE_REF(std::wstring)
379 #undef BOOST_HASH_SPECIALIZE
380 #undef BOOST_HASH_SPECIALIZE_REF
382 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
385 : public std::unary_function<T*, std::size_t>
387 std::size_t operator()(T* v) const \
389 return boost::hash_value(v); \
393 namespace hash_detail
395 template <bool IsPointer>
399 struct hash_impl<true>
403 : public std::unary_function<T, std::size_t>
405 std::size_t operator()(T val) const
407 return boost::hash_value(val);
413 template <class T> struct hash
414 : public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
415 ::BOOST_NESTED_TEMPLATE inner<T>
421 #endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
423 ////////////////////////////////////////////////////////////////////////////////
425 #if !defined(BOOST_HASH_NO_EXTENSIONS) \
426 && !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
427 #define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
432 #if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
433 namespace hash_detail
435 template <bool IsArray>
436 struct call_hash_impl
441 static std::size_t call(T const& v)
443 using namespace boost;
444 return hash_value(v);
450 struct call_hash_impl<true>
452 template <class Array>
455 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
456 static std::size_t call(Array const& v)
458 static std::size_t call(Array& v)
461 const int size = sizeof(v) / sizeof(*v);
462 return boost::hash_range(v, v + size);
469 : public call_hash_impl<boost::is_array<T>::value>
470 ::BOOST_NESTED_TEMPLATE inner<T>
474 #endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
476 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
478 template <class T> struct hash
479 : std::unary_function<T, std::size_t>
481 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
482 std::size_t operator()(T const& val) const
484 return hash_value(val);
487 std::size_t operator()(T const& val) const
489 return hash_detail::call_hash<T>::call(val);
494 #if BOOST_WORKAROUND(__DMC__, <= 0x848)
495 template <class T, unsigned int n> struct hash<T[n]>
496 : std::unary_function<T[n], std::size_t>
498 std::size_t operator()(const T* val) const
500 return boost::hash_range(val, val+n);
505 #else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
507 // On compilers without partial specialization, boost::hash<T>
508 // has already been declared to deal with pointers, so just
509 // need to supply the non-pointer version.
511 namespace hash_detail
513 template <bool IsPointer>
516 #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
519 struct hash_impl<false>
523 : std::unary_function<T, std::size_t>
525 #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
526 std::size_t operator()(T const& val) const
528 return hash_value(val);
531 std::size_t operator()(T const& val) const
533 return hash_detail::call_hash<T>::call(val);
539 #else // Visual C++ 6.5
541 // There's probably a more elegant way to Visual C++ 6.5 to work
542 // but I don't know what it is.
544 template <bool IsConst>
545 struct hash_impl_msvc
549 : public std::unary_function<T, std::size_t>
551 std::size_t operator()(T const& val) const
553 return hash_detail::call_hash<T const>::call(val);
556 std::size_t operator()(T& val) const
558 return hash_detail::call_hash<T>::call(val);
564 struct hash_impl_msvc<true>
568 : public std::unary_function<T, std::size_t>
570 std::size_t operator()(T& val) const
572 return hash_detail::call_hash<T>::call(val);
578 struct hash_impl_msvc2
579 : public hash_impl_msvc<boost::is_const<T>::value>
580 ::BOOST_NESTED_TEMPLATE inner<T> {};
583 struct hash_impl<false>
586 struct inner : public hash_impl_msvc2<T> {};
589 #endif // Visual C++ 6.5
591 #endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION