mirror of
https://github.com/boostorg/container_hash.git
synced 2026-03-07 06:24:04 +01:00
Compare commits
273 Commits
boost-1.34
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
427434a46f | ||
|
|
c381253e56 | ||
|
|
3c4f491886 | ||
|
|
09f197abf6 | ||
|
|
582671543b | ||
|
|
6157ad5267 | ||
|
|
7dbc8b593f | ||
|
|
b066a9c509 | ||
|
|
74603822f4 | ||
|
|
998f714f8f | ||
|
|
614feab582 | ||
|
|
999c2d5963 | ||
|
|
10c83e95d9 | ||
|
|
734eb87d2a | ||
|
|
af17fa46fb | ||
|
|
e26c102522 | ||
|
|
378007cf94 | ||
|
|
dea8d12a04 | ||
|
|
1870aa9534 | ||
|
|
0d6cee7e64 | ||
|
|
7d148af8d2 | ||
|
|
bb8ebafca1 | ||
|
|
7e162c4f03 | ||
|
|
061e0d9d6d | ||
|
|
e5f3356742 | ||
|
|
9721f9c764 | ||
|
|
8a8ab9ec70 | ||
|
|
13a86a7a26 | ||
|
|
0e0906b0a4 | ||
|
|
67ad8c2151 | ||
|
|
be4292842d | ||
|
|
473b1da8de | ||
|
|
8afae2e762 | ||
|
|
03380087a9 | ||
|
|
9dcc33ab1b | ||
|
|
7f7ecfc717 | ||
|
|
dfd48ef498 | ||
|
|
a2756e75e8 | ||
|
|
acf1f3bc48 | ||
|
|
853a713cf2 | ||
|
|
7b2f73c225 | ||
|
|
eec47991f9 | ||
|
|
f1de575546 | ||
|
|
05f16beaf0 | ||
|
|
9119b2646b | ||
|
|
0757aea7cb | ||
|
|
92fe67f714 | ||
|
|
5ebe3ad87d | ||
|
|
411ac66581 | ||
|
|
af3a31090c | ||
|
|
806abd0ddf | ||
|
|
8ef04ed807 | ||
|
|
6be66ba092 | ||
|
|
0d4c55854b | ||
|
|
8bc410f571 | ||
|
|
68f0d9bc6b | ||
|
|
5611f4238e | ||
|
|
963d06acb8 | ||
|
|
f3229da836 | ||
|
|
441cea413d | ||
|
|
4f3265079d | ||
|
|
98953a28c7 | ||
|
|
c3d01123fa | ||
|
|
f98a942e2e | ||
|
|
a6f8c51afb | ||
|
|
eb040cb89b | ||
|
|
d92209d725 | ||
|
|
56293f4313 | ||
|
|
335930c652 | ||
|
|
da096ddf8c | ||
|
|
8c0e9a2b09 | ||
|
|
664522596f | ||
|
|
ce885af9b0 | ||
|
|
9e641187c6 | ||
|
|
7dc95d044d | ||
|
|
ad614b3d5f | ||
|
|
ed598f865e | ||
|
|
482f038837 | ||
|
|
a2e947588d | ||
|
|
982b350d71 | ||
|
|
577054de93 | ||
|
|
fc3b3863b4 | ||
|
|
906f632706 | ||
|
|
bbfb6fd32c | ||
|
|
38d131c158 | ||
|
|
2553a5fbdc | ||
|
|
425de7d1dd | ||
|
|
f544265741 | ||
|
|
733422d1b9 | ||
|
|
77f856e3cf | ||
|
|
6544b32920 | ||
|
|
538b8fb95a | ||
|
|
e042170fb9 | ||
|
|
316b1aa9f0 | ||
|
|
0ba3e9b282 | ||
|
|
98f0f11423 | ||
|
|
6e37c616db | ||
|
|
5f10c2bb7e | ||
|
|
6d7a55a4f7 | ||
|
|
0ed492ba18 | ||
|
|
2734e22b50 | ||
|
|
9938fad017 | ||
|
|
4787563f96 | ||
|
|
78eeabaeb2 | ||
|
|
3882189584 | ||
|
|
079f8025b3 | ||
|
|
b43c9fa145 | ||
|
|
b0ceeca154 | ||
|
|
d8bfb81914 | ||
|
|
9958072d2a | ||
|
|
99c6e89390 | ||
|
|
3ee9d7d507 | ||
|
|
e75f94f71d | ||
|
|
5db98a2dda | ||
|
|
07b565143f | ||
|
|
d8980c3f09 | ||
|
|
83b052b784 | ||
|
|
c51bebf8a4 | ||
|
|
8b98036bb8 | ||
|
|
4774d24966 | ||
|
|
13f44653b5 | ||
|
|
e20c872440 | ||
|
|
600740e2ae | ||
|
|
52a964ae91 | ||
|
|
3d79c2f1e4 | ||
|
|
3cf1a67771 | ||
|
|
9cc8c20413 | ||
|
|
9f4a6a966e | ||
|
|
15d4153c37 | ||
|
|
326a338add | ||
|
|
b0459a20da | ||
|
|
909d0c9547 | ||
|
|
912aed0b57 | ||
|
|
e5d343faea | ||
|
|
3e320b7ae5 | ||
|
|
8bc6175fa0 | ||
|
|
6751e9cf47 | ||
|
|
004e4df2a2 | ||
|
|
411f559730 | ||
|
|
8a6aba46c7 | ||
|
|
65b103e812 | ||
|
|
c160428eff | ||
|
|
dda32a279a | ||
|
|
f1a8a0fde8 | ||
|
|
814476afa2 | ||
|
|
9ef99e556a | ||
|
|
2aff9855bb | ||
|
|
72cb0e7788 | ||
|
|
220c3a4e62 | ||
|
|
b0b7f17984 | ||
|
|
342284f4cf | ||
|
|
fe6449fea6 | ||
|
|
a3e434ec47 | ||
|
|
7c72c09288 | ||
|
|
45dfe7d9c5 | ||
|
|
2560590a2b | ||
|
|
c984bbb5f0 | ||
|
|
0480bcf503 | ||
|
|
6ae2b9da78 | ||
|
|
058c541da1 | ||
|
|
bf23bd7ed3 | ||
|
|
d9fd6a499d | ||
|
|
cec8e80658 | ||
|
|
3e24330335 | ||
|
|
3f1cbcd762 | ||
|
|
59f9787c11 | ||
|
|
8daec229d2 | ||
|
|
dd0632c991 | ||
|
|
707186737c | ||
|
|
b9917c8810 | ||
|
|
cc8672de3e | ||
|
|
4bb4957dc4 | ||
|
|
62226713a2 | ||
|
|
db3e4eee37 | ||
|
|
bd9c0e53d7 | ||
|
|
dd854f794b | ||
|
|
b1b9907efd | ||
|
|
55acb6d733 | ||
|
|
5b34fead70 | ||
|
|
1cc54e9d62 | ||
|
|
56714cf282 | ||
|
|
038a21dae6 | ||
|
|
110f23f6aa | ||
|
|
b2d85ea76b | ||
|
|
f0f19cd688 | ||
|
|
210ed051dd | ||
|
|
06b83dbce0 | ||
|
|
b0d0ec44ec | ||
|
|
035b91bdcd | ||
|
|
571d7bfd25 | ||
|
|
793b9f5eeb | ||
|
|
558f92f421 | ||
|
|
1d34150bb9 | ||
|
|
45d409c405 | ||
|
|
2e6da0ab6d | ||
|
|
74a03d1655 | ||
|
|
a93b6e3fea | ||
|
|
d83e6aef2b | ||
|
|
81a2c42496 | ||
|
|
1df7ab54e3 | ||
|
|
5194d14c25 | ||
|
|
cc8d3636e8 | ||
|
|
423d71ae31 | ||
|
|
d3719996d2 | ||
|
|
ce6543623e | ||
|
|
26dc8abf25 | ||
|
|
f637c9e8ce | ||
|
|
59f532cc68 | ||
|
|
d756415eb3 | ||
|
|
ee28cdbcd5 | ||
|
|
3b30bda727 | ||
|
|
48c2728dd5 | ||
|
|
58285d414e | ||
|
|
90c422e846 | ||
|
|
db8825c7d1 | ||
|
|
9211fcba2e | ||
|
|
f15ea62785 | ||
|
|
bd102b0479 | ||
|
|
2ae3f472c1 | ||
|
|
33643fd6b3 | ||
|
|
aa7a824c6d | ||
|
|
567290d703 | ||
|
|
59064fed23 | ||
|
|
8d271da155 | ||
|
|
4e59762347 | ||
|
|
fbe0c3eeca | ||
|
|
0728daf92d | ||
|
|
d25ca5a376 | ||
|
|
15d9d535a9 | ||
|
|
27d2c57873 | ||
|
|
4ef5d0d98c | ||
|
|
e8970a08f3 | ||
|
|
891112a42f | ||
|
|
718fda8635 | ||
|
|
f31d7a7613 | ||
|
|
586c98cb7e | ||
|
|
74fc58cd13 | ||
|
|
e5b0a03e57 | ||
|
|
7438a90198 | ||
|
|
555fefae20 | ||
|
|
87a3e4f6f0 | ||
|
|
3ebd297644 | ||
|
|
c2d8b6c92e | ||
|
|
8aa2b19669 | ||
|
|
64da418fb2 | ||
|
|
a60b7d12f3 | ||
|
|
a08d42c10f | ||
|
|
9430503530 | ||
|
|
59643536dd | ||
|
|
b165afccaa | ||
|
|
64d717dcf5 | ||
|
|
311bf0d6c5 | ||
|
|
46654045d7 | ||
|
|
572d82713b | ||
|
|
4283c17309 | ||
|
|
d8c636ef9f | ||
|
|
82cca89876 | ||
|
|
ba4c0abf5d | ||
|
|
6ee55d99e7 | ||
|
|
a4b51721db | ||
|
|
cae86235d5 | ||
|
|
81af8bc170 | ||
|
|
59adb10b3a | ||
|
|
3b29b95b8e | ||
|
|
855ebe6b69 | ||
|
|
e4b7765da1 | ||
|
|
f3e6c4e96a | ||
|
|
58aec4566a | ||
|
|
9cbe356636 | ||
|
|
906f897e4a | ||
|
|
32d68419ec | ||
|
|
6caa46edab | ||
|
|
c81a6bee4e |
@@ -1,9 +1,19 @@
|
||||
|
||||
# Copyright Daniel James 2005. Use, modification, and distribution are
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# Copyright 2005-2008 Daniel James.
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
using boostbook ;
|
||||
using quickbook ;
|
||||
|
||||
xml hash : hash.qbk ;
|
||||
boostbook standalone : hash ;
|
||||
boostbook standalone : hash :
|
||||
<xsl:param>boost.root=../../../..
|
||||
|
||||
<xsl:param>chunk.first.sections=1
|
||||
<xsl:param>chunk.section.depth=2
|
||||
<xsl:param>generate.section.toc.level=2
|
||||
<xsl:param>toc.section.depth=1
|
||||
<xsl:param>toc.max.depth=1
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html
|
||||
;
|
||||
|
||||
159
doc/changes.qbk
159
doc/changes.qbk
@@ -1,27 +1,172 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
|
||||
|
||||
[section:changes Change Log]
|
||||
|
||||
[h2 Boost 1.33.0]
|
||||
|
||||
* Initial Release
|
||||
|
||||
[h2 Changes in Boost 1.33.1]
|
||||
[h2 Boost 1.33.1]
|
||||
|
||||
* Fixed the points example, as pointed out by 沈慧峰.
|
||||
|
||||
[h2 Changes in Boost 1.34.0]
|
||||
[h2 Boost 1.34.0]
|
||||
|
||||
* Use declarations for standard classes, so that the library
|
||||
doesn't need to include all of their headers
|
||||
* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header,
|
||||
<[headerref boost/functional/hash.hpp]> is used.
|
||||
* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which
|
||||
disables the extensions to TR1
|
||||
disables the extensions to TR1.
|
||||
|
||||
* Minor improvements to the hash functions for floating point numbers.
|
||||
* Update the portable example to hopefully be more generally portable.
|
||||
|
||||
[h2 Future Developments]
|
||||
[h2 Boost 1.34.1]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/952 Ticket 952]:
|
||||
Suppress incorrect 64-bit warning on Visual C++.
|
||||
|
||||
[h2 Boost 1.35.0]
|
||||
|
||||
* Support for `long long`, `std::complex`.
|
||||
* Improved algorithm for hashing floating point numbers:
|
||||
* Improved portablity, as described by Daniel Krügler in
|
||||
[@http://lists.boost.org/boost-users/2005/08/13418.php
|
||||
a post to the boost users list].
|
||||
* Fits more information into each combine loop, which can reduce the
|
||||
the number of times combine is called and hopefully give a better
|
||||
quality hash function.
|
||||
* Improved the algorithm for hashing floating point numbers.
|
||||
* On Cygwin use a binary hash function for floating point numbers, as
|
||||
Cygwin doesn't have decent floating point functions for `long double`.
|
||||
* Never uses `fpclass` which doesn't support `long double`.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
|
||||
Removed unnecessary use of `errno`.
|
||||
* Explicitly overload for more built in types.
|
||||
* Minor improvements to the documentation.
|
||||
* A few bug and warning fixes:
|
||||
* [@http://svn.boost.org/trac/boost/ticket/1509 Ticket 1509]:
|
||||
Suppress another Visual C++ warning.
|
||||
* Some workarounds for the Sun compilers.
|
||||
|
||||
[h2 Boost 1.36.0]
|
||||
|
||||
* Stop using OpenBSD's dodgy `std::numeric_limits`.
|
||||
* Using the boost typedefs for `long long` and `unsigned long long`.
|
||||
* Move the extensions into their own header.
|
||||
|
||||
[h2 Boost 1.37.0]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/2264 Ticket 2264]:
|
||||
In Visual C++, always use C99 float functions for `long double` and `float` as
|
||||
the C++ overloads aren't always availables.
|
||||
|
||||
[h2 Boost 1.38.0]
|
||||
|
||||
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
|
||||
will be removed in a future version of Boost.
|
||||
* Moved detail headers out of `boost/functional/detail`, since they are part of
|
||||
functional/hash, not functional. `boost/functional/detail/container_fwd.hpp`
|
||||
has been moved to `boost/detail/container_fwd.hpp` as it's used outside of
|
||||
this library, the others have been moved to `boost/functional/hash/detail`.
|
||||
|
||||
[h2 Boost 1.39.0]
|
||||
|
||||
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
|
||||
forwarding header in the old location. You should still use the old location,
|
||||
the new location is mainly for implementation and possible modularization.
|
||||
* [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated
|
||||
headers.
|
||||
* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
|
||||
for vxworks.
|
||||
|
||||
[h2 Boost 1.40.0]
|
||||
|
||||
* Automatically configure the float functions using template metaprogramming
|
||||
instead of trying to configure every possibility manually.
|
||||
* Workaround for when STLport doesn't support long double.
|
||||
|
||||
[h2 Boost 1.42.0]
|
||||
|
||||
* Reduce the number of warnings for Visual C++ warning level 4.
|
||||
* Some code formatting changes to fit lines into 80 characters.
|
||||
* Rename an internal namespace.
|
||||
|
||||
[h2 Boost 1.43.0]
|
||||
|
||||
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
|
||||
Don't foward declare containers when using gcc's parallel library,
|
||||
allow user to stop forward declaration by defining the
|
||||
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
|
||||
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
|
||||
Avoid hashing 0.5 and 0 to the same number.
|
||||
* Stop using deprecated `BOOST_HAS_*` macros.
|
||||
|
||||
[h2 Boost 1.44.0]
|
||||
|
||||
* Add option to prevent implicit conversions when calling `hash_value` by
|
||||
defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
|
||||
for a type that does not have `hash_value` declared but does have
|
||||
an implicit conversion to a type that does, it would use that
|
||||
implicit conversion to hash it. Which can sometimes go very wrong,
|
||||
e.g. using a conversion to bool and only hashing to 2 possible
|
||||
values. Since fixing this is a breaking change and was only
|
||||
approached quite late in the release cycle with little discussion
|
||||
it's opt-in for now. This, or something like it, will become the
|
||||
default in a future version.
|
||||
|
||||
[h2 Boost 1.46.0]
|
||||
|
||||
* Avoid warning due with gcc's `-Wconversion` flag.
|
||||
|
||||
[h2 Boost 1.50.0]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
|
||||
Avoid gcc's `-Wfloat-equal` warning.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
|
||||
Support `std::array` and `std::tuple` when available.
|
||||
* Add deprecation warning to the long deprecated
|
||||
`boost/functional/detail/container_fwd.hpp`.
|
||||
|
||||
[h2 Boost 1.51.0]
|
||||
|
||||
* Support the standard smart pointers.
|
||||
* `hash_value` now implemented using SFINAE to avoid implicit casts to built
|
||||
in types when calling it.
|
||||
* Updated to use the new config macros.
|
||||
|
||||
[h2 Boost 1.52.0]
|
||||
|
||||
* Restore `enum` support, which was accidentally removed in the last version.
|
||||
* New floating point hasher - will hash the binary representation on more
|
||||
platforms, which should be faster.
|
||||
|
||||
[h2 Boost 1.53.0]
|
||||
|
||||
* Add support for `boost::int128_type` and `boost::uint128_type` where
|
||||
available - currently only `__int128` and `unsigned __int128` on some
|
||||
versions of gcc.
|
||||
* On platforms that are known to have the standard floating point functions,
|
||||
don't use automatic detection - which can break if there are ambiguous
|
||||
overloads.
|
||||
* Fix undefined behaviour when using the binary float hash (Thomas Heller).
|
||||
|
||||
[h2 Boost 1.54.0]
|
||||
|
||||
* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]:
|
||||
Fixed a typo.
|
||||
|
||||
[h2 Boost 1.55.0]
|
||||
|
||||
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9
|
||||
([ticket 8822]).
|
||||
* Suppress Visual C++ infinite loop warning ([ticket 8568]).
|
||||
|
||||
* A more portable hash function, as described by Daniel Krügler in
|
||||
[@http://lists.boost.org/boost-users/2005/08/13418.php a post to the boost users list].
|
||||
* Implement `hash_value` for more classes, including `std::complex`.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:disable Disabling The Extensions]
|
||||
|
||||
While [classref boost::hash]'s extensions are generally useful, you might want
|
||||
|
||||
13
doc/hash.qbk
13
doc/hash.qbk
@@ -1,24 +1,29 @@
|
||||
[library Boost.Functional/Hash
|
||||
[quickbook 1.3]
|
||||
[quickbook 1.5]
|
||||
[authors [James, Daniel]]
|
||||
[copyright 2005 2006 Daniel James]
|
||||
[copyright 2005 2006 2007 2008 Daniel James]
|
||||
[purpose A TR1 hash function object that can be extended to hash user
|
||||
defined types]
|
||||
[category higher-order]
|
||||
[id hash]
|
||||
[dirname hash]
|
||||
[dirname functional/hash]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
[@http://www.boost.org/LICENSE_1_0.txt]
|
||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||
]
|
||||
]
|
||||
|
||||
[def __issues__
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
|
||||
Library Extension Technical Report Issues List]]
|
||||
|
||||
[include:hash intro.qbk]
|
||||
[include:hash tutorial.qbk]
|
||||
[include:hash portability.qbk]
|
||||
[include:hash disable.qbk]
|
||||
[include:hash changes.qbk]
|
||||
[include:hash rationale.qbk]
|
||||
[xinclude ref.xml]
|
||||
[include:hash links.qbk]
|
||||
[include:hash thanks.qbk]
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:intro Introduction]
|
||||
|
||||
[def __tr1__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf
|
||||
C++ Standard Library Technical Report]]
|
||||
[def __tr1-short__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf
|
||||
Technical Report]]
|
||||
[def __multi-index__ [@../../libs/multi_index/doc/index.html
|
||||
[def __tr1-full__
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
|
||||
Draft Technical Report on C++ Library Extensions]]
|
||||
[def __tr1__
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
|
||||
TR1]]
|
||||
[def __unordered__ [link unordered Boost.Unordered]]
|
||||
[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
|
||||
[def __multi-index__ [@boost:/libs/multi_index/doc/index.html
|
||||
Boost Multi-Index Containers Library]]
|
||||
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
|
||||
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
||||
Boost.MultiIndex]]
|
||||
[def __issues__ [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
Library Extension Technical Report Issues List]]
|
||||
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
|
||||
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
|
||||
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
|
||||
|
||||
[classref boost::hash] is an implementation of the __hash-function__ object
|
||||
specified by the __tr1-short__. It is intended for use as the default hash function
|
||||
for unordered associative containers, and the __multi-index__'s hash indexes.
|
||||
specified by the __tr1-full__ (TR1). It is the default hash function for
|
||||
__unordered__, __intrusive__'s unordered associative containers, and
|
||||
__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
|
||||
|
||||
As it is compliant with the __tr1-short__, it will work with:
|
||||
As it is compliant with __tr1__, it will work with:
|
||||
|
||||
* integers
|
||||
* floats
|
||||
@@ -25,12 +34,19 @@ As it is compliant with the __tr1-short__, it will work with:
|
||||
* strings
|
||||
|
||||
It also implements the extension proposed by Peter Dimov in issue 6.18 of the
|
||||
__issues__, this adds support for:
|
||||
__issues__ (page 63), this adds support for:
|
||||
|
||||
* arrays
|
||||
* `std::pair`
|
||||
* the standard containers.
|
||||
* extending [classref boost::hash] for custom types.
|
||||
|
||||
[note
|
||||
This hash function is designed to be used in containers based on
|
||||
the STL and is not suitable as a general purpose hash function.
|
||||
For more details see the [link hash.rationale rationale].
|
||||
]
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:links Links]
|
||||
|
||||
[*A Proposal to Add Hash Tables to the Standard Library]\n
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]\n
|
||||
[*A Proposal to Add Hash Tables to the Standard Library]
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]
|
||||
The hash table proposal explains much of the design. The hash function object
|
||||
is discussed in Section D.
|
||||
|
||||
[*The C++ Standard Library Technical Report.]\n
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]\n
|
||||
[*The C++ Standard Library Technical Report.]
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]
|
||||
Contains the hash function specification in section 6.3.2.
|
||||
|
||||
[*Library Extension Technical Report Issues List.]\n
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]\n
|
||||
[*Library Extension Technical Report Issues List.]
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]
|
||||
The library implements the extension described in Issue 6.18, pages 63-67.
|
||||
|
||||
[*Methods for Identifying Versioned and Plagiarised Documents]\n
|
||||
Timothy C. Hoad, Justin Zobel\n
|
||||
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]\n
|
||||
[*Methods for Identifying Versioned and Plagiarised Documents]
|
||||
Timothy C. Hoad, Justin Zobel
|
||||
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]
|
||||
Contains the hash function that [funcref boost::hash_combine] is based on.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:portability Portability]
|
||||
|
||||
[def __boost_hash__ [classref boost::hash]]
|
||||
@@ -5,7 +10,7 @@
|
||||
__boost_hash__ is written to be as portable as possible, but unfortunately, several
|
||||
older compilers don't support argument dependent lookup (ADL) - the mechanism
|
||||
used for customisation. On those compilers custom overloads for `hash_value`
|
||||
need to be declared in the boost namespace.
|
||||
needs to be declared in the boost namespace.
|
||||
|
||||
On a strictly standards compliant compiler, an overload defined in the
|
||||
boost namespace won't be found when __boost_hash__ is instantiated,
|
||||
@@ -83,18 +88,6 @@ boost namespace:
|
||||
}
|
||||
|
||||
Full code for this example is at
|
||||
[@../../libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
|
||||
|
||||
[h2 Other Issues]
|
||||
|
||||
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
|
||||
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
|
||||
support built in arrays so this shouldn't be a problem in most cases.
|
||||
|
||||
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
|
||||
|
||||
When using GCC on Solaris, `boost::hash_value(long double)` treats
|
||||
`long double`s as `double`s - so the hash function doesn't take into account the
|
||||
full range of values.
|
||||
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
|
||||
|
||||
[endsect]
|
||||
|
||||
50
doc/rationale.qbk
Normal file
50
doc/rationale.qbk
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
[/ Copyright 2011 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:rationale Rationale]
|
||||
|
||||
The rationale can be found in the original design
|
||||
[footnote issue 6.18 of the __issues__ (page 63)].
|
||||
|
||||
[heading Quality of the hash function]
|
||||
|
||||
Many hash functions strive to have little correlation between the input
|
||||
and output values. They attempt to uniformally distribute the output
|
||||
values for very similar inputs. This hash function makes no such
|
||||
attempt. In fact, for integers, the result of the hash function is often
|
||||
just the input value. So similar but different input values will often
|
||||
result in similar but different output values.
|
||||
This means that it is not appropriate as a general hash function. For
|
||||
example, a hash table may discard bits from the hash function resulting
|
||||
in likely collisions, or might have poor collision resolution when hash
|
||||
values are clustered together. In such cases this hash function will
|
||||
preform poorly.
|
||||
|
||||
But the standard has no such requirement for the hash function,
|
||||
it just requires that the hashes of two different values are unlikely
|
||||
to collide. Containers or algorithms
|
||||
designed to work with the standard hash function will have to be
|
||||
implemented to work well when the hash function's output is correlated
|
||||
to its input. Since they are paying that cost a higher quality hash function
|
||||
would be wasteful.
|
||||
|
||||
For other use cases, if you do need a higher quality hash function,
|
||||
then neither the standard hash function or `boost::hash` are appropriate.
|
||||
There are several options
|
||||
available. One is to use a second hash on the output of this hash
|
||||
function, such as [@http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||
Thomas Wang's hash function]. This this may not work as
|
||||
well as a hash algorithm tailored for the input.
|
||||
|
||||
For strings there are several fast, high quality hash functions
|
||||
available (for example [@http://code.google.com/p/smhasher/ MurmurHash3]
|
||||
and [@http://code.google.com/p/cityhash/ Google's CityHash]),
|
||||
although they tend to be more machine specific.
|
||||
These may also be appropriate for hashing a binary representation of
|
||||
your data - providing that all equal values have an equal
|
||||
representation, which is not always the case (e.g. for floating point
|
||||
values).
|
||||
|
||||
[endsect]
|
||||
597
doc/ref.xml
597
doc/ref.xml
@@ -1,9 +1,16 @@
|
||||
|
||||
<!--
|
||||
Copyright Daniel James 2005-2009
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<library-reference>
|
||||
<section id="hash.reference.specification">
|
||||
<para>For the full specification, see section 6.3 of the
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf">C++ Standard Library Technical Report</ulink>
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</ulink>
|
||||
and issue 6.18 of the
|
||||
<ulink url="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf">Library Extension Technical Report Issues List</ulink>.
|
||||
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
|
||||
</para>
|
||||
</section>
|
||||
<header name="boost/functional/hash.hpp">
|
||||
@@ -27,7 +34,7 @@
|
||||
<classname>std::unary_function<T, std::size_t></classname>
|
||||
</inherit>
|
||||
|
||||
<purpose>An STL compliant hash function object.</purpose>
|
||||
<purpose><simpara>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</simpara></purpose>
|
||||
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
@@ -48,6 +55,10 @@
|
||||
is defined. The specializations are still defined, so only the specializations
|
||||
required by TR1 are defined.
|
||||
</para>
|
||||
<para>
|
||||
Forward declared in
|
||||
<code><boost/functional/hash_fwd.hpp></code>
|
||||
</para>
|
||||
</notes>
|
||||
<throws><para>
|
||||
Only throws if
|
||||
@@ -68,7 +79,7 @@
|
||||
</parameter>
|
||||
<returns>
|
||||
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||
<para><functionname alt="boost::hash_value(bool)">hash_value</functionname>(val) in Boost.</para>
|
||||
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
@@ -254,6 +265,42 @@
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
<template-arg>long long</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>long long</paramtype>
|
||||
</parameter>
|
||||
<returns>
|
||||
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
<template-arg>unsigned long long</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>unsigned long long</paramtype>
|
||||
</parameter>
|
||||
<returns>
|
||||
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
@@ -266,7 +313,7 @@
|
||||
</parameter>
|
||||
<returns>
|
||||
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||
<para><functionname alt="boost::hash_value(float)">hash_value</functionname>(val) in Boost.</para>
|
||||
<para><functionname>hash_value</functionname>(val) in Boost.</para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
@@ -344,6 +391,50 @@
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
</template>
|
||||
<specialization>
|
||||
<template-arg>T*</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>T*</paramtype>
|
||||
</parameter>
|
||||
<returns>
|
||||
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
<template-arg>std::type_index</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>std::type_index</paramtype>
|
||||
</parameter>
|
||||
<returns>
|
||||
<para><code>val.hash_code()</code></para>
|
||||
</returns>
|
||||
<throws><para>Doesn't throw</para></throws>
|
||||
</method>
|
||||
<notes>
|
||||
<para>
|
||||
Only available if it's in your standard library and Boost.Config
|
||||
is aware of it.
|
||||
</para>
|
||||
</notes>
|
||||
</struct-specialization>
|
||||
|
||||
<free-function-group name="Support functions (Boost extension).">
|
||||
|
||||
<!--
|
||||
boost::hash_combine
|
||||
-->
|
||||
@@ -354,16 +445,20 @@
|
||||
</template>
|
||||
<type>void</type>
|
||||
<parameter name="seed"><paramtype>size_t &</paramtype></parameter>
|
||||
<parameter name="v"><paramtype>T const &</paramtype></parameter>
|
||||
<purpose>
|
||||
<parameter name="v"><paramtype>T const&</paramtype></parameter>
|
||||
<purpose><simpara>
|
||||
Called repeatedly to incrementally create a hash value from
|
||||
several variables.
|
||||
</purpose>
|
||||
</simpara></purpose>
|
||||
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);</programlisting></effects>
|
||||
<notes>
|
||||
<para><functionname>hash_value</functionname> is called without
|
||||
qualification, so that overloads can be found via ADL.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
<para>
|
||||
Forward declared in
|
||||
<code><boost/functional/hash_fwd.hpp></code>
|
||||
</para>
|
||||
</notes>
|
||||
<throws>
|
||||
Only throws if <functionname>hash_value</functionname>(T) throws.
|
||||
@@ -396,10 +491,10 @@
|
||||
<parameter name="last"><paramtype>It</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<purpose>
|
||||
<purpose><simpara>
|
||||
Calculate the combined hash value of the elements of an iterator
|
||||
range.
|
||||
</purpose>
|
||||
</simpara></purpose>
|
||||
<effects>
|
||||
<para>For the two argument overload:
|
||||
<programlisting>
|
||||
@@ -412,15 +507,14 @@ for(; first != last; ++first)
|
||||
|
||||
return seed;
|
||||
</programlisting>
|
||||
</para>For the three arguments overload:
|
||||
</para>
|
||||
<para>For the three arguments overload:</para>
|
||||
<programlisting>
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
<functionname>hash_combine</functionname>(seed, *first);
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
</para>
|
||||
</effects>
|
||||
<notes>
|
||||
<para>
|
||||
@@ -429,6 +523,10 @@ for(; first != last; ++first)
|
||||
container.
|
||||
</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
<para>
|
||||
Forward declared in
|
||||
<code><boost/functional/hash_fwd.hpp></code>
|
||||
</para>
|
||||
</notes>
|
||||
<throws><para>
|
||||
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
|
||||
@@ -438,26 +536,53 @@ for(; first != last; ++first)
|
||||
</para></throws>
|
||||
</overloaded-function>
|
||||
|
||||
</free-function-group>
|
||||
|
||||
<free-function-group name="Overloadable hash implementation (Boost extension).">
|
||||
|
||||
<!--
|
||||
boost::hash_value - integers
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<purpose>
|
||||
Implementation of a hash function for integers.
|
||||
</purpose>
|
||||
<purpose><simpara>
|
||||
Implementation of the hash function.
|
||||
</simpara></purpose>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call hash_value without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
<notes>
|
||||
<para>Overloads for other types supplied in other headers.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>bool</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>char</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>signed char</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>unsigned char</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>short</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>unsigned short</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
@@ -479,31 +604,15 @@ for(; first != last; ++first)
|
||||
<parameter name="val"><paramtype>unsigned long</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<returns>
|
||||
<code>val</code>
|
||||
</returns>
|
||||
</overloaded-function>
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>long long</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<!--
|
||||
boost::hash_value - floating point
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<purpose>
|
||||
Implementation of a hash function for floating point values.
|
||||
</purpose>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call hash_value without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
<notes>
|
||||
<para>Overloads for other types supplied in other headers.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>unsigned long long</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
@@ -520,70 +629,12 @@ for(; first != last; ++first)
|
||||
<parameter name="val"><paramtype>long double</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<returns>
|
||||
<para>
|
||||
An unspecified value, except that equal arguments shall yield the same
|
||||
result
|
||||
</para>
|
||||
</returns>
|
||||
</overloaded-function>
|
||||
|
||||
<!--
|
||||
boost::hash_value - pointers
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<purpose>
|
||||
Implementation of a hash function for pointers.
|
||||
</purpose>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call hash_value without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
<notes>
|
||||
<para>Overloads for other types supplied in other headers.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
|
||||
<signature>
|
||||
<template><template-type-parameter name="T"/></template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>T* const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<returns>
|
||||
<para>
|
||||
An unspecified value, except that equal arguments shall yield the same
|
||||
result
|
||||
</para>
|
||||
</returns>
|
||||
</overloaded-function>
|
||||
|
||||
<!--
|
||||
boost::hash_value - arrays
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<purpose>
|
||||
Implementation of a hash function for built in arrays.
|
||||
</purpose>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call hash_value without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
<notes>
|
||||
<para>Overloads for other types supplied in other headers.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
@@ -602,30 +653,6 @@ for(; first != last; ++first)
|
||||
<parameter><paramtype>const T (&val)[N]</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<returns><code>hash_range(val, val+N)</code></returns>
|
||||
</overloaded-function>
|
||||
|
||||
<!--
|
||||
boost::hash_value - string
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<purpose>
|
||||
Implementation of a hash function for <code>std::basic_string</code>.
|
||||
</purpose>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call hash_value without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
<notes>
|
||||
<para>Overloads for other types supplied in other headers.</para>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="Ch"/>
|
||||
@@ -636,118 +663,220 @@ for(; first != last; ++first)
|
||||
<paramtype>std::basic_string<Ch, std::char_traits<Ch>, A> const&</paramtype>
|
||||
</parameter>
|
||||
</signature>
|
||||
|
||||
<returns><code>hash_range(val.begin(), val.end())</code></returns>
|
||||
</overloaded-function>
|
||||
|
||||
<!--
|
||||
boost::hash_value - pairs
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="A"/>
|
||||
<template-type-parameter name="B"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::pair<A, B> const &</paramtype></parameter>
|
||||
<parameter name="val"><paramtype>std::pair<A, B> const&</paramtype></parameter>
|
||||
</signature>
|
||||
<effects><programlisting>
|
||||
size_t seed = 0;
|
||||
<functionname>hash_combine</functionname>(seed, val.first);
|
||||
<functionname>hash_combine</functionname>(seed, val.second);
|
||||
return seed;
|
||||
</programlisting></effects>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::vector<T, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::list<T, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::deque<T, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::set<K, C, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::multiset<K, C, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::map<K, T, C, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::multimap<K, T, C, A> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::complex<T> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::type_index</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-nontype-parameter name="N">
|
||||
<type>std::size_t</type>
|
||||
</template-nontype-parameter>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::array<T, N> const&</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T" pack="1"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::tuple<T...></paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<description><para>
|
||||
Generally shouldn't be called directly by users, instead they should use
|
||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||
or <functionname>boost::hash_combine</functionname> which
|
||||
call <code>hash_value</code> without namespace qualification so that overloads
|
||||
for custom types are found via ADL.
|
||||
</para></description>
|
||||
|
||||
<notes>
|
||||
<para>This is an extension to TR1</para>
|
||||
</notes>
|
||||
|
||||
<throws>
|
||||
Only throws if <code><functionname>hash_value</functionname>(A)</code>
|
||||
or <code><functionname>hash_value</functionname>(B)</code> throws.
|
||||
Only throws if a user supplied version of
|
||||
<code><functionname>hash_value</functionname></code>
|
||||
throws for an element of a container, or
|
||||
one of the types stored in a pair.
|
||||
</throws>
|
||||
<notes><para>This is an extension to TR1</para></notes>
|
||||
</overloaded-function>
|
||||
|
||||
<!--
|
||||
boost::hash_value - containers
|
||||
-->
|
||||
|
||||
<overloaded-function name="hash_value">
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::vector<T, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::list<T, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::deque<T, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::set<K, C, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::multiset<K, C, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::map<K, T, C, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="K"/>
|
||||
<template-type-parameter name="T"/>
|
||||
<template-type-parameter name="C"/>
|
||||
<template-type-parameter name="A"/>
|
||||
</template>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>std::multimap<K, T, C, A> const &</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<returns>
|
||||
<code><functionname>hash_range</functionname>(val.begin(), val.end());</code>
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Types</entry>
|
||||
<entry>Returns</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>bool</code>,
|
||||
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>,
|
||||
<code>short</code>, <code>unsigned short</code>,
|
||||
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
|
||||
</entry>
|
||||
<entry><code>val</code></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>long long</code>, <code>unsigned long long</code></entry>
|
||||
<entry><code>val</code> when <code>abs(val) <= std::numeric_limits<std::size_t>::max()</code>.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>float</code>, <code>double</code>, <code>long double</code></entry>
|
||||
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>T*</code></entry>
|
||||
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>T val[N]</code>,
|
||||
<code>const T val[N]</code>
|
||||
</entry>
|
||||
<entry><code>hash_range(val, val+N)</code></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>std:basic_string<Ch, std::char_traits<Ch>, A></code>,
|
||||
<code>std::vector<T, A></code>,
|
||||
<code>std::list<T, A></code>,
|
||||
<code>std::deque<T, A></code>,
|
||||
<code>std::set<K, C, A></code>,
|
||||
<code>std::multiset<K, C, A></code>,
|
||||
<code>std::map<K, T, C, A></code>,
|
||||
<code>std::multimap<K, T, C, A></code>,
|
||||
<code>std::array<T, N></code>
|
||||
</entry>
|
||||
<entry><code>hash_range(val.begin(), val.end())</code></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>std::pair<A, B></code></entry>
|
||||
<entry><programlisting>size_t seed = 0;
|
||||
<functionname>hash_combine</functionname>(seed, val.first);
|
||||
<functionname>hash_combine</functionname>(seed, val.second);
|
||||
return seed;</programlisting></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>std::tuple<T...></code></entry>
|
||||
<entry><programlisting>size_t seed = 0;
|
||||
<functionname>hash_combine</functionname>(seed, get<0>(val));
|
||||
<functionname>hash_combine</functionname>(seed, get<1>(val));
|
||||
// ....
|
||||
return seed;</programlisting></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>std::complex<T></code>
|
||||
</entry>
|
||||
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<code>std::type_index</code>
|
||||
</entry>
|
||||
<entry><code>val.hash_code()</code></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</returns>
|
||||
<throws>
|
||||
Only throws if <code><functionname>hash_value</functionname>(T)</code> throws.
|
||||
</throws>
|
||||
<notes><para>This is an extension to TR1</para></notes>
|
||||
</overloaded-function>
|
||||
</overloaded-function>
|
||||
</free-function-group>
|
||||
</namespace>
|
||||
</header>
|
||||
</library-reference>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[section:acknowledgements Acknowledgements]
|
||||
|
||||
This library is based on the design by Peter Dimov. During the initial
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
|
||||
|
||||
[/ Copyright 2005-2008 Daniel James.
|
||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||
|
||||
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
||||
Boost.MultiIndex]]
|
||||
|
||||
[section:tutorial Tutorial]
|
||||
@@ -12,7 +17,7 @@ If your standard library supplies its own implementation of the unordered
|
||||
associative containers and you wish to use
|
||||
[classref boost::hash], just use an extra template parameter:
|
||||
|
||||
std::unordered_multiset<std::vector<int>, ``[classref boost::hash]``<int> >
|
||||
std::unordered_multiset<int, ``[classref boost::hash]``<int> >
|
||||
set_of_ints;
|
||||
|
||||
std::unordered_set<std::pair<int, int>, ``[classref boost::hash]``<std::pair<int, int> >
|
||||
@@ -105,16 +110,16 @@ And you can now use [classref boost::hash] with book:
|
||||
assert(books.find(dandelion) == books.end());
|
||||
|
||||
The full example can be found in:
|
||||
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp]
|
||||
[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
|
||||
and
|
||||
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
|
||||
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
|
||||
|
||||
[tip
|
||||
When writing a hash function, first look at how the equality function works.
|
||||
Objects that are equal must generate the same hash value.
|
||||
When objects are not equal they should generate different hash values.
|
||||
In this object equality was based just on the id so the hash function
|
||||
only hash the id. If it was based on the objects name and author
|
||||
only hashes the id. If it was based on the object's name and author
|
||||
then the hash function should take them into account
|
||||
(how to do this is discussed in the next section).
|
||||
]
|
||||
@@ -165,7 +170,7 @@ of point, it can be repeatedly called for any number of elements. It calls
|
||||
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
|
||||
|
||||
Full code for this example is at
|
||||
[@../../libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
|
||||
[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
|
||||
|
||||
[note
|
||||
When using [funcref boost::hash_combine] the order of the
|
||||
@@ -193,5 +198,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
|
||||
std::vector<std::string> some_strings;
|
||||
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
|
||||
|
||||
[endsect]
|
||||
Note that when writing template classes, you might not want to include the main
|
||||
hash header as it's quite an expensive include that brings in a lot of other
|
||||
headers, so instead you can include the `<boost/functional/hash_fwd.hpp>`
|
||||
header which forward declares [classref boost::hash],
|
||||
[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
|
||||
include the main header before instantiating [classref boost::hash]. When using
|
||||
a container that uses [classref boost::hash] it should do that for you, so your
|
||||
type will work fine with the boost hash containers. There's an example of this
|
||||
in [@boost:/libs/functional/hash/examples/template.hpp template.hpp] and
|
||||
[@boost:/libs/functional/hash/examples/template.cpp template.cpp].
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
# (C) Copyright Daniel James 2005.
|
||||
# Use, modification and distribution are subject to the
|
||||
# Boost Software License, Version 1.0. (See accompanying file
|
||||
# LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
subproject libs/functional/hash/examples ;
|
||||
|
||||
import testing ;
|
||||
|
||||
DEPENDS all : test ;
|
||||
|
||||
rule hash-example ( name )
|
||||
{
|
||||
return [
|
||||
run $(name).cpp
|
||||
: : : <include>$(BOOST_ROOT)
|
||||
] ;
|
||||
}
|
||||
|
||||
{
|
||||
test-suite functional/examples
|
||||
:
|
||||
[ hash-example books ]
|
||||
[ hash-example point ]
|
||||
[ hash-example portable ]
|
||||
;
|
||||
}
|
||||
@@ -6,3 +6,4 @@
|
||||
run books.cpp ;
|
||||
run point.cpp ;
|
||||
run portable.cpp ;
|
||||
run template.cpp ;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./books.hpp"
|
||||
#include <boost/functional/hash.hpp>
|
||||
@@ -20,6 +20,7 @@ int main()
|
||||
|
||||
boost::hash<library::book> book_hasher;
|
||||
std::size_t knife_hash_value = book_hasher(knife);
|
||||
(void)knife_hash_value; // suppress unused variable warning
|
||||
|
||||
// If std::unordered_set was available:
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This example illustrates how to use boost::hash with a custom hash function.
|
||||
// The implementation is contained in books.cpp
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <cassert>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <cassert>
|
||||
|
||||
18
examples/template.cpp
Normal file
18
examples/template.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "template.hpp"
|
||||
#include <cassert>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef my_pair<int, float> pair;
|
||||
boost::unordered_set<pair> pair_set;
|
||||
pair_set.emplace(10, 0.5f);
|
||||
|
||||
assert(pair_set.find(pair(10, 0.5f)) != pair_set.end());
|
||||
assert(pair_set.find(pair(10, 0.6f)) == pair_set.end());
|
||||
}
|
||||
36
examples/template.hpp
Normal file
36
examples/template.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This is an example of how to write a hash function for a template
|
||||
// class.
|
||||
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
template <typename A, typename B>
|
||||
class my_pair
|
||||
{
|
||||
A value1;
|
||||
B value2;
|
||||
public:
|
||||
my_pair(A const& v1, B const& v2)
|
||||
: value1(v1), value2(v2)
|
||||
{}
|
||||
|
||||
bool operator==(my_pair const& other) const
|
||||
{
|
||||
return value1 == other.value1 &&
|
||||
value2 == other.value2;
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(my_pair const& p)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, p.value1);
|
||||
boost::hash_combine(seed, p.value2);
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_DETAIL_CONTAINER_FWD_HPP)
|
||||
#define BOOST_DETAIL_CONTAINER_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
#define BOOST_HASH_CHAR_TRAITS string_char_traits
|
||||
#else
|
||||
#define BOOST_HASH_CHAR_TRAITS char_traits
|
||||
#endif
|
||||
|
||||
#if (defined(__GLIBCXX__) && defined(_GLIBCXX_DEBUG)) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, > 0x551) \
|
||||
|| BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \
|
||||
|| (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
#include <complex>
|
||||
|
||||
#else
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && \
|
||||
defined(__STL_CONFIG_H)
|
||||
|
||||
#define BOOST_CONTAINER_FWD_BAD_BITSET
|
||||
|
||||
#if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
|
||||
#define BOOST_CONTAINER_FWD_BAD_DEQUE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
|
||||
#include <deque>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_CONTAINER_FWD_BAD_BITSET)
|
||||
#include <bitset>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4099) // struct/class mismatch in fwd declarations
|
||||
#endif
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <class T> class allocator;
|
||||
template <class charT, class traits, class Allocator> class basic_string;
|
||||
template <class charT> struct BOOST_HASH_CHAR_TRAITS;
|
||||
template <class T> class complex;
|
||||
}
|
||||
|
||||
// gcc 3.4 and greater
|
||||
namespace std
|
||||
{
|
||||
#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
|
||||
template <class T, class Allocator> class deque;
|
||||
#endif
|
||||
|
||||
template <class T, class Allocator> class list;
|
||||
template <class T, class Allocator> class vector;
|
||||
template <class Key, class T, class Compare, class Allocator> class map;
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
class multimap;
|
||||
template <class Key, class Compare, class Allocator> class set;
|
||||
template <class Key, class Compare, class Allocator> class multiset;
|
||||
|
||||
#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET)
|
||||
template <size_t N> class bitset;
|
||||
#endif
|
||||
template <class T1, class T2> struct pair;
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,154 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP)
|
||||
#define BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// The C++ standard requires that the C float functions are overloarded
|
||||
// for float, double and long double in the std namespace, but some of the older
|
||||
// library implementations don't support this. On some that don't, the C99
|
||||
// float functions (frexpf, frexpl, etc.) are available.
|
||||
//
|
||||
// Some of this is based on guess work. If I don't know any better I assume that
|
||||
// the standard C++ overloaded functions are available. If they're not then this
|
||||
// means that the argument is cast to a double and back, which is inefficient
|
||||
// and will give pretty bad results for long doubles - so if you know better
|
||||
// let me know.
|
||||
|
||||
// STLport:
|
||||
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
# if defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# elif defined(BOOST_MSVC) && BOOST_MSVC < 1300
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# else
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
# endif
|
||||
|
||||
// Roguewave:
|
||||
//
|
||||
// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't
|
||||
// defined, but for the same version of roguewave on sunpro they are.
|
||||
#elif defined(_RWSTD_VER)
|
||||
# if defined(__BORLANDC__)
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# define BOOST_HASH_C99_NO_FLOAT_FUNCS
|
||||
# elif defined(__DECCXX)
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# else
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
# endif
|
||||
|
||||
// libstdc++ (gcc 3.0 onwards, I think)
|
||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
|
||||
// SGI:
|
||||
#elif defined(__STL_CONFIG_H)
|
||||
# if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# else
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
# endif
|
||||
|
||||
// Dinkumware.
|
||||
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||
// Overloaded float functions were probably introduced in an earlier version
|
||||
// than this.
|
||||
# if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402)
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
# else
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
# endif
|
||||
|
||||
// Digital Mars
|
||||
#elif defined(__DMC__)
|
||||
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
|
||||
// Use overloaded float functions by default.
|
||||
#else
|
||||
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
inline float call_ldexp(float v, int exp)
|
||||
{
|
||||
using namespace std;
|
||||
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
|
||||
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
|
||||
return ldexp(v, exp);
|
||||
#else
|
||||
return ldexpf(v, exp);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline double call_ldexp(double v, int exp)
|
||||
{
|
||||
using namespace std;
|
||||
return ldexp(v, exp);
|
||||
}
|
||||
|
||||
inline long double call_ldexp(long double v, int exp)
|
||||
{
|
||||
using namespace std;
|
||||
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
|
||||
return ldexp(v, exp);
|
||||
#else
|
||||
return ldexpl(v, exp);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline float call_frexp(float v, int* exp)
|
||||
{
|
||||
using namespace std;
|
||||
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
|
||||
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
|
||||
return frexp(v, exp);
|
||||
#else
|
||||
return frexpf(v, exp);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline double call_frexp(double v, int* exp)
|
||||
{
|
||||
using namespace std;
|
||||
return frexp(v, exp);
|
||||
}
|
||||
|
||||
inline long double call_frexp(long double v, int* exp)
|
||||
{
|
||||
using namespace std;
|
||||
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
|
||||
return frexp(v, exp);
|
||||
#else
|
||||
return frexpl(v, exp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS)
|
||||
#undef BOOST_HASH_USE_C99_FLOAT_FUNCS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
|
||||
#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
|
||||
#undef BOOST_HASH_C99_NO_FLOAT_FUNCS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,122 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER)
|
||||
#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/functional/detail/float_functions.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <errno.h>
|
||||
|
||||
// Don't use fpclassify or _fpclass for stlport.
|
||||
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
# if defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
// GNU libstdc++ 3
|
||||
# if defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)
|
||||
# define BOOST_HASH_USE_FPCLASSIFY
|
||||
# endif
|
||||
# elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||
// Dinkumware Library, on Visual C++
|
||||
# if defined(BOOST_MSVC)
|
||||
# define BOOST_HASH_USE_FPCLASS
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
||||
{
|
||||
seed ^= value + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::size_t float_hash_impl(T v)
|
||||
{
|
||||
int exp = 0;
|
||||
errno = 0;
|
||||
v = boost::hash_detail::call_frexp(v, &exp);
|
||||
if(errno) return 0;
|
||||
|
||||
std::size_t seed = 0;
|
||||
|
||||
std::size_t const length
|
||||
= (std::numeric_limits<T>::digits +
|
||||
std::numeric_limits<int>::digits - 1)
|
||||
/ std::numeric_limits<int>::digits;
|
||||
|
||||
for(std::size_t i = 0; i < length; ++i)
|
||||
{
|
||||
v = boost::hash_detail::call_ldexp(v, std::numeric_limits<int>::digits);
|
||||
int const part = static_cast<int>(v);
|
||||
v -= part;
|
||||
hash_float_combine(seed, part);
|
||||
}
|
||||
|
||||
hash_float_combine(seed, exp);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::size_t float_hash_value(T v)
|
||||
{
|
||||
#if defined(BOOST_HASH_USE_FPCLASSIFY)
|
||||
using namespace std;
|
||||
switch (fpclassify(v)) {
|
||||
case FP_ZERO:
|
||||
return 0;
|
||||
case FP_INFINITE:
|
||||
return (std::size_t)(v > 0 ? -1 : -2);
|
||||
case FP_NAN:
|
||||
return (std::size_t)(-3);
|
||||
case FP_NORMAL:
|
||||
case FP_SUBNORMAL:
|
||||
return float_hash_impl(v);
|
||||
default:
|
||||
BOOST_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
#elif defined(BOOST_HASH_USE_FPCLASS)
|
||||
switch(_fpclass(v)) {
|
||||
case _FPCLASS_NZ:
|
||||
case _FPCLASS_PZ:
|
||||
return 0;
|
||||
case _FPCLASS_PINF:
|
||||
return (std::size_t)(-1);
|
||||
case _FPCLASS_NINF:
|
||||
return (std::size_t)(-2);
|
||||
case _FPCLASS_SNAN:
|
||||
case _FPCLASS_QNAN:
|
||||
return (std::size_t)(-3);
|
||||
case _FPCLASS_NN:
|
||||
case _FPCLASS_ND:
|
||||
return float_hash_impl(v);
|
||||
case _FPCLASS_PD:
|
||||
case _FPCLASS_PN:
|
||||
return float_hash_impl(v);
|
||||
default:
|
||||
BOOST_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return float_hash_impl(v);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DEQUE_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_DEQUE_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/deque.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
336
include/boost/functional/hash/detail/float_functions.hpp
Normal file
336
include/boost/functional/hash/detail/float_functions.hpp
Normal file
@@ -0,0 +1,336 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
|
||||
// sufficiently good floating point support to not require any
|
||||
// workarounds.
|
||||
//
|
||||
// When set to 0, the library tries to automatically
|
||||
// use the best available implementation. This normally works well, but
|
||||
// breaks when ambiguities are created by odd namespacing of the functions.
|
||||
//
|
||||
// Note that if this is set to 0, the library should still take full
|
||||
// advantage of the platform's floating point support.
|
||||
|
||||
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif defined(__LIBCOMO__)
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
|
||||
// Rogue Wave library:
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
// libc++
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
// GNU libstdc++ 3
|
||||
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||
# else
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
# endif
|
||||
#elif defined(__STL_CONFIG_H)
|
||||
// generic SGI STL
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif defined(__MSL_CPP__)
|
||||
// MSL standard lib:
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif defined(__IBMCPP__)
|
||||
// VACPP std lib (probably conformant for much earlier version).
|
||||
# if __IBMCPP__ >= 1210
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||
# else
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
# endif
|
||||
#elif defined(MSIPL_COMPILE_H)
|
||||
// Modena C++ standard library
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||
// Dinkumware Library (this has to appear after any possible replacement libraries):
|
||||
# if _CPPLIB_VER >= 405
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||
# else
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
# endif
|
||||
#else
|
||||
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_CONFORMANT_FLOATS
|
||||
|
||||
// The standard library is known to be compliant, so don't use the
|
||||
// configuration mechanism.
|
||||
|
||||
namespace boost {
|
||||
namespace hash_detail {
|
||||
template <typename Float>
|
||||
struct call_ldexp {
|
||||
typedef Float float_type;
|
||||
inline Float operator()(Float x, int y) const {
|
||||
return std::ldexp(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Float>
|
||||
struct call_frexp {
|
||||
typedef Float float_type;
|
||||
inline Float operator()(Float x, int* y) const {
|
||||
return std::frexp(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Float>
|
||||
struct select_hash_type
|
||||
{
|
||||
typedef Float type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
|
||||
|
||||
// The C++ standard requires that the C float functions are overloarded
|
||||
// for float, double and long double in the std namespace, but some of the older
|
||||
// library implementations don't support this. On some that don't, the C99
|
||||
// float functions (frexpf, frexpl, etc.) are available.
|
||||
//
|
||||
// The following tries to automatically detect which are available.
|
||||
|
||||
namespace boost {
|
||||
namespace hash_detail {
|
||||
|
||||
// Returned by dummy versions of the float functions.
|
||||
|
||||
struct not_found {
|
||||
// Implicitly convertible to float and long double in order to avoid
|
||||
// a compile error when the dummy float functions are used.
|
||||
|
||||
inline operator float() const { return 0; }
|
||||
inline operator long double() const { return 0; }
|
||||
};
|
||||
|
||||
// A type for detecting the return type of functions.
|
||||
|
||||
template <typename T> struct is;
|
||||
template <> struct is<float> { char x[10]; };
|
||||
template <> struct is<double> { char x[20]; };
|
||||
template <> struct is<long double> { char x[30]; };
|
||||
template <> struct is<boost::hash_detail::not_found> { char x[40]; };
|
||||
|
||||
// Used to convert the return type of a function to a type for sizeof.
|
||||
|
||||
template <typename T> is<T> float_type(T);
|
||||
|
||||
// call_ldexp
|
||||
//
|
||||
// This will get specialized for float and long double
|
||||
|
||||
template <typename Float> struct call_ldexp
|
||||
{
|
||||
typedef double float_type;
|
||||
|
||||
inline double operator()(double a, int b) const
|
||||
{
|
||||
using namespace std;
|
||||
return ldexp(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
// call_frexp
|
||||
//
|
||||
// This will get specialized for float and long double
|
||||
|
||||
template <typename Float> struct call_frexp
|
||||
{
|
||||
typedef double float_type;
|
||||
|
||||
inline double operator()(double a, int* b) const
|
||||
{
|
||||
using namespace std;
|
||||
return frexp(a, b);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// A namespace for dummy functions to detect when the actual function we want
|
||||
// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
|
||||
//
|
||||
// AFAICT these have to be outside of the boost namespace, as if they're in
|
||||
// the boost namespace they'll always be preferable to any other function
|
||||
// (since the arguments are built in types, ADL can't be used).
|
||||
|
||||
namespace boost_hash_detect_float_functions {
|
||||
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
|
||||
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
|
||||
}
|
||||
|
||||
// Macros for generating specializations of call_ldexp and call_frexp.
|
||||
//
|
||||
// check_cpp and check_c99 check if the C++ or C99 functions are available.
|
||||
//
|
||||
// Then the call_* functions select an appropriate implementation.
|
||||
//
|
||||
// I used c99_func in a few places just to get a unique name.
|
||||
//
|
||||
// Important: when using 'using namespace' at namespace level, include as
|
||||
// little as possible in that namespace, as Visual C++ has an odd bug which
|
||||
// can cause the namespace to be imported at the global level. This seems to
|
||||
// happen mainly when there's a template in the same namesapce.
|
||||
|
||||
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
|
||||
namespace boost_hash_detect_float_functions { \
|
||||
template <class Float> \
|
||||
boost::hash_detail::not_found c99_func(Float, type2); \
|
||||
} \
|
||||
\
|
||||
namespace boost { \
|
||||
namespace hash_detail { \
|
||||
namespace c99_func##_detect { \
|
||||
using namespace std; \
|
||||
using namespace boost_hash_detect_float_functions; \
|
||||
\
|
||||
struct check { \
|
||||
static type1 x; \
|
||||
static type2 y; \
|
||||
BOOST_STATIC_CONSTANT(bool, cpp = \
|
||||
sizeof(float_type(cpp_func(x,y))) \
|
||||
== sizeof(is<type1>)); \
|
||||
BOOST_STATIC_CONSTANT(bool, c99 = \
|
||||
sizeof(float_type(c99_func(x,y))) \
|
||||
== sizeof(is<type1>)); \
|
||||
}; \
|
||||
} \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_c99_##c99_func : \
|
||||
boost::hash_detail::call_##cpp_func<double> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_c99_##c99_func<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
using namespace std; \
|
||||
return c99_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <bool x> \
|
||||
struct call_cpp_##c99_func : \
|
||||
call_c99_##c99_func< \
|
||||
::boost::hash_detail::c99_func##_detect::check::c99 \
|
||||
> {}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_cpp_##c99_func<true> { \
|
||||
typedef type1 float_type; \
|
||||
\
|
||||
template <typename T> \
|
||||
inline type1 operator()(type1 a, T b) const \
|
||||
{ \
|
||||
using namespace std; \
|
||||
return cpp_func(a, b); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <> \
|
||||
struct call_##cpp_func<type1> : \
|
||||
call_cpp_##c99_func< \
|
||||
::boost::hash_detail::c99_func##_detect::check::cpp \
|
||||
> {}; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
|
||||
namespace boost { \
|
||||
namespace hash_detail { \
|
||||
\
|
||||
template <> \
|
||||
struct call_##cpp_func<type1> { \
|
||||
typedef type1 float_type; \
|
||||
inline type1 operator()(type1 x, type2 y) const { \
|
||||
return c99_func(x, y); \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(ldexpf)
|
||||
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
|
||||
#else
|
||||
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
|
||||
#endif
|
||||
|
||||
#if defined(ldexpl)
|
||||
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
|
||||
#else
|
||||
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
|
||||
#endif
|
||||
|
||||
#if defined(frexpf)
|
||||
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
|
||||
#else
|
||||
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
|
||||
#endif
|
||||
|
||||
#if defined(frexpl)
|
||||
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
|
||||
#else
|
||||
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
|
||||
#endif
|
||||
|
||||
#undef BOOST_HASH_CALL_FLOAT_MACRO
|
||||
#undef BOOST_HASH_CALL_FLOAT_FUNC
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
template <typename Float1, typename Float2>
|
||||
struct select_hash_type_impl {
|
||||
typedef double type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct select_hash_type_impl<float, float> {
|
||||
typedef float type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct select_hash_type_impl<long double, long double> {
|
||||
typedef long double type;
|
||||
};
|
||||
|
||||
|
||||
// select_hash_type
|
||||
//
|
||||
// If there is support for a particular floating point type, use that
|
||||
// otherwise use double (there's always support for double).
|
||||
|
||||
template <typename Float>
|
||||
struct select_hash_type : select_hash_type_impl<
|
||||
BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
|
||||
BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
|
||||
> {};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_HASH_CONFORMANT_FLOATS
|
||||
|
||||
#endif
|
||||
271
include/boost/functional/hash/detail/hash_float.hpp
Normal file
271
include/boost/functional/hash/detail/hash_float.hpp
Normal file
@@ -0,0 +1,271 @@
|
||||
|
||||
// Copyright 2005-2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/integer/static_log2.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#if BOOST_MSVC >= 1400
|
||||
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
|
||||
// not satisfy test. Loop body not executed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Can we use fpclassify?
|
||||
|
||||
// STLport
|
||||
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
#define BOOST_HASH_USE_FPCLASSIFY 0
|
||||
|
||||
// GNU libstdc++ 3
|
||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
|
||||
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
|
||||
# define BOOST_HASH_USE_FPCLASSIFY 1
|
||||
# else
|
||||
# define BOOST_HASH_USE_FPCLASSIFY 0
|
||||
# endif
|
||||
|
||||
// Everything else
|
||||
#else
|
||||
# define BOOST_HASH_USE_FPCLASSIFY 0
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
||||
{
|
||||
seed ^= value + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Binary hash function
|
||||
//
|
||||
// Only used for floats with known iec559 floats, and certain values in
|
||||
// numeric_limits
|
||||
|
||||
inline std::size_t hash_binary(char* ptr, std::size_t length)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
if (length >= sizeof(std::size_t)) {
|
||||
seed = *(std::size_t*) ptr;
|
||||
length -= sizeof(std::size_t);
|
||||
ptr += sizeof(std::size_t);
|
||||
|
||||
while(length >= sizeof(std::size_t)) {
|
||||
std::size_t buffer = 0;
|
||||
std::memcpy(&buffer, ptr, sizeof(std::size_t));
|
||||
hash_float_combine(seed, buffer);
|
||||
length -= sizeof(std::size_t);
|
||||
ptr += sizeof(std::size_t);
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
std::size_t buffer = 0;
|
||||
std::memcpy(&buffer, ptr, length);
|
||||
hash_float_combine(seed, buffer);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <typename Float, unsigned digits, unsigned max_exponent>
|
||||
struct enable_binary_hash
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
std::numeric_limits<Float>::is_iec559 &&
|
||||
std::numeric_limits<Float>::digits == digits &&
|
||||
std::numeric_limits<Float>::radix == 2 &&
|
||||
std::numeric_limits<Float>::max_exponent == max_exponent);
|
||||
};
|
||||
|
||||
template <typename Float>
|
||||
inline std::size_t float_hash_impl(Float v,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||
enable_binary_hash<Float, 24, 128>::value,
|
||||
std::size_t>::type)
|
||||
{
|
||||
return hash_binary((char*) &v, 4);
|
||||
}
|
||||
|
||||
|
||||
template <typename Float>
|
||||
inline std::size_t float_hash_impl(Float v,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||
enable_binary_hash<Float, 53, 1024>::value,
|
||||
std::size_t>::type)
|
||||
{
|
||||
return hash_binary((char*) &v, 8);
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
inline std::size_t float_hash_impl(Float v,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||
enable_binary_hash<Float, 64, 16384>::value,
|
||||
std::size_t>::type)
|
||||
{
|
||||
return hash_binary((char*) &v, 10);
|
||||
}
|
||||
|
||||
template <typename Float>
|
||||
inline std::size_t float_hash_impl(Float v,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||
enable_binary_hash<Float, 113, 16384>::value,
|
||||
std::size_t>::type)
|
||||
{
|
||||
return hash_binary((char*) &v, 16);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Portable hash function
|
||||
//
|
||||
// Used as a fallback when the binary hash function isn't supported.
|
||||
|
||||
template <class T>
|
||||
inline std::size_t float_hash_impl2(T v)
|
||||
{
|
||||
boost::hash_detail::call_frexp<T> frexp;
|
||||
boost::hash_detail::call_ldexp<T> ldexp;
|
||||
|
||||
int exp = 0;
|
||||
|
||||
v = frexp(v, &exp);
|
||||
|
||||
// A postive value is easier to hash, so combine the
|
||||
// sign with the exponent and use the absolute value.
|
||||
if(v < 0) {
|
||||
v = -v;
|
||||
exp += limits<T>::max_exponent -
|
||||
limits<T>::min_exponent;
|
||||
}
|
||||
|
||||
v = ldexp(v, limits<std::size_t>::digits);
|
||||
std::size_t seed = static_cast<std::size_t>(v);
|
||||
v -= static_cast<T>(seed);
|
||||
|
||||
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
|
||||
std::size_t const length
|
||||
= (limits<T>::digits *
|
||||
boost::static_log2<limits<T>::radix>::value
|
||||
+ limits<std::size_t>::digits - 1)
|
||||
/ limits<std::size_t>::digits;
|
||||
|
||||
for(std::size_t i = 0; i != length; ++i)
|
||||
{
|
||||
v = ldexp(v, limits<std::size_t>::digits);
|
||||
std::size_t part = static_cast<std::size_t>(v);
|
||||
v -= static_cast<T>(part);
|
||||
hash_float_combine(seed, part);
|
||||
}
|
||||
|
||||
hash_float_combine(seed, exp);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
|
||||
template <class T>
|
||||
inline std::size_t float_hash_impl(T v, ...)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
|
||||
return float_hash_impl2(static_cast<type>(v));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if BOOST_HASH_USE_FPCLASSIFY
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
template <class T>
|
||||
inline std::size_t float_hash_value(T v)
|
||||
{
|
||||
#if defined(fpclassify)
|
||||
switch (fpclassify(v))
|
||||
#elif BOOST_HASH_CONFORMANT_FLOATS
|
||||
switch (std::fpclassify(v))
|
||||
#else
|
||||
using namespace std;
|
||||
switch (fpclassify(v))
|
||||
#endif
|
||||
{
|
||||
case FP_ZERO:
|
||||
return 0;
|
||||
case FP_INFINITE:
|
||||
return (std::size_t)(v > 0 ? -1 : -2);
|
||||
case FP_NAN:
|
||||
return (std::size_t)(-3);
|
||||
case FP_NORMAL:
|
||||
case FP_SUBNORMAL:
|
||||
return float_hash_impl(v, 0);
|
||||
default:
|
||||
BOOST_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else // !BOOST_HASH_USE_FPCLASSIFY
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
template <class T>
|
||||
inline bool is_zero(T v)
|
||||
{
|
||||
#if !defined(__GNUC__)
|
||||
return v == 0;
|
||||
#else
|
||||
// GCC's '-Wfloat-equal' will complain about comparing
|
||||
// v to 0, but because it disables warnings for system
|
||||
// headers it won't complain if you use std::equal_to to
|
||||
// compare with 0. Resulting in this silliness:
|
||||
return std::equal_to<T>()(v, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::size_t float_hash_value(T v)
|
||||
{
|
||||
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_HASH_USE_FPCLASSIFY
|
||||
|
||||
#undef BOOST_HASH_USE_FPCLASSIFY
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
62
include/boost/functional/hash/detail/limits.hpp
Normal file
62
include/boost/functional/hash/detail/limits.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// On some platforms std::limits gives incorrect values for long double.
|
||||
// This tries to work around them.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
// On OpenBSD, numeric_limits is not reliable for long doubles, but
|
||||
// the macros defined in <float.h> are and support long double when STLport
|
||||
// doesn't.
|
||||
|
||||
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
template <class T>
|
||||
struct limits : std::numeric_limits<T> {};
|
||||
|
||||
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
|
||||
template <>
|
||||
struct limits<long double>
|
||||
: std::numeric_limits<long double>
|
||||
{
|
||||
static long double epsilon() {
|
||||
return LDBL_EPSILON;
|
||||
}
|
||||
|
||||
static long double (max)() {
|
||||
return LDBL_MAX;
|
||||
}
|
||||
|
||||
static long double (min)() {
|
||||
return LDBL_MIN;
|
||||
}
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
|
||||
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
|
||||
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
|
||||
#if defined(_STLP_NO_LONG_DOUBLE)
|
||||
BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
|
||||
#endif
|
||||
};
|
||||
#endif // __OpenBSD__
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
284
include/boost/functional/hash/extensions.hpp
Normal file
284
include/boost/functional/hash/extensions.hpp
Normal file
@@ -0,0 +1,284 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
// This implements the extensions to the standard.
|
||||
// It's undocumented, so you shouldn't use it....
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/detail/container_fwd.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||
# include <array>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
# include <tuple>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value(std::complex<T> const&);
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const& v)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, v.first);
|
||||
boost::hash_combine(seed, v.second);
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value(std::complex<T> const& v)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
std::size_t seed = hasher(v.imag());
|
||||
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||
template <class T, std::size_t N>
|
||||
std::size_t hash_value(std::array<T, N> const& v)
|
||||
{
|
||||
return boost::hash_range(v.begin(), v.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
namespace hash_detail {
|
||||
template <std::size_t I, typename T>
|
||||
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
|
||||
void>::type
|
||||
hash_combine_tuple(std::size_t&, T const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
|
||||
void>::type
|
||||
hash_combine_tuple(std::size_t& seed, T const& v)
|
||||
{
|
||||
boost::hash_combine(seed, std::get<I>(v));
|
||||
boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::size_t hash_tuple(T const& v)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_detail::hash_combine_tuple<0>(seed, v);
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <typename... T>
|
||||
inline std::size_t hash_value(std::tuple<T...> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
#else
|
||||
|
||||
inline std::size_t hash_value(std::tuple<> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
# define BOOST_HASH_TUPLE_F(z, n, _) \
|
||||
template< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
inline std::size_t hash_value(std::tuple< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, A) \
|
||||
> const& v) \
|
||||
{ \
|
||||
return boost::hash_detail::hash_tuple(v); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
|
||||
# undef BOOST_HASH_TUPLE_F
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
template <typename T>
|
||||
inline std::size_t hash_value(std::shared_ptr<T> const& x) {
|
||||
return boost::hash_value(x.get());
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
|
||||
return boost::hash_value(x.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// call_hash_impl
|
||||
//
|
||||
|
||||
// On compilers without function template ordering, this deals with arrays.
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsArray>
|
||||
struct call_hash_impl
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
{
|
||||
static std::size_t call(T const& v)
|
||||
{
|
||||
using namespace boost;
|
||||
return hash_value(v);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct call_hash_impl<true>
|
||||
{
|
||||
template <class Array>
|
||||
struct inner
|
||||
{
|
||||
static std::size_t call(Array const& v)
|
||||
{
|
||||
const int size = sizeof(v) / sizeof(*v);
|
||||
return boost::hash_range(v, v + size);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct call_hash
|
||||
: public call_hash_impl<boost::is_array<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
}
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
|
||||
|
||||
template <class T> struct hash
|
||||
: std::unary_function<T, std::size_t>
|
||||
{
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_value(val);
|
||||
}
|
||||
#else
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T>::call(val);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||
template <class T, unsigned int n> struct hash<T[n]>
|
||||
: std::unary_function<T[n], std::size_t>
|
||||
{
|
||||
std::size_t operator()(const T* val) const
|
||||
{
|
||||
return boost::hash_range(val, val+n);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
@@ -10,120 +10,245 @@
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/functional/hash/hash_fwd.hpp>
|
||||
#include <functional>
|
||||
#include <boost/functional/detail/hash_float.hpp>
|
||||
#include <boost/functional/detail/container_fwd.hpp>
|
||||
#include <boost/functional/hash/detail/hash_float.hpp>
|
||||
#include <string>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
#include <typeindex>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
|
||||
#if BOOST_MSVC >= 1400
|
||||
#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
|
||||
// are always of range '0' to '4294967295'.
|
||||
// Loop executes infinitely.
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
// Borland complains about an ambiguous function overload
|
||||
// when compiling boost::hash<bool>.
|
||||
std::size_t hash_value(bool);
|
||||
#endif
|
||||
|
||||
std::size_t hash_value(int);
|
||||
std::size_t hash_value(unsigned int);
|
||||
std::size_t hash_value(long);
|
||||
std::size_t hash_value(unsigned long);
|
||||
namespace hash_detail
|
||||
{
|
||||
struct enable_hash_value { typedef std::size_t type; };
|
||||
|
||||
template <typename T> struct basic_numbers {};
|
||||
template <typename T> struct long_numbers;
|
||||
template <typename T> struct ulong_numbers;
|
||||
template <typename T> struct float_numbers {};
|
||||
|
||||
template <> struct basic_numbers<bool> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<char> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<unsigned char> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<signed char> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<short> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<unsigned short> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<int> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<unsigned int> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<long> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct basic_numbers<unsigned long> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
template <> struct basic_numbers<wchar_t> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
#endif
|
||||
|
||||
// long_numbers is defined like this to allow for separate
|
||||
// specialization for long_long and int128_type, in case
|
||||
// they conflict.
|
||||
template <typename T> struct long_numbers2 {};
|
||||
template <typename T> struct ulong_numbers2 {};
|
||||
template <typename T> struct long_numbers : long_numbers2<T> {};
|
||||
template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
|
||||
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
template <> struct long_numbers<boost::long_long_type> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct ulong_numbers<boost::ulong_long_type> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
template <> struct long_numbers2<boost::int128_type> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct ulong_numbers2<boost::uint128_type> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
#endif
|
||||
|
||||
template <> struct float_numbers<float> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct float_numbers<double> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
template <> struct float_numbers<long double> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
|
||||
template <typename T>
|
||||
typename boost::hash_detail::long_numbers<T>::type hash_value(T);
|
||||
template <typename T>
|
||||
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
|
||||
|
||||
template <typename T>
|
||||
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
|
||||
hash_value(T);
|
||||
|
||||
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||
template <class T> std::size_t hash_value(T* const&);
|
||||
#else
|
||||
template <class T> std::size_t hash_value(T*);
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template< class T, unsigned N >
|
||||
std::size_t hash_value(const T (&array)[N]);
|
||||
std::size_t hash_value(const T (&x)[N]);
|
||||
|
||||
template< class T, unsigned N >
|
||||
std::size_t hash_value(T (&array)[N]);
|
||||
std::size_t hash_value(T (&x)[N]);
|
||||
#endif
|
||||
|
||||
std::size_t hash_value(float v);
|
||||
std::size_t hash_value(double v);
|
||||
std::size_t hash_value(long double v);
|
||||
|
||||
template <class Ch, class A>
|
||||
std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
|
||||
std::size_t hash_value(
|
||||
std::basic_string<Ch, std::char_traits<Ch>, A> const&);
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const&);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v);
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v);
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v);
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
|
||||
template <typename T>
|
||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
std::size_t hash_value(std::type_index);
|
||||
#endif
|
||||
|
||||
// Implementation
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
inline std::size_t hash_value(bool v)
|
||||
namespace hash_detail
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
#endif
|
||||
template <class T>
|
||||
inline std::size_t hash_value_signed(T val)
|
||||
{
|
||||
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
|
||||
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
|
||||
const int length = (std::numeric_limits<T>::digits - 1)
|
||||
/ size_t_bits;
|
||||
|
||||
inline std::size_t hash_value(int v)
|
||||
std::size_t seed = 0;
|
||||
T positive = val < 0 ? -1 - val : val;
|
||||
|
||||
// Hopefully, this loop can be unrolled.
|
||||
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
|
||||
{
|
||||
seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
|
||||
}
|
||||
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::size_t hash_value_unsigned(T val)
|
||||
{
|
||||
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
|
||||
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
|
||||
const int length = (std::numeric_limits<T>::digits - 1)
|
||||
/ size_t_bits;
|
||||
|
||||
std::size_t seed = 0;
|
||||
|
||||
// Hopefully, this loop can be unrolled.
|
||||
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
|
||||
{
|
||||
seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
|
||||
}
|
||||
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
|
||||
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(unsigned int v)
|
||||
template <typename T>
|
||||
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
return hash_detail::hash_value_signed(v);
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(long v)
|
||||
template <typename T>
|
||||
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
return hash_detail::hash_value_unsigned(v);
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(unsigned long v)
|
||||
template <typename T>
|
||||
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
|
||||
hash_value(T v)
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
|
||||
// Implementation by Alberto Barbati and Dave Harris.
|
||||
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
|
||||
template <class T> std::size_t hash_value(T* const& v)
|
||||
#else
|
||||
template <class T> std::size_t hash_value(T* v)
|
||||
#endif
|
||||
{
|
||||
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
|
||||
// for some reason ptrdiff_t on OpenVMS compiler with
|
||||
// 64 bit is not 64 bit !!!
|
||||
std::size_t x = static_cast<std::size_t>(
|
||||
reinterpret_cast<long long int>(v));
|
||||
#else
|
||||
std::size_t x = static_cast<std::size_t>(
|
||||
reinterpret_cast<std::ptrdiff_t>(v));
|
||||
#endif
|
||||
return x + (x >> 3);
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t& seed, T& v)
|
||||
#else
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#if BOOST_MSVC <= 1400
|
||||
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
|
||||
// 'unsigned int', possible loss of data
|
||||
// A misguided attempt to detect 64-bit
|
||||
// incompatability.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t& seed, T const& v)
|
||||
#endif
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class It>
|
||||
inline std::size_t hash_range(It first, It last)
|
||||
{
|
||||
@@ -174,95 +299,54 @@ namespace boost
|
||||
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(const T (&array)[N])
|
||||
inline std::size_t hash_value(const T (&x)[N])
|
||||
{
|
||||
return hash_range(array, array + N);
|
||||
return hash_range(x, x + N);
|
||||
}
|
||||
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(T (&array)[N])
|
||||
inline std::size_t hash_value(T (&x)[N])
|
||||
{
|
||||
return hash_range(array, array + N);
|
||||
return hash_range(x, x + N);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Ch, class A>
|
||||
inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
|
||||
inline std::size_t hash_value(
|
||||
std::basic_string<Ch, std::char_traits<Ch>, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(float v)
|
||||
template <typename T>
|
||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(double v)
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
inline std::size_t hash_value(std::type_index v)
|
||||
{
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(long double v)
|
||||
{
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value(std::pair<A, B> const& v)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.first);
|
||||
hash_combine(seed, v.second);
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::vector<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::list<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
std::size_t hash_value(std::deque<T, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::set<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class C, class A>
|
||||
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <class K, class T, class C, class A>
|
||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
return v.hash_code();
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
// Define the specializations required by the standard. The general purpose
|
||||
// boost::hash is defined later in extensions.hpp if
|
||||
// BOOST_HASH_NO_EXTENSIONS is not defined.
|
||||
|
||||
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
|
||||
// passed by copy.
|
||||
//
|
||||
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
|
||||
// passed by copy.
|
||||
//
|
||||
// These are undefined later.
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#define BOOST_HASH_SPECIALIZE(type) \
|
||||
template <> struct hash<type> \
|
||||
: public std::unary_function<type, std::size_t> \
|
||||
@@ -282,45 +366,6 @@ namespace boost
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
#else
|
||||
#define BOOST_HASH_SPECIALIZE(type) \
|
||||
template <> struct hash<type> \
|
||||
: public std::unary_function<type, std::size_t> \
|
||||
{ \
|
||||
std::size_t operator()(type v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <> struct hash<const type> \
|
||||
: public std::unary_function<const type, std::size_t> \
|
||||
{ \
|
||||
std::size_t operator()(const type v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BOOST_HASH_SPECIALIZE_REF(type) \
|
||||
template <> struct hash<type> \
|
||||
: public std::unary_function<type, std::size_t> \
|
||||
{ \
|
||||
std::size_t operator()(type const& v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
template <> struct hash<const type> \
|
||||
: public std::unary_function<const type, std::size_t> \
|
||||
{ \
|
||||
std::size_t operator()(type const& v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
#endif
|
||||
|
||||
BOOST_HASH_SPECIALIZE(bool)
|
||||
BOOST_HASH_SPECIALIZE(char)
|
||||
@@ -345,205 +390,56 @@ namespace boost
|
||||
BOOST_HASH_SPECIALIZE_REF(std::wstring)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
BOOST_HASH_SPECIALIZE(boost::long_long_type)
|
||||
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
BOOST_HASH_SPECIALIZE(boost::int128_type)
|
||||
BOOST_HASH_SPECIALIZE(boost::uint128_type)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
BOOST_HASH_SPECIALIZE(std::type_index)
|
||||
#endif
|
||||
|
||||
#undef BOOST_HASH_SPECIALIZE
|
||||
#undef BOOST_HASH_SPECIALIZE_REF
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
// Specializing boost::hash for pointers.
|
||||
|
||||
|
||||
template <class T>
|
||||
struct hash<T*>
|
||||
: public std::unary_function<T*, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T* v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
#else
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
struct hash_impl;
|
||||
|
||||
template <>
|
||||
struct hash_impl<true>
|
||||
std::size_t operator()(T* v) const
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: public std::unary_function<T, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T val) const
|
||||
{
|
||||
return boost::hash_value(val);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
|
||||
return boost::hash_value(v);
|
||||
#else
|
||||
std::size_t x = static_cast<std::size_t>(
|
||||
reinterpret_cast<std::ptrdiff_t>(v));
|
||||
|
||||
template <class T> struct hash
|
||||
: public hash_detail::hash_impl<boost::is_pointer<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
return x + (x >> 3);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Include this outside of the include guards in case the file is included
|
||||
// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
|
||||
// undefined.
|
||||
|
||||
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
|
||||
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsArray>
|
||||
struct call_hash_impl
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
{
|
||||
static std::size_t call(T const& v)
|
||||
{
|
||||
using namespace boost;
|
||||
return hash_value(v);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct call_hash_impl<true>
|
||||
{
|
||||
template <class Array>
|
||||
struct inner
|
||||
{
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
static std::size_t call(Array const& v)
|
||||
#else
|
||||
static std::size_t call(Array& v)
|
||||
#include <boost/functional/hash/extensions.hpp>
|
||||
#endif
|
||||
{
|
||||
const int size = sizeof(v) / sizeof(*v);
|
||||
return boost::hash_range(v, v + size);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct call_hash
|
||||
: public call_hash_impl<boost::is_array<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
}
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T> struct hash
|
||||
: std::unary_function<T, std::size_t>
|
||||
{
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_value(val);
|
||||
}
|
||||
#else
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T>::call(val);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#elif !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
// On compilers without partial specialization, boost::hash<T>
|
||||
// has already been declared to deal with pointers, so just
|
||||
// need to supply the non-pointer version.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <>
|
||||
struct hash_impl<false>
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: std::unary_function<T, std::size_t>
|
||||
{
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_value(val);
|
||||
}
|
||||
#else
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T>::call(val);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#else // Visual C++ 6.5
|
||||
|
||||
// There's probably a more elegant way to Visual C++ 6.5 to work
|
||||
// but I don't know what it is.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsConst>
|
||||
struct hash_impl_msvc
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: public std::unary_function<T, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T const>::call(val);
|
||||
}
|
||||
|
||||
std::size_t operator()(T& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T>::call(val);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash_impl_msvc<true>
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: public std::unary_function<T, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T& val) const
|
||||
{
|
||||
return hash_detail::call_hash<T>::call(val);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct hash_impl_msvc2
|
||||
: public hash_impl_msvc<boost::is_const<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T> {};
|
||||
|
||||
template <>
|
||||
struct hash_impl<false>
|
||||
{
|
||||
template <class T>
|
||||
struct inner : public hash_impl_msvc2<T> {};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
36
include/boost/functional/hash/hash_fwd.hpp
Normal file
36
include/boost/functional/hash/hash_fwd.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class T> struct hash;
|
||||
|
||||
template <class T> void hash_combine(std::size_t& seed, T const& v);
|
||||
|
||||
template <class It> std::size_t hash_range(It, It);
|
||||
template <class It> void hash_range(std::size_t&, It, It);
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template <class T> inline std::size_t hash_range(T*, T*);
|
||||
template <class T> inline void hash_range(std::size_t&, T*, T*);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_LIST_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_LIST_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/list.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_MAP_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_MAP_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/map.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_PAIR_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_PAIR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/pair.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_SET_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_SET_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/set.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_VECTOR_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_VECTOR_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#warning "boost/functional/hash/vector.hpp is deprecated, use boost/functional/hash.hpp instead."
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,40 +1,11 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class T> struct hash;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
template <class T> void hash_combine(std::size_t& seed, T& v);
|
||||
#else
|
||||
template <class T> void hash_combine(std::size_t& seed, T const& v);
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
template <class It> std::size_t hash_range(It, It);
|
||||
template <class It> void hash_range(std::size_t&, It, It);
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template <class T> inline std::size_t hash_range(T*, T*);
|
||||
template <class T> inline void hash_range(std::size_t&, T*, T*);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#include <boost/functional/hash/hash_fwd.hpp>
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
|
||||
<!--
|
||||
Copyright 2005-2007 Daniel James.
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=../../doc/html/hash.html">
|
||||
|
||||
51
test/Jamfile
51
test/Jamfile
@@ -1,51 +0,0 @@
|
||||
|
||||
# Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
subproject libs/functional/hash/test ;
|
||||
|
||||
import testing ;
|
||||
|
||||
DEPENDS all : test ;
|
||||
|
||||
rule hash-test ( names + : extras * )
|
||||
{
|
||||
return [
|
||||
run $(names).cpp
|
||||
: : : <include>$(BOOST_ROOT) $(extras)
|
||||
: $(names[1])
|
||||
] ;
|
||||
}
|
||||
|
||||
{
|
||||
test-suite functional/hash
|
||||
:
|
||||
[ hash-test hash_fwd_test_1 ]
|
||||
[ hash-test hash_fwd_test_2 ]
|
||||
[ hash-test hash_number_test ]
|
||||
[ hash-test hash_pointer_test ]
|
||||
[ hash-test hash_function_pointer_test ]
|
||||
[ hash-test hash_float_test : <test-info>always_show_run_output ]
|
||||
[ hash-test hash_string_test ]
|
||||
[ hash-test hash_range_test ]
|
||||
[ hash-test hash_custom_test ]
|
||||
[ hash-test hash_global_namespace_test ]
|
||||
[ hash-test hash_friend_test ]
|
||||
[ hash-test hash_built_in_array_test ]
|
||||
[ hash-test hash_value_array_test ]
|
||||
[ hash-test hash_vector_test ]
|
||||
[ hash-test hash_list_test ]
|
||||
[ hash-test hash_deque_test ]
|
||||
[ hash-test hash_set_test ]
|
||||
[ hash-test hash_map_test ]
|
||||
[ hash-test link_test link_test_2 ]
|
||||
[ hash-test link_ext_test link_no_ext_test ]
|
||||
[ run container_fwd_test.cpp : : : <include>$(BOOST_ROOT) ]
|
||||
[ compile-fail hash_no_ext_fail_test.cpp ]
|
||||
[ run hash_no_ext_macro_1.cpp ]
|
||||
[ run hash_no_ext_macro_2.cpp ]
|
||||
;
|
||||
}
|
||||
|
||||
subinclude libs/functional/hash/examples ;
|
||||
@@ -1,13 +1,20 @@
|
||||
|
||||
# Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
# subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
# Copyright 2005-2012 Daniel James.
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import testing ;
|
||||
|
||||
project hash-tests
|
||||
: requirements
|
||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
<warnings>all
|
||||
<toolset>intel:<warnings>on
|
||||
#<toolset>intel:<cxxflags>-strict-ansi
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
#<toolset>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
test-suite functional/hash
|
||||
@@ -15,9 +22,11 @@ test-suite functional/hash
|
||||
[ run hash_fwd_test_1.cpp ]
|
||||
[ run hash_fwd_test_2.cpp ]
|
||||
[ run hash_number_test.cpp ]
|
||||
[ run hash_enum_test.cpp ]
|
||||
[ run hash_pointer_test.cpp ]
|
||||
[ run hash_function_pointer_test.cpp ]
|
||||
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run hash_float_test.cpp ]
|
||||
[ run hash_long_double_test.cpp ]
|
||||
[ run hash_string_test.cpp ]
|
||||
[ run hash_range_test.cpp ]
|
||||
[ run hash_custom_test.cpp ]
|
||||
@@ -30,12 +39,43 @@ test-suite functional/hash
|
||||
[ run hash_deque_test.cpp ]
|
||||
[ run hash_set_test.cpp ]
|
||||
[ run hash_map_test.cpp ]
|
||||
[ run hash_complex_test.cpp ]
|
||||
[ run hash_type_index_test.cpp ]
|
||||
[ run hash_std_array_test.cpp ]
|
||||
[ run hash_std_tuple_test.cpp ]
|
||||
[ run hash_std_smart_ptr_test.cpp ]
|
||||
[ run link_test.cpp link_test_2.cpp ]
|
||||
[ run link_ext_test.cpp link_no_ext_test.cpp ]
|
||||
[ run container_fwd_test.cpp ]
|
||||
[ run extensions_hpp_test.cpp ]
|
||||
[ compile-fail hash_no_ext_fail_test.cpp ]
|
||||
[ compile-fail namespace_fail_test.cpp ]
|
||||
[ run implicit_test.cpp ]
|
||||
[ run hash_no_ext_macro_1.cpp ]
|
||||
[ run hash_no_ext_macro_2.cpp ]
|
||||
;
|
||||
|
||||
test-suite functional/hash_no_ext
|
||||
:
|
||||
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
|
||||
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
|
||||
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
|
||||
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
|
||||
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
|
||||
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
|
||||
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
|
||||
;
|
||||
|
||||
# Tests to see if the floating point hash is using the binary hash.
|
||||
# Not run normally because on some platforms these should fail.
|
||||
test-suite functional/hash_no_generic_float
|
||||
:
|
||||
[ run hash_float_test.cpp
|
||||
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||
: hash_float_test_no_generic ]
|
||||
[ run hash_long_double_test.cpp
|
||||
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||
: hash_long_double_test_no_generic ]
|
||||
;
|
||||
explicit functional/hash_no_generic_float ;
|
||||
|
||||
build-project ../examples ;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
@@ -11,6 +11,6 @@ template <class T>
|
||||
void compile_time_tests(T*)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
|
||||
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
|
||||
};
|
||||
std::unary_function<T, std::size_t>, BOOST_HASH_TEST_NAMESPACE::hash<T> >::value));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if defined(TEST_STD)
|
||||
# define TEST_STD_INCLUDES
|
||||
# define HASH_NAMESPACE std::tr1
|
||||
#if defined(BOOST_HASH_TEST_STD)
|
||||
# define BOOST_HASH_TEST_STD_INCLUDES
|
||||
# define BOOST_HASH_TEST_NAMESPACE std
|
||||
#else
|
||||
# define HASH_NAMESPACE boost
|
||||
# define BOOST_HASH_TEST_NAMESPACE boost
|
||||
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# define TEST_EXTENSIONS
|
||||
# define BOOST_HASH_TEST_EXTENSIONS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
// The standard windows mobile headers trigger this warning so I disable it
|
||||
// before doing anything else.
|
||||
#pragma warning(disable:4201) // nonstandard extension used :
|
||||
// nameless struct/union
|
||||
#endif
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/functional/detail/container_fwd.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
||||
template <class charT, class Allocator>
|
||||
static void test(std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
|
||||
{
|
||||
}
|
||||
#else
|
||||
template <class charT, class Allocator>
|
||||
static void test(std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class T, class Allocator>
|
||||
static void test(std::deque<T, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
static void test(std::list<T, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
static void test(std::vector<T, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
static void test(std::map<Key, T, Compare, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Key, class T, class Compare, class Allocator>
|
||||
static void test(std::multimap<Key, T, Compare, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Key, class Compare, class Allocator>
|
||||
static void test(std::set<Key, Compare, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Key, class Compare, class Allocator>
|
||||
static void test(std::multiset<Key, Compare, Allocator> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
static void test(std::bitset<N> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static void test(std::complex<T> const&)
|
||||
{
|
||||
}
|
||||
|
||||
template <class X, class Y>
|
||||
static void test(std::pair<X, Y> const&)
|
||||
{
|
||||
}
|
||||
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
#include <complex>
|
||||
#include <utility>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::deque<int> x1;
|
||||
std::list<std::string> x2;
|
||||
std::vector<float> x3;
|
||||
std::vector<bool> x4;
|
||||
std::map<int, int> x5;
|
||||
std::multimap<float, int*> x6;
|
||||
std::set<std::string> x7;
|
||||
std::multiset<std::vector<int> > x8;
|
||||
std::bitset<10> x9;
|
||||
std::string x10;
|
||||
std::complex<double> x11;
|
||||
std::pair<std::list<int>, char***> x12;
|
||||
|
||||
test(x1);
|
||||
test(x2);
|
||||
test(x3);
|
||||
test(x4);
|
||||
test(x5);
|
||||
test(x6);
|
||||
test(x7);
|
||||
test(x8);
|
||||
test(x9);
|
||||
test(x10);
|
||||
test(x11);
|
||||
test(x12);
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
test/extensions_hpp_test.cpp
Normal file
19
test/extensions_hpp_test.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
// Copyright 2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Check that boost/functional/hash/extensions.hpp works okay.
|
||||
//
|
||||
// It probably should be in boost/functional/hash/detail, but since it isn't it
|
||||
// should work.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash/extensions.hpp>
|
||||
|
||||
int main() {
|
||||
int x[2] = { 2, 3 };
|
||||
boost::hash<int[2]> hf;
|
||||
hf(x);
|
||||
}
|
||||
13
test/extra/Jamfile.v2
Normal file
13
test/extra/Jamfile.v2
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
# Copyright 2012 Daniel James.
|
||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
import testing ;
|
||||
|
||||
build-project .. ;
|
||||
|
||||
test-suite functional/hash/config
|
||||
:
|
||||
[ compile check_float_funcs.cpp ]
|
||||
;
|
||||
58
test/extra/check_float_funcs.cpp
Normal file
58
test/extra/check_float_funcs.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <cmath>
|
||||
|
||||
namespace test
|
||||
{
|
||||
template <class T1>
|
||||
struct check_return_type
|
||||
{
|
||||
template <class T2>
|
||||
static void equals(T2)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
static void equals_ref(T2&)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
static void convertible(T2)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int main() {
|
||||
float f = 0;
|
||||
double d = 0;
|
||||
long double l = 0;
|
||||
|
||||
test::check_return_type<float>::equals(std::ldexp(f, 0));
|
||||
test::check_return_type<double>::equals(std::ldexp(d, 0));
|
||||
test::check_return_type<long double>::equals(std::ldexp(l, 0));
|
||||
|
||||
int dummy = 0;
|
||||
|
||||
test::check_return_type<float>::equals(std::frexp(f, &dummy));
|
||||
test::check_return_type<double>::equals(std::frexp(d, &dummy));
|
||||
test::check_return_type<long double>::equals(std::frexp(l, &dummy));
|
||||
|
||||
#if BOOST_HASH_USE_FPCLASSIFY
|
||||
|
||||
int (*fpc1)(float) = std::fpclassify;
|
||||
int (*fpc2)(double) = std::fpclassify;
|
||||
int (*fpc3)(long double) = std::fpclassify;
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
void array_int_test()
|
||||
{
|
||||
@@ -27,47 +27,47 @@ void array_int_test()
|
||||
8, -12, 23, 65, 45,
|
||||
-1, 93, -54, 987, 3
|
||||
};
|
||||
HASH_NAMESPACE::hash<int[25]> hasher1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
|
||||
|
||||
const int length2 = 1;
|
||||
int array2[1] = {3};
|
||||
HASH_NAMESPACE::hash<int[1]> hasher2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
|
||||
|
||||
const int length3 = 2;
|
||||
int array3[2] = {2, 3};
|
||||
HASH_NAMESPACE::hash<int[2]> hasher3;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
|
||||
|
||||
BOOST_TEST(hasher1(array1)
|
||||
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
|
||||
BOOST_TEST(hasher2(array2)
|
||||
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
|
||||
BOOST_TEST(hasher3(array3)
|
||||
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
|
||||
}
|
||||
|
||||
void two_dimensional_array_test()
|
||||
{
|
||||
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
|
||||
|
||||
std::size_t seed1 = 0;
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
std::size_t seed2 = 0;
|
||||
for(int j = 0; j < 2; ++j)
|
||||
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
|
||||
HASH_NAMESPACE::hash_combine(seed1, seed2);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
|
||||
}
|
||||
|
||||
BOOST_TEST(hasher(array) == seed1);
|
||||
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
|
||||
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
|
||||
}
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
array_int_test();
|
||||
two_dimensional_array_test();
|
||||
#endif
|
||||
|
||||
110
test/hash_complex_test.cpp
Normal file
110
test/hash_complex_test.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4244) // conversion from 'unsigned long' to
|
||||
// 'unsigned short', possible loss of data
|
||||
#pragma warning(disable:4245) // conversion from 'int' to
|
||||
// 'const unsigned short',
|
||||
// signed/unsigned mismatch
|
||||
#pragma warning(disable:4305) // truncation from 'double' to
|
||||
// 'const std::complex<float>::_Ty'
|
||||
#pragma warning(disable:4309) // truncation of constant value
|
||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||
#if BOOST_MSVC < 1400
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
#include <complex>
|
||||
#include <sstream>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
template <class T>
|
||||
void generic_complex_tests(std::complex<T> v)
|
||||
{
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
|
||||
|
||||
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
|
||||
T real = v.real();
|
||||
T imag = v.imag();
|
||||
|
||||
BOOST_TEST(real_hasher(real) == complex_hasher(std::complex<T>(real)));
|
||||
|
||||
if(imag != 0 && real_hasher(real) == complex_hasher(v)) {
|
||||
std::ostringstream os;
|
||||
os<<"real_hasher("<<real<<") == complex_hasher("
|
||||
<<v.real()<<" + "<<v.imag()<<"i) == "
|
||||
<<real_hasher(real)<<" (This might not be a bug).";
|
||||
BOOST_ERROR(os.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
template <class Float>
|
||||
void complex_float_tests(Float*)
|
||||
{
|
||||
typedef std::complex<Float> complex;
|
||||
generic_complex_tests(complex(0,0));
|
||||
generic_complex_tests(complex(0.5,0));
|
||||
generic_complex_tests(complex(25,0));
|
||||
generic_complex_tests(complex(25,0));
|
||||
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void complex_integral_tests(Integer*)
|
||||
{
|
||||
typedef std::complex<Integer> complex;
|
||||
generic_complex_tests(complex(0,0));
|
||||
generic_complex_tests(complex(15342,124));
|
||||
generic_complex_tests(complex(25,54356));
|
||||
generic_complex_tests(complex(5325,2346));
|
||||
generic_complex_tests(complex(-243897,-49923874));
|
||||
generic_complex_tests(complex(-543,763));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// I've comments out the short and unsigned short tests
|
||||
// as they cause warnings and don't really test
|
||||
// anything that the other tests already deal with.
|
||||
|
||||
complex_float_tests((float*) 0);
|
||||
complex_float_tests((double*) 0);
|
||||
complex_float_tests((long double*) 0);
|
||||
//complex_integral_tests((short*) 0);
|
||||
complex_integral_tests((int*) 0);
|
||||
complex_integral_tests((long*) 0);
|
||||
//complex_integral_tests((unsigned short*) 0);
|
||||
complex_integral_tests((unsigned int*) 0);
|
||||
complex_integral_tests((unsigned long*) 0);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -40,8 +41,8 @@ namespace boost
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -50,7 +51,7 @@ namespace boost
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -58,13 +59,13 @@ namespace boost
|
||||
|
||||
void custom_tests()
|
||||
{
|
||||
HASH_NAMESPACE::hash<test::custom> custom_hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
|
||||
BOOST_TEST(custom_hasher(10) == 100u);
|
||||
test::custom x(55);
|
||||
BOOST_TEST(custom_hasher(x) == 550u);
|
||||
|
||||
{
|
||||
using namespace HASH_NAMESPACE;
|
||||
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||
}
|
||||
|
||||
@@ -74,25 +75,25 @@ void custom_tests()
|
||||
custom_vector.push_back(35);
|
||||
|
||||
std::size_t seed = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
|
||||
|
||||
std::size_t seed2 = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||
|
||||
BOOST_TEST(seed ==
|
||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == seed2);
|
||||
}
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
custom_tests();
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <deque>
|
||||
|
||||
@@ -23,11 +23,11 @@ using std::deque;
|
||||
#define CONTAINER_TYPE deque
|
||||
#include "./hash_sequence_test.hpp"
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
deque_tests::deque_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
|
||||
63
test/hash_enum_test.cpp
Normal file
63
test/hash_enum_test.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
namespace test {
|
||||
enum enum_override { enum_override1, enum_override2 };
|
||||
std::size_t hash_value(enum_override) { return 896532; }
|
||||
|
||||
enum enum1 { enum1a };
|
||||
enum enum2 { enum2a, enum2b };
|
||||
enum enum3 { enum3a = 574, enum3b };
|
||||
enum enum4 { enum4a = -12574, enum4b };
|
||||
}
|
||||
|
||||
int main() {
|
||||
compile_time_tests((test::enum1*) 0);
|
||||
compile_time_tests((test::enum2*) 0);
|
||||
compile_time_tests((test::enum3*) 0);
|
||||
compile_time_tests((test::enum4*) 0);
|
||||
compile_time_tests((test::enum_override*) 0);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::enum1> hash1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::enum2> hash2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::enum3> hash3;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::enum4> hash4;
|
||||
|
||||
BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
|
||||
|
||||
BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
|
||||
BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
|
||||
BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
|
||||
|
||||
BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
|
||||
BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
|
||||
BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
|
||||
|
||||
BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
|
||||
BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
|
||||
BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::enum_override> hash_override;
|
||||
|
||||
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||
hash_override(test::enum_override1));
|
||||
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||
hash_override(test::enum_override2));
|
||||
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||
hash_override(test::enum_override1));
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,223 +1,18 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
#include "hash_float_test.hpp"
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
void float_tests(char const* name, T* = 0)
|
||||
{
|
||||
std::cerr<<"\n"
|
||||
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
|
||||
<<"\n"
|
||||
<<"std::numeric_limits<T>::digits = "
|
||||
<<std::numeric_limits<T>::digits<<"\n"
|
||||
<<"std::numeric_limits<int>::digits = "
|
||||
<<std::numeric_limits<int>::digits<<"\n"
|
||||
<<"std::numeric_limits<std::size_t>::digits = "
|
||||
<<std::numeric_limits<std::size_t>::digits<<"\n"
|
||||
<<"\n"
|
||||
;
|
||||
|
||||
HASH_NAMESPACE::hash<T> x1;
|
||||
|
||||
T zero = 0;
|
||||
T minus_zero = (T) -1 * zero;
|
||||
|
||||
BOOST_TEST(zero == minus_zero);
|
||||
BOOST_TEST(x1(zero) == x1(minus_zero));
|
||||
|
||||
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
|
||||
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Doing anything with infinity causes borland to crash.
|
||||
#if defined(__BORLANDC__)
|
||||
std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n";
|
||||
#else
|
||||
if(std::numeric_limits<T>::has_infinity) {
|
||||
T infinity = -log(zero);
|
||||
T infinity2 = (T) 1. / zero;
|
||||
T infinity3 = (T) -1. / minus_zero;
|
||||
T infinity4 = std::numeric_limits<T>::infinity();
|
||||
|
||||
T minus_infinity = log(zero);
|
||||
T minus_infinity2 = (T) -1. / zero;
|
||||
T minus_infinity3 = (T) 1. / minus_zero;
|
||||
|
||||
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
|
||||
BOOST_TEST(x1(minus_infinity)
|
||||
== HASH_NAMESPACE::hash_value(minus_infinity));
|
||||
|
||||
if(infinity == infinity2)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity2));
|
||||
if(infinity == infinity3);
|
||||
BOOST_TEST(x1(infinity) == x1(infinity3));
|
||||
if(infinity == infinity4)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity4));
|
||||
|
||||
if(minus_infinity == minus_infinity2)
|
||||
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
|
||||
if(minus_infinity == minus_infinity3)
|
||||
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
|
||||
|
||||
BOOST_TEST(infinity != minus_infinity);
|
||||
|
||||
if(x1(infinity) == x1(minus_infinity)) {
|
||||
std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
|
||||
}
|
||||
|
||||
// This should really be 'has_denorm == denorm_present' but some
|
||||
// compilers don't have 'denorm_present'. See also a later use.
|
||||
if(std::numeric_limits<T>::has_denorm) {
|
||||
if(x1(std::numeric_limits<T>::denorm_min()) == x1(infinity)) {
|
||||
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
|
||||
}
|
||||
if(x1(std::numeric_limits<T>::denorm_min()) == x1(minus_infinity)) {
|
||||
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
||||
}
|
||||
}
|
||||
if(std::numeric_limits<T>::has_quiet_NaN) {
|
||||
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(infinity)) {
|
||||
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
|
||||
}
|
||||
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(minus_infinity)) {
|
||||
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
T max = (std::numeric_limits<T>::max)();
|
||||
T half_max = max / 2;
|
||||
T quarter_max = max / 4;
|
||||
T three_quarter_max = max - quarter_max;
|
||||
|
||||
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
|
||||
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
|
||||
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
|
||||
|
||||
// The '!=' tests could legitimately fail, but with my hash it indicates a bug.
|
||||
BOOST_TEST(x1(max) == x1(max));
|
||||
BOOST_TEST(x1(max) != x1(quarter_max));
|
||||
BOOST_TEST(x1(max) != x1(half_max));
|
||||
BOOST_TEST(x1(max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(quarter_max) == x1(quarter_max));
|
||||
BOOST_TEST(x1(quarter_max) != x1(half_max));
|
||||
BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(half_max) == x1(half_max));
|
||||
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
|
||||
|
||||
T v1 = asin((T) 1);
|
||||
T v2 = acos((T) 0);
|
||||
if(v1 == v2)
|
||||
BOOST_TEST(x1(v1) == x1(v2));
|
||||
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
|
||||
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
|
||||
|
||||
BOOST_TEST(x1(std::numeric_limits<T>::epsilon()) ==
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
|
||||
|
||||
BOOST_TEST(std::numeric_limits<T>::epsilon() != (T) 0);
|
||||
if(x1(std::numeric_limits<T>::epsilon()) == x1((T) 0))
|
||||
std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||
|
||||
BOOST_TEST(-std::numeric_limits<T>::epsilon() != (T) 0);
|
||||
if(x1(-std::numeric_limits<T>::epsilon()) == x1((T) 0))
|
||||
std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||
|
||||
BOOST_TEST((T) 1 + std::numeric_limits<T>::epsilon() != (T) 1);
|
||||
if(x1((T) 1 + std::numeric_limits<T>::epsilon()) == x1((T) 1))
|
||||
std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) 1 - std::numeric_limits<T>::epsilon() != (T) 1);
|
||||
if(x1((T) 1 - std::numeric_limits<T>::epsilon()) == x1((T) 1))
|
||||
std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) -1 + std::numeric_limits<T>::epsilon() != (T) -1);
|
||||
if(x1((T) -1 + std::numeric_limits<T>::epsilon()) == x1((T) -1))
|
||||
std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) -1 - std::numeric_limits<T>::epsilon() != (T) -1);
|
||||
if(x1((T) -1 - std::numeric_limits<T>::epsilon()) == x1((T) -1))
|
||||
std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||
|
||||
// As before.
|
||||
if(std::numeric_limits<T>::has_denorm) {
|
||||
if(x1(std::numeric_limits<T>::denorm_min()) == x1(zero)) {
|
||||
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
||||
}
|
||||
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
|
||||
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
||||
// specialization of std::numeric_limits::denorm_min() for long
|
||||
// doubles which causes this test to fail.
|
||||
if(x1(std::numeric_limits<T>::denorm_min()) !=
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()))
|
||||
{
|
||||
std::cerr<<"x1(std::numeric_limits<T>::denorm_min()) = "
|
||||
<< x1(std::numeric_limits<T>::denorm_min())
|
||||
<< "\nhash_value(std::numeric_limits<T>::denorm_min()) = "
|
||||
<< HASH_NAMESPACE::hash_value(
|
||||
std::numeric_limits<T>::denorm_min())
|
||||
<< "\nx1(0) = "<<x1(0)<<"\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// NaN also causes borland to crash.
|
||||
#if !defined(__BORLANDC__)
|
||||
if(std::numeric_limits<T>::has_quiet_NaN) {
|
||||
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(1.0)) {
|
||||
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
||||
}
|
||||
BOOST_TEST(x1(std::numeric_limits<T>::quiet_NaN()) ==
|
||||
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void hash_float_tests()
|
||||
int main()
|
||||
{
|
||||
std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
|
||||
std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
|
||||
std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
|
||||
|
||||
float_tests("float", (float*) 0);
|
||||
}
|
||||
|
||||
void hash_double_tests()
|
||||
{
|
||||
float_tests("double", (double*) 0);
|
||||
}
|
||||
|
||||
void hash_long_double_tests()
|
||||
{
|
||||
float_tests("long double", (long double*) 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
hash_float_tests();
|
||||
hash_double_tests();
|
||||
hash_long_double_tests();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
309
test/hash_float_test.hpp
Normal file
309
test/hash_float_test.hpp
Normal file
@@ -0,0 +1,309 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4723) // conditional expression is constant
|
||||
#if BOOST_MSVC < 1400
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
char const* float_type(float*) { return "float"; }
|
||||
char const* float_type(double*) { return "double"; }
|
||||
char const* float_type(long double*) { return "long double"; }
|
||||
|
||||
template <class T>
|
||||
void float_tests(char const* name, T* = 0)
|
||||
{
|
||||
std::cerr
|
||||
<< "\n"
|
||||
<< "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
|
||||
<< name
|
||||
<< ">\n"
|
||||
<< "\n"
|
||||
<< "boost::hash_detail::limits<T>::digits = "
|
||||
<< boost::hash_detail::limits<T>::digits<< "\n"
|
||||
<< "boost::hash_detail::limits<int>::digits = "
|
||||
<< boost::hash_detail::limits<int>::digits<< "\n"
|
||||
<< "boost::hash_detail::limits<std::size_t>::digits = "
|
||||
<< boost::hash_detail::limits<std::size_t>::digits
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
<< "boost::hash_detail::call_ldexp<T>::float_type = "
|
||||
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||
boost::hash_detail::call_ldexp<T>::float_type*>(0))
|
||||
<< "\n"
|
||||
<< "boost::hash_detail::call_frexp<T>::float_type = "
|
||||
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||
boost::hash_detail::call_frexp<T>::float_type*>(0))
|
||||
<< "\n"
|
||||
<< "boost::hash_detail::select_hash_type<T>::type = "
|
||||
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||
boost::hash_detail::select_hash_type<T>::type*>(0))
|
||||
<< "\n"
|
||||
<< "\n"
|
||||
;
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||
|
||||
T zero = 0;
|
||||
T minus_zero = (T) -1 * zero;
|
||||
|
||||
BOOST_TEST(zero == minus_zero);
|
||||
BOOST_TEST(x1(zero) == x1(minus_zero));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
|
||||
BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
|
||||
#endif
|
||||
|
||||
BOOST_TEST(x1(zero) != x1(0.5));
|
||||
BOOST_TEST(x1(minus_zero) != x1(0.5));
|
||||
BOOST_TEST(x1(0.5) != x1(-0.5));
|
||||
BOOST_TEST(x1(1) != x1(-1));
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Doing anything with infinity causes borland to crash.
|
||||
#if defined(__BORLANDC__)
|
||||
std::cerr
|
||||
<< "Not running infinity checks on Borland, as it causes it to crash."
|
||||
"\n";
|
||||
#else
|
||||
if(boost::hash_detail::limits<T>::has_infinity) {
|
||||
T infinity = -log(zero);
|
||||
T infinity2 = (T) 1. / zero;
|
||||
T infinity3 = (T) -1. / minus_zero;
|
||||
T infinity4 = boost::hash_detail::limits<T>::infinity();
|
||||
|
||||
T minus_infinity = log(zero);
|
||||
T minus_infinity2 = (T) -1. / zero;
|
||||
T minus_infinity3 = (T) 1. / minus_zero;
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
|
||||
BOOST_TEST(x1(minus_infinity)
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
|
||||
#endif
|
||||
|
||||
if(infinity == infinity2)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity2));
|
||||
if(infinity == infinity3)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity3));
|
||||
if(infinity == infinity4)
|
||||
BOOST_TEST(x1(infinity) == x1(infinity4));
|
||||
|
||||
if(minus_infinity == minus_infinity2)
|
||||
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
|
||||
if(minus_infinity == minus_infinity3)
|
||||
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
|
||||
|
||||
BOOST_TEST(infinity != minus_infinity);
|
||||
|
||||
if(x1(infinity) == x1(minus_infinity)) {
|
||||
std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
|
||||
}
|
||||
|
||||
// This should really be 'has_denorm == denorm_present' but some
|
||||
// compilers don't have 'denorm_present'. See also a later use.
|
||||
if(boost::hash_detail::limits<T>::has_denorm) {
|
||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
|
||||
{
|
||||
std::cerr
|
||||
<< "x1(denorm_min) == x1(infinity) == "
|
||||
<< x1(infinity)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) ==
|
||||
x1(minus_infinity))
|
||||
{
|
||||
std::cerr
|
||||
<< "x1(denorm_min) == x1(-infinity) == "
|
||||
<< x1(minus_infinity)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
|
||||
{
|
||||
std::cerr
|
||||
<< "x1(quiet_NaN) == x1(infinity) == "
|
||||
<< x1(infinity)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
|
||||
x1(minus_infinity))
|
||||
{
|
||||
std::cerr
|
||||
<< "x1(quiet_NaN) == x1(-infinity) == "
|
||||
<< x1(minus_infinity)
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
T max = (boost::hash_detail::limits<T>::max)();
|
||||
T half_max = max / 2;
|
||||
T quarter_max = max / 4;
|
||||
T three_quarter_max = max - quarter_max;
|
||||
|
||||
// Check the limits::max is in range.
|
||||
BOOST_TEST(max != half_max);
|
||||
BOOST_TEST(max != quarter_max);
|
||||
BOOST_TEST(max != three_quarter_max);
|
||||
BOOST_TEST(half_max != quarter_max);
|
||||
BOOST_TEST(half_max != three_quarter_max);
|
||||
BOOST_TEST(quarter_max != three_quarter_max);
|
||||
|
||||
BOOST_TEST(max != -max);
|
||||
BOOST_TEST(half_max != -half_max);
|
||||
BOOST_TEST(quarter_max != -quarter_max);
|
||||
BOOST_TEST(three_quarter_max != -three_quarter_max);
|
||||
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
|
||||
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
|
||||
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
|
||||
#endif
|
||||
|
||||
// The '!=' tests could legitimately fail, but with my hash it indicates a
|
||||
// bug.
|
||||
BOOST_TEST(x1(max) == x1(max));
|
||||
BOOST_TEST(x1(max) != x1(quarter_max));
|
||||
BOOST_TEST(x1(max) != x1(half_max));
|
||||
BOOST_TEST(x1(max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(quarter_max) == x1(quarter_max));
|
||||
BOOST_TEST(x1(quarter_max) != x1(half_max));
|
||||
BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(half_max) == x1(half_max));
|
||||
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
|
||||
|
||||
BOOST_TEST(x1(max) != x1(-max));
|
||||
BOOST_TEST(x1(half_max) != x1(-half_max));
|
||||
BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
|
||||
BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
|
||||
|
||||
|
||||
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
|
||||
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
|
||||
defined(__ICC) || defined(__ECC)) && \
|
||||
(defined(__GLIBCPP__) || defined(__GLIBCXX__)))
|
||||
T v1 = asin((T) 1);
|
||||
T v2 = acos((T) 0);
|
||||
if(v1 == v2)
|
||||
BOOST_TEST(x1(v1) == x1(v2));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
|
||||
BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||
boost::hash_detail::limits<T>::epsilon()));
|
||||
#endif
|
||||
|
||||
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
|
||||
if(x1(boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
|
||||
std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||
|
||||
BOOST_TEST(-boost::hash_detail::limits<T>::epsilon() != (T) 0);
|
||||
if(x1(-boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
|
||||
std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
|
||||
|
||||
BOOST_TEST((T) 1 + boost::hash_detail::limits<T>::epsilon() != (T) 1);
|
||||
if(x1((T) 1 + boost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
|
||||
std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) 1 - boost::hash_detail::limits<T>::epsilon() != (T) 1);
|
||||
if(x1((T) 1 - boost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
|
||||
std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) -1 + boost::hash_detail::limits<T>::epsilon() != (T) -1);
|
||||
if(x1((T) -1 + boost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
|
||||
std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||
|
||||
BOOST_TEST((T) -1 - boost::hash_detail::limits<T>::epsilon() != (T) -1);
|
||||
if(x1((T) -1 - boost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
|
||||
std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
|
||||
|
||||
// As before.
|
||||
if(boost::hash_detail::limits<T>::has_denorm) {
|
||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
|
||||
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
||||
}
|
||||
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
||||
// specialization of boost::hash_detail::limits::denorm_min() for long
|
||||
// doubles which causes this test to fail.
|
||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||
boost::hash_detail::limits<T>::denorm_min()))
|
||||
{
|
||||
std::cerr
|
||||
<< "x1(boost::hash_detail::limits<T>::denorm_min()) = "
|
||||
<< x1(boost::hash_detail::limits<T>::denorm_min())
|
||||
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
|
||||
" = "
|
||||
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||
boost::hash_detail::limits<T>::denorm_min())
|
||||
<< "\nx1(0) = "
|
||||
<< x1(0)
|
||||
<< "\n";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// NaN also causes borland to crash.
|
||||
#if !defined(__BORLANDC__) && defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
|
||||
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
||||
}
|
||||
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||
boost::hash_detail::limits<T>::quiet_NaN()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
@@ -42,8 +44,8 @@ namespace boost
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -52,7 +54,7 @@ namespace boost
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -60,13 +62,13 @@ namespace boost
|
||||
|
||||
void custom_tests()
|
||||
{
|
||||
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
|
||||
BOOST_TEST(custom_hasher(10) == 100u);
|
||||
test::custom<int> x(55);
|
||||
BOOST_TEST(custom_hasher(x) == 550u);
|
||||
|
||||
{
|
||||
using namespace HASH_NAMESPACE;
|
||||
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||
}
|
||||
|
||||
@@ -76,25 +78,25 @@ void custom_tests()
|
||||
custom_vector.push_back(35);
|
||||
|
||||
std::size_t seed = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
|
||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
|
||||
|
||||
std::size_t seed2 = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||
|
||||
BOOST_TEST(seed ==
|
||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == seed2);
|
||||
}
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
custom_tests();
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
void void_func1() { static int x = 1; ++x; }
|
||||
@@ -29,8 +24,8 @@ void function_pointer_tests()
|
||||
compile_time_tests((void(**)()) 0);
|
||||
compile_time_tests((int(**)(int)) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<void(*)()> hasher_void;
|
||||
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
|
||||
|
||||
BOOST_TEST(&void_func1 != &void_func2);
|
||||
BOOST_TEST(&int_func1 != &int_func2);
|
||||
@@ -43,11 +38,11 @@ void function_pointer_tests()
|
||||
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
|
||||
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
|
||||
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(hasher_void(&void_func1)
|
||||
== HASH_NAMESPACE::hash_value(&void_func1));
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
|
||||
BOOST_TEST(hasher_int(&int_func1)
|
||||
== HASH_NAMESPACE::hash_value(&int_func1));
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
|
||||
|
||||
// This isn't specified in Peter's proposal:
|
||||
BOOST_TEST(hasher_void(0) == 0);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
@@ -25,7 +25,7 @@ namespace test {
|
||||
template <class T>
|
||||
std::size_t hash_value(test_type1<T> const& x)
|
||||
{
|
||||
HASH_NAMESPACE::hash<T> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
return hasher(x.value);
|
||||
}
|
||||
#endif
|
||||
@@ -42,8 +42,8 @@ namespace test {
|
||||
std::size_t hash_value(test_type2<T> const& x)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
||||
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
|
||||
return seed;
|
||||
}
|
||||
#endif
|
||||
@@ -60,8 +60,9 @@ namespace test {
|
||||
template <class T>
|
||||
std::size_t hash_value(test_type3<T> const& x)
|
||||
{
|
||||
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||
std::size_t seed =
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||
return seed;
|
||||
}
|
||||
#endif
|
||||
@@ -75,7 +76,7 @@ namespace boost
|
||||
template <class T>
|
||||
std::size_t hash_value(test::test_type1<T> const& x)
|
||||
{
|
||||
HASH_NAMESPACE::hash<T> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
return hasher(x.value);
|
||||
}
|
||||
|
||||
@@ -83,16 +84,17 @@ namespace boost
|
||||
std::size_t hash_value(test::test_type2<T> const& x)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
||||
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value(test::test_type3<T> const& x)
|
||||
{
|
||||
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||
std::size_t seed =
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This checks that template code implemented using hash_fwd will work.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <string>
|
||||
@@ -19,10 +21,10 @@ void fwd_test1()
|
||||
test::test_type1<int> x(5);
|
||||
test::test_type1<std::string> y("Test");
|
||||
|
||||
HASH_NAMESPACE::hash<int> hasher_int;
|
||||
HASH_NAMESPACE::hash<std::string> hasher_string;
|
||||
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
|
||||
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
|
||||
|
||||
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
|
||||
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
|
||||
@@ -34,15 +36,15 @@ void fwd_test2()
|
||||
test::test_type2<std::string> y("Test1", "Test2");
|
||||
|
||||
std::size_t seed1 = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed1, 5);
|
||||
HASH_NAMESPACE::hash_combine(seed1, 10);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
|
||||
|
||||
std::size_t seed2 = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
|
||||
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
|
||||
|
||||
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
|
||||
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
|
||||
|
||||
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||
@@ -66,14 +68,16 @@ void fwd_test3()
|
||||
test::test_type3<int> x(values1.begin(), values1.end());
|
||||
test::test_type3<std::string> y(values2.begin(), values2.end());
|
||||
|
||||
std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
|
||||
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
|
||||
std::size_t seed1 =
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
|
||||
|
||||
std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
|
||||
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
|
||||
std::size_t seed2 =
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
|
||||
|
||||
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
|
||||
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
|
||||
|
||||
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||
@@ -83,11 +87,10 @@ void fwd_test3()
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
fwd_test1();
|
||||
fwd_test2();
|
||||
fwd_test3();
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This test just makes sure a header which uses hash_fwd can compile without
|
||||
// the main hash headers.
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
#include "./config.hpp"
|
||||
|
||||
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
template <class T> void unused(T const&) {}
|
||||
@@ -30,10 +37,11 @@ void fwd_test()
|
||||
unused(y1); unused(y2); unused(y3);
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
fwd_test();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
|
||||
// in the global namespace.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -40,17 +42,17 @@ namespace boost
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash/hash.hpp>
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -58,13 +60,13 @@ namespace boost
|
||||
|
||||
void custom_tests()
|
||||
{
|
||||
HASH_NAMESPACE::hash<custom> custom_hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
|
||||
BOOST_TEST(custom_hasher(10) == 100u);
|
||||
custom x(55);
|
||||
BOOST_TEST(custom_hasher(x) == 550u);
|
||||
|
||||
{
|
||||
using namespace HASH_NAMESPACE;
|
||||
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||
}
|
||||
|
||||
@@ -74,26 +76,26 @@ void custom_tests()
|
||||
custom_vector.push_back(35);
|
||||
|
||||
std::size_t seed = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed, custom(5));
|
||||
HASH_NAMESPACE::hash_combine(seed, custom(25));
|
||||
HASH_NAMESPACE::hash_combine(seed, custom(35));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
|
||||
|
||||
std::size_t seed2 = 0;
|
||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||
|
||||
BOOST_TEST(seed ==
|
||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
custom_vector.begin(), custom_vector.end()));
|
||||
BOOST_TEST(seed == seed2);
|
||||
}
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
custom_tests();
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <list>
|
||||
|
||||
@@ -23,11 +23,11 @@ using std::list;
|
||||
#define CONTAINER_TYPE list
|
||||
#include "./hash_sequence_test.hpp"
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
list_tests::list_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
|
||||
17
test/hash_long_double_test.cpp
Normal file
17
test/hash_long_double_test.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "hash_float_test.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
|
||||
std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
|
||||
std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
|
||||
|
||||
float_tests("long double", (long double*) 0);
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
using std::map;
|
||||
#define CONTAINER_TYPE map
|
||||
@@ -27,11 +27,11 @@ using std::multimap;
|
||||
#define CONTAINER_TYPE multimap
|
||||
#include "./hash_map_test.hpp"
|
||||
|
||||
#endif // TEST_EXTENSTIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
map_tests::map_hash_integer_tests();
|
||||
multimap_tests::multimap_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(CONTAINER_TYPE)
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
@@ -9,6 +9,12 @@
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4244) // conversion from 'int' to 'float'
|
||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||
#endif
|
||||
|
||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
@@ -16,30 +22,32 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
const int number_of_containers = 10;
|
||||
T containers[number_of_containers];
|
||||
typedef typename T::value_type pair;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
|
||||
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
for(int j = 0; j < i; ++j)
|
||||
containers[i].insert(pair(0, 0));
|
||||
containers[i].insert(pair(key(0), value(0)));
|
||||
}
|
||||
|
||||
containers[6].insert(pair(1,0));
|
||||
containers[7].insert(pair(1,0));
|
||||
containers[7].insert(pair(1,0));
|
||||
containers[8].insert(pair(-1,1));
|
||||
containers[9].insert(pair(-1,3));
|
||||
containers[9].insert(pair(-1,3));
|
||||
containers[6].insert(pair(key(1),value(0)));
|
||||
containers[7].insert(pair(key(1),value(0)));
|
||||
containers[7].insert(pair(key(1),value(0)));
|
||||
containers[8].insert(pair(key(-1),value(1)));
|
||||
containers[9].insert(pair(key(-1),value(3)));
|
||||
containers[9].insert(pair(key(-1),value(3)));
|
||||
|
||||
HASH_NAMESPACE::hash<T> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
|
||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2]) ==
|
||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2])
|
||||
== HASH_NAMESPACE::hash_range(
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
containers[i2].begin(), containers[i2].end()));
|
||||
|
||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||
@@ -60,5 +68,9 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#undef CONTAINER_TYPE
|
||||
#endif
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
#include "./config.hpp"
|
||||
|
||||
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
|
||||
// (or at least one of them).
|
||||
#define BOOST_HASH_NO_EXTENSIONS
|
||||
#if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# define BOOST_HASH_NO_EXTENSIONS
|
||||
#endif
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
template <class T> void ignore(T const&) {}
|
||||
|
||||
int main()
|
||||
{
|
||||
HASH_NAMESPACE::hash< int[10] > hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
|
||||
ignore(hasher);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
|
||||
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
||||
# if defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# undef BOOST_HASH_NO_EXTENSIONS
|
||||
# endif
|
||||
# include <boost/functional/hash.hpp>
|
||||
|
||||
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
||||
# define BOOST_HASH_NO_EXTENSIONS
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
#include <boost/functional/hash.hpp>
|
||||
#define BOOST_HASH_NO_EXTENSIONS
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <deque>
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::deque<int> x;
|
||||
|
||||
x.push_back(1);
|
||||
x.push_back(2);
|
||||
|
||||
HASH_NAMESPACE::hash<std::deque<int> > hasher;
|
||||
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
|
||||
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
|
||||
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
||||
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# define BOOST_HASH_NO_EXTENSIONS
|
||||
# endif
|
||||
# include <boost/functional/hash.hpp>
|
||||
|
||||
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
||||
# undef BOOST_HASH_NO_EXTENSIONS
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
#define BOOST_HASH_NO_EXTENSIONS
|
||||
#include <boost/functional/hash.hpp>
|
||||
#undef BOOST_HASH_NO_EXTENSIONS
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <map>
|
||||
|
||||
int main()
|
||||
{
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::map<int, int> x;
|
||||
|
||||
x.insert(std::map<int, int>::value_type(53, -42));
|
||||
x.insert(std::map<int, int>::value_type(14, -75));
|
||||
|
||||
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
|
||||
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
|
||||
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,23 +15,57 @@
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4309) // truncation of constant value
|
||||
#pragma warning(disable:4310) // cast truncates constant value
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
void numeric_extra_tests(typename
|
||||
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
|
||||
void*>::type = 0)
|
||||
{
|
||||
typedef boost::hash_detail::limits<T> limits;
|
||||
|
||||
if(limits::is_signed ||
|
||||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
|
||||
{
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
|
||||
}
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void numeric_extra_tests(typename
|
||||
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
|
||||
void*>::type = 0)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void numeric_test(T*)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
typedef boost::hash_detail::limits<T> limits;
|
||||
|
||||
compile_time_tests((T*) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<T> x1;
|
||||
HASH_NAMESPACE::hash<T> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||
|
||||
T v1 = -5;
|
||||
T v1 = (T) -5;
|
||||
BOOST_TEST(x1(v1) == x2(v1));
|
||||
BOOST_TEST(x1(T(-5)) == x2(T(-5)));
|
||||
BOOST_TEST(x1(T(0)) == x2(T(0)));
|
||||
@@ -40,31 +74,25 @@ void numeric_test(T*)
|
||||
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
|
||||
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
|
||||
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
|
||||
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
|
||||
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
|
||||
BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
|
||||
BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
|
||||
BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
|
||||
|
||||
if (limits::is_integer)
|
||||
{
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
|
||||
}
|
||||
numeric_extra_tests<T>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void limits_test(T*)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
typedef boost::hash_detail::limits<T> limits;
|
||||
|
||||
if(limits::is_specialized)
|
||||
{
|
||||
HASH_NAMESPACE::hash<T> x1;
|
||||
HASH_NAMESPACE::hash<T> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||
|
||||
T min_value = (limits::min)();
|
||||
T max_value = (limits::max)();
|
||||
@@ -72,15 +100,15 @@ void limits_test(T*)
|
||||
BOOST_TEST(x1(min_value) == x2((limits::min)()));
|
||||
BOOST_TEST(x1(max_value) == x2((limits::max)()));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
|
||||
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
|
||||
BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
|
||||
|
||||
if (limits::is_integer)
|
||||
{
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
|
||||
== std::size_t(min_value));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
|
||||
== std::size_t(max_value));
|
||||
}
|
||||
#endif
|
||||
@@ -90,10 +118,10 @@ void limits_test(T*)
|
||||
template <class T>
|
||||
void poor_quality_tests(T*)
|
||||
{
|
||||
typedef std::numeric_limits<T> limits;
|
||||
typedef boost::hash_detail::limits<T> limits;
|
||||
|
||||
HASH_NAMESPACE::hash<T> x1;
|
||||
HASH_NAMESPACE::hash<T> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||
|
||||
// A hash function can legally fail these tests, but it'll not be a good
|
||||
// sign.
|
||||
@@ -102,19 +130,33 @@ void poor_quality_tests(T*)
|
||||
if(T(1) != T(2))
|
||||
BOOST_TEST(x1(T(1)) != x2(T(2)));
|
||||
if((limits::max)() != (limits::max)() - 1)
|
||||
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1));
|
||||
BOOST_TEST(x1(static_cast<T>((limits::max)()))
|
||||
!= x2(static_cast<T>((limits::max)() - 1)));
|
||||
}
|
||||
|
||||
void bool_test()
|
||||
{
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
|
||||
|
||||
BOOST_TEST(x1(true) == x2(true));
|
||||
BOOST_TEST(x1(false) == x2(false));
|
||||
BOOST_TEST(x1(true) != x2(false));
|
||||
BOOST_TEST(x1(false) != x2(true));
|
||||
}
|
||||
|
||||
#define NUMERIC_TEST(type, name) \
|
||||
std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
|
||||
numeric_test((type*) 0); \
|
||||
limits_test((type*) 0); \
|
||||
poor_quality_tests((type*) 0);
|
||||
#define NUMERIC_TEST_NO_LIMITS(type, name) \
|
||||
std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
|
||||
numeric_test((type*) 0); \
|
||||
poor_quality_tests((type*) 0);
|
||||
|
||||
int main()
|
||||
{
|
||||
NUMERIC_TEST(bool, bool)
|
||||
NUMERIC_TEST(char, char)
|
||||
NUMERIC_TEST(signed char, schar)
|
||||
NUMERIC_TEST(unsigned char, uchar)
|
||||
@@ -128,11 +170,27 @@ int main()
|
||||
NUMERIC_TEST(long, hash_long)
|
||||
NUMERIC_TEST(unsigned long, ulong)
|
||||
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
|
||||
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
|
||||
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
|
||||
#endif
|
||||
|
||||
NUMERIC_TEST(float, float)
|
||||
NUMERIC_TEST(double, double)
|
||||
NUMERIC_TEST(long double, ldouble)
|
||||
|
||||
NUMERIC_TEST(std::size_t, size_t)
|
||||
NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
|
||||
|
||||
bool_test();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
void pointer_tests()
|
||||
@@ -24,8 +20,8 @@ void pointer_tests()
|
||||
compile_time_tests((int**) 0);
|
||||
compile_time_tests((void**) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<int*> x1;
|
||||
HASH_NAMESPACE::hash<int*> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
|
||||
|
||||
int int1;
|
||||
int int2;
|
||||
@@ -33,9 +29,9 @@ void pointer_tests()
|
||||
BOOST_TEST(x1(0) == x2(0));
|
||||
BOOST_TEST(x1(&int1) == x2(&int1));
|
||||
BOOST_TEST(x1(&int2) == x2(&int2));
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
|
||||
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
|
||||
BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
|
||||
|
||||
// This isn't specified in Peter's proposal:
|
||||
BOOST_TEST(x1(0) == 0);
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
|
||||
int main() {}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <vector>
|
||||
|
||||
void hash_range_tests()
|
||||
@@ -41,41 +40,41 @@ void hash_range_tests()
|
||||
std::vector<int> x;
|
||||
|
||||
std::size_t x_seed = 0;
|
||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
|
||||
|
||||
x.push_back(10);
|
||||
HASH_NAMESPACE::hash_combine(x_seed, 10);
|
||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
|
||||
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
|
||||
x.push_back(20);
|
||||
HASH_NAMESPACE::hash_combine(x_seed, 20);
|
||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
|
||||
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
|
||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||
|
||||
std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
|
||||
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
|
||||
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
|
||||
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
|
||||
std::size_t seed =
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
|
||||
BOOST_TEST(seed ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
hash_range_tests();
|
||||
@@ -83,3 +82,4 @@ int main()
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
#endif // TEST_EXTESNIONS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(CONTAINER_TYPE)
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
@@ -9,6 +9,11 @@
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||
#endif
|
||||
|
||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
@@ -33,16 +38,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
containers[10].push_back(-1);
|
||||
containers[10].push_back(1);
|
||||
|
||||
HASH_NAMESPACE::hash<T> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
|
||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2]) ==
|
||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2])
|
||||
== HASH_NAMESPACE::hash_range(
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
containers[i2].begin(), containers[i2].end()));
|
||||
|
||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||
@@ -63,5 +68,9 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#undef CONTAINER_TYPE
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <set>
|
||||
|
||||
@@ -31,7 +31,7 @@ using std::multiset;
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
set_tests::set_hash_integer_tests();
|
||||
multiset_tests::multiset_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(CONTAINER_TYPE)
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
@@ -9,12 +9,17 @@
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||
#endif
|
||||
|
||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
void integer_tests(T* = 0)
|
||||
{
|
||||
const int number_of_containers = 11;
|
||||
const int number_of_containers = 12;
|
||||
T containers[number_of_containers];
|
||||
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
@@ -30,17 +35,22 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
containers[9].insert(-1);
|
||||
containers[10].insert(-1);
|
||||
containers[10].insert(1);
|
||||
containers[11].insert(1);
|
||||
containers[11].insert(2);
|
||||
containers[11].insert(3);
|
||||
containers[11].insert(4);
|
||||
containers[11].insert(5);
|
||||
|
||||
HASH_NAMESPACE::hash<T> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
|
||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2]) ==
|
||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||
|
||||
BOOST_TEST(hasher(containers[i2])
|
||||
== HASH_NAMESPACE::hash_range(
|
||||
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||
containers[i2].begin(), containers[i2].end()));
|
||||
|
||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||
@@ -61,5 +71,9 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#undef CONTAINER_TYPE
|
||||
#endif
|
||||
|
||||
103
test/hash_std_array_test.cpp
Normal file
103
test/hash_std_array_test.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||
#define TEST_ARRAY
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_ARRAY
|
||||
|
||||
template <typename T>
|
||||
void array_tests(T const& v) {
|
||||
boost::hash<typename T::value_type> hf;
|
||||
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
|
||||
if (i != j)
|
||||
BOOST_TEST(hf(*i) != hf(*j));
|
||||
else
|
||||
BOOST_TEST(hf(*i) == hf(*j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void empty_array_test() {
|
||||
/*
|
||||
boost::hash<std::array<int, 0> > empty_array_hash;
|
||||
std::array<int, 0> empty_array;
|
||||
BOOST_TEST(empty_array_hash(empty_array) == boost::hash_value(empty_array));
|
||||
*/
|
||||
}
|
||||
|
||||
void int_1_array_test()
|
||||
{
|
||||
std::vector<std::array<int, 1> > arrays;
|
||||
std::array<int, 1> val;
|
||||
val[0] = 0;
|
||||
arrays.push_back(val);
|
||||
val[0] = 1;
|
||||
arrays.push_back(val);
|
||||
val[0] = 2;
|
||||
arrays.push_back(val);
|
||||
array_tests(arrays);
|
||||
}
|
||||
|
||||
void string_1_array_test()
|
||||
{
|
||||
std::vector<std::array<std::string, 1> > arrays;
|
||||
std::array<std::string, 1> val;
|
||||
arrays.push_back(val);
|
||||
val[0] = "one";
|
||||
arrays.push_back(val);
|
||||
val[0] = "two";
|
||||
arrays.push_back(val);
|
||||
array_tests(arrays);
|
||||
}
|
||||
|
||||
void string_3_array_test()
|
||||
{
|
||||
std::vector<std::array<std::string,3 > > arrays;
|
||||
std::array<std::string, 3> val;
|
||||
arrays.push_back(val);
|
||||
val[0] = "one";
|
||||
arrays.push_back(val);
|
||||
val[0] = ""; val[1] = "one"; val[2] = "";
|
||||
arrays.push_back(val);
|
||||
val[0] = ""; val[1] = ""; val[2] = "one";
|
||||
arrays.push_back(val);
|
||||
val[0] = "one"; val[1] = "one"; val[2] = "one";
|
||||
arrays.push_back(val);
|
||||
val[0] = "one"; val[1] = "two"; val[2] = "three";
|
||||
arrays.push_back(val);
|
||||
array_tests(arrays);
|
||||
}
|
||||
|
||||
#endif // TEST_ARRAY
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_ARRAY
|
||||
empty_array_test();
|
||||
int_1_array_test();
|
||||
string_1_array_test();
|
||||
string_3_array_test();
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
80
test/hash_std_smart_ptr_test.cpp
Normal file
80
test/hash_std_smart_ptr_test.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
#define TEST_SMART_PTRS
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_SMART_PTRS
|
||||
|
||||
void shared_ptr_tests()
|
||||
{
|
||||
std::shared_ptr<int> x;
|
||||
compile_time_tests(&x);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x2;
|
||||
|
||||
std::shared_ptr<int> ptr1(new int(10));
|
||||
std::shared_ptr<int> ptr2;
|
||||
|
||||
BOOST_TEST(x1(x) == x2(ptr2));
|
||||
BOOST_TEST(x1(x) != x2(ptr1));
|
||||
ptr2.reset(new int(10));
|
||||
BOOST_TEST(x1(ptr1) == x2(ptr1));
|
||||
BOOST_TEST(x1(ptr1) != x2(ptr2));
|
||||
ptr2 = ptr1;
|
||||
BOOST_TEST(x1(ptr1) == x2(ptr2));
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||
BOOST_TEST(x1(ptr1) == BOOST_HASH_TEST_NAMESPACE::hash_value(ptr2));
|
||||
#endif
|
||||
}
|
||||
|
||||
void unique_ptr_tests()
|
||||
{
|
||||
std::unique_ptr<int> x;
|
||||
compile_time_tests(&x);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x2;
|
||||
|
||||
std::unique_ptr<int> ptr1(new int(10));
|
||||
std::unique_ptr<int> ptr2;
|
||||
|
||||
BOOST_TEST(x1(x) == x2(ptr2));
|
||||
BOOST_TEST(x1(x) != x2(ptr1));
|
||||
ptr2.reset(new int(10));
|
||||
BOOST_TEST(x1(ptr1) == x2(ptr1));
|
||||
BOOST_TEST(x1(ptr1) != x2(ptr2));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_SMART_PTRS
|
||||
shared_ptr_tests();
|
||||
unique_ptr_tests();
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
77
test/hash_std_tuple_test.cpp
Normal file
77
test/hash_std_tuple_test.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
// Copyright 2012 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#define TEST_TUPLE
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_TUPLE
|
||||
|
||||
template <typename T>
|
||||
void tuple_tests(T const& v) {
|
||||
boost::hash<typename T::value_type> hf;
|
||||
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
|
||||
if (i != j)
|
||||
BOOST_TEST(hf(*i) != hf(*j));
|
||||
else
|
||||
BOOST_TEST(hf(*i) == hf(*j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void empty_tuple_test() {
|
||||
boost::hash<std::tuple<> > empty_tuple_hash;
|
||||
std::tuple<> empty_tuple;
|
||||
BOOST_TEST(empty_tuple_hash(empty_tuple) == boost::hash_value(empty_tuple));
|
||||
}
|
||||
|
||||
void int_tuple_test() {
|
||||
std::vector<std::tuple<int> > int_tuples;
|
||||
int_tuples.push_back(std::make_tuple(0));
|
||||
int_tuples.push_back(std::make_tuple(1));
|
||||
int_tuples.push_back(std::make_tuple(2));
|
||||
tuple_tests(int_tuples);
|
||||
}
|
||||
|
||||
void int_string_tuple_test() {
|
||||
std::vector<std::tuple<int, std::string> > int_string_tuples;
|
||||
int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
|
||||
int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
|
||||
int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
|
||||
int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
|
||||
int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
|
||||
int_string_tuples.push_back(std::make_tuple(0, std::string("")));
|
||||
int_string_tuples.push_back(std::make_tuple(1, std::string("")));
|
||||
tuple_tests(int_string_tuples);
|
||||
}
|
||||
|
||||
#endif // TEST_TUPLE
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_TUPLE
|
||||
empty_tuple_test();
|
||||
int_tuple_test();
|
||||
int_string_tuple_test();
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,45 +1,40 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
void string_tests()
|
||||
{
|
||||
compile_time_tests((std::string*) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<std::string> x1;
|
||||
HASH_NAMESPACE::hash<std::string> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
|
||||
|
||||
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
|
||||
BOOST_TEST(x1("") == x2(std::string()));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::string value1;
|
||||
std::string value2("Hello");
|
||||
|
||||
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
||||
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
||||
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
||||
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
|
||||
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -48,22 +43,22 @@ void wstring_tests()
|
||||
{
|
||||
compile_time_tests((std::wstring*) 0);
|
||||
|
||||
HASH_NAMESPACE::hash<std::wstring> x1;
|
||||
HASH_NAMESPACE::hash<std::wstring> x2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
|
||||
|
||||
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
|
||||
BOOST_TEST(x1(L"") == x2(std::wstring()));
|
||||
|
||||
#if defined(TEST_EXTENSIONS)
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::wstring value1;
|
||||
std::wstring value2(L"Hello");
|
||||
|
||||
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
||||
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
||||
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
||||
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
|
||||
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
|
||||
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
53
test/hash_type_index_test.cpp
Normal file
53
test/hash_type_index_test.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
// Copyright 2011 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
#endif
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
|
||||
#include <typeindex>
|
||||
|
||||
void test_type_index() {
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::type_index> hasher;
|
||||
|
||||
#if defined(BOOST_NO_TYPEID)
|
||||
std::cout<<"Unable to test std::type_index, as typeid isn't available"
|
||||
<<std::endl;
|
||||
#else
|
||||
std::type_index int_index = typeid(int);
|
||||
std::type_index int2_index = typeid(int);
|
||||
std::type_index char_index = typeid(char);
|
||||
|
||||
BOOST_TEST(hasher(int_index) == int_index.hash_code());
|
||||
BOOST_TEST(hasher(int_index) == int2_index.hash_code());
|
||||
BOOST_TEST(hasher(char_index) == char_index.hash_code());
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int_index.hash_code());
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
|
||||
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(char_index) == char_index.hash_code());
|
||||
|
||||
BOOST_TEST(hasher(int_index) == hasher(int2_index));
|
||||
BOOST_TEST(hasher(int_index) != hasher(char_index));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
test_type_index();
|
||||
#else
|
||||
std::cout<<"<type_index> not available."<<std::endl;
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// On some compilers hash_value isn't available for arrays, so I test it
|
||||
// separately from the main array tests.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
void array_int_test()
|
||||
{
|
||||
@@ -29,32 +29,32 @@ void array_int_test()
|
||||
8, -12, 23, 65, 45,
|
||||
-1, 93, -54, 987, 3
|
||||
};
|
||||
HASH_NAMESPACE::hash<int[25]> hasher1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
|
||||
|
||||
int array2[1] = {3};
|
||||
HASH_NAMESPACE::hash<int[1]> hasher2;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
|
||||
|
||||
int array3[2] = {2, 3};
|
||||
HASH_NAMESPACE::hash<int[2]> hasher3;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
|
||||
|
||||
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
|
||||
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
|
||||
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
|
||||
BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
|
||||
BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
|
||||
BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
|
||||
}
|
||||
|
||||
void two_dimensional_array_test()
|
||||
{
|
||||
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
|
||||
|
||||
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
|
||||
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
array_int_test();
|
||||
two_dimensional_array_test();
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
# ifdef TEST_STD_INCLUDES
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -23,11 +23,11 @@ using std::vector;
|
||||
#define CONTAINER_TYPE vector
|
||||
#include "./hash_sequence_test.hpp"
|
||||
|
||||
#endif // TEST_EXTENSIONS
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef TEST_EXTENSIONS
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
vector_tests::vector_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
|
||||
21
test/implicit_test.cpp
Normal file
21
test/implicit_test.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
// Copyright 2010 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
struct base {};
|
||||
std::size_t hash_value(base const&) { return 0; }
|
||||
|
||||
struct converts { operator base() const { return base(); } };
|
||||
}
|
||||
|
||||
int main() {
|
||||
boost::hash<test::converts> hash;
|
||||
test::converts x;
|
||||
|
||||
hash(x);
|
||||
}
|
||||
@@ -1,22 +1,33 @@
|
||||
|
||||
// Copyright Daniel James 2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
#include "./config.hpp"
|
||||
|
||||
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <vector>
|
||||
|
||||
int f(std::size_t hash1, int* x1) {
|
||||
// Check that HASH_NAMESPACE::hash<int*> works in both files.
|
||||
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
||||
|
||||
// Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
|
||||
BOOST_TEST(hash1 == ptr_hasher(x1));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
|
||||
// Check that std::vector<std::size_t> is avaiable in this file.
|
||||
std::vector<std::size_t> x;
|
||||
x.push_back(*x1);
|
||||
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
||||
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
||||
return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define HASH_NAMESPACE boost
|
||||
#include "./config.hpp"
|
||||
|
||||
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||
#define BOOST_HASH_NO_EXTENSIONS
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
@@ -11,7 +13,7 @@
|
||||
extern int f(std::size_t, int*);
|
||||
|
||||
int main() {
|
||||
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
|
||||
int x = 55;
|
||||
BOOST_TEST(!f(ptr_hasher(&x), &x));
|
||||
return boost::report_errors();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
|
||||
16
test/namespace_fail_test.cpp
Normal file
16
test/namespace_fail_test.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
// Copyright 2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Check that I haven't inadvertantly pulled namespace std into the global
|
||||
// namespace.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
typedef list<int> foo;
|
||||
|
||||
int main() {}
|
||||
Reference in New Issue
Block a user