forked from boostorg/container_hash
Compare commits
153 Commits
boost-1.55
...
boost-1.72
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fbda1a98a | ||
|
|
62f29ea201 | ||
|
|
59f9543c10 | ||
|
|
a6da082784 | ||
|
|
e73522f296 | ||
|
|
3e8dbcbcc5 | ||
|
|
601b8d0378 | ||
|
|
60f5e0d393 | ||
|
|
e67d20d1c3 | ||
|
|
8c9bd9eccd | ||
|
|
88d1c5c395 | ||
|
|
957818bb97 | ||
|
|
21f32243a8 | ||
|
|
9fafa9e37b | ||
|
|
cc541b71c5 | ||
|
|
d20a68efdb | ||
|
|
d45e3986f3 | ||
|
|
1e263669cb | ||
|
|
8ea85f5ad2 | ||
|
|
e01239286c | ||
|
|
17809c3cbc | ||
|
|
8963c38770 | ||
|
|
0ad83592af | ||
|
|
cb6a0246df | ||
|
|
27b2732916 | ||
|
|
4d9f438823 | ||
|
|
ddc05d17df | ||
|
|
b9ae7e7fb6 | ||
|
|
42bb81befa | ||
|
|
f81ee167c5 | ||
|
|
5c4edf4d7d | ||
|
|
b5c3b5d00a | ||
|
|
def7a785a5 | ||
|
|
3521c417b5 | ||
|
|
8b77644ea0 | ||
|
|
d41ead127d | ||
|
|
f460c21dd0 | ||
|
|
c3e070a244 | ||
|
|
9d5a16c288 | ||
|
|
e80c0c84bb | ||
|
|
c64e516518 | ||
|
|
b40b795572 | ||
|
|
8d784ed76d | ||
|
|
6ca88a8146 | ||
|
|
53fbb04e88 | ||
|
|
c7fc03d2b9 | ||
|
|
fc3e0bff4f | ||
|
|
376000169c | ||
|
|
bc09240437 | ||
|
|
dfa8fa5d91 | ||
|
|
8098c5b302 | ||
|
|
7f3a063064 | ||
|
|
d803b3bdc0 | ||
|
|
170558e4fa | ||
|
|
4a4cb9f7a4 | ||
|
|
7a6c0f20d5 | ||
|
|
8bdfb0cf90 | ||
|
|
3ee110f82c | ||
|
|
f7ad177dae | ||
|
|
955cdaed3d | ||
|
|
9c82e48bc9 | ||
|
|
1b3bed82aa | ||
|
|
6dd58674aa | ||
|
|
4a530f85d0 | ||
|
|
babb4f8f73 | ||
|
|
01b81754cf | ||
|
|
5210c845f5 | ||
|
|
4b99dbdb64 | ||
|
|
2cdf1c7d9e | ||
|
|
a489b08e27 | ||
|
|
b9c3499f45 | ||
|
|
ab9f98455a | ||
|
|
7159a86166 | ||
|
|
d0ee8e13bd | ||
|
|
98140b7373 | ||
|
|
e2d7225f57 | ||
|
|
36545f62cf | ||
|
|
618fc6d074 | ||
|
|
c2764e22a7 | ||
|
|
9148cde86f | ||
|
|
5a811f25aa | ||
|
|
b790429529 | ||
|
|
1e6cefbfeb | ||
|
|
b0ddb244be | ||
|
|
3dfdb19bfd | ||
|
|
f184dd019f | ||
|
|
0361d416b7 | ||
|
|
7838c3678f | ||
|
|
5856bff480 | ||
|
|
468516ed71 | ||
|
|
c8d8c7edd4 | ||
|
|
e76c3dc1a2 | ||
|
|
8171dbb465 | ||
|
|
99d4923496 | ||
|
|
29865a5bca | ||
|
|
8b05fd5fdf | ||
|
|
ada1369a14 | ||
|
|
4977373964 | ||
|
|
8b19e7eaa0 | ||
|
|
75ae18ef54 | ||
|
|
754d5f535e | ||
|
|
ebc607d44e | ||
|
|
549196ca7d | ||
|
|
f2761964bd | ||
|
|
41487a2e8c | ||
|
|
ca52df8a05 | ||
|
|
b39e6e96f0 | ||
|
|
8266a55b26 | ||
|
|
711b2b6d69 | ||
|
|
d888097468 | ||
|
|
23f1db7729 | ||
|
|
35ef2502d5 | ||
|
|
aa3ab0790a | ||
|
|
6c3e20ac18 | ||
|
|
97cc6fbbc1 | ||
|
|
309d17f387 | ||
|
|
928767f2bd | ||
|
|
bb2a91bf47 | ||
|
|
496bf24900 | ||
|
|
09f197abf6 | ||
|
|
582671543b | ||
|
|
6157ad5267 | ||
|
|
844d9758bd | ||
|
|
7dbc8b593f | ||
|
|
3c22fce14c | ||
|
|
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 |
36
.appveyor.yml
Normal file
36
.appveyor.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright 2017 Daniel James
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||
TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-14.0
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
CXXSTD: 14,17
|
||||
|
||||
install:
|
||||
- cd c:\projects
|
||||
- curl -sSL -o boost.7z https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.7z
|
||||
- 7z x boost.7z
|
||||
- set BOOST_ROOT=c:\projects\boost_1_67_0
|
||||
- rd /s /q %BOOST_ROOT%\boost\functional\hash
|
||||
- cd %BOOST_ROOT%\tools\build
|
||||
- cmd /c bootstrap
|
||||
- cd %APPVEYOR_BUILD_FOLDER%
|
||||
- echo. 2>Jamroot.jam
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- cd %APPVEYOR_BUILD_FOLDER%\test
|
||||
- cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT% --verbose-test hash_info
|
||||
- cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT%
|
||||
78
.travis.yml
Normal file
78
.travis.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
# Copyright (C) 2016 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)
|
||||
|
||||
# Use Trusty to get a reasonably recent version of Boost.
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
language: c++
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
env: |
|
||||
USER_CONFIG="using gcc : : g++-4.8 ;"
|
||||
CXXSTD=03,11
|
||||
- compiler: g++-7
|
||||
env: |
|
||||
USER_CONFIG="using gcc : : g++-7 ;"
|
||||
CXXSTD=11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- compiler: clang
|
||||
env: |
|
||||
USER_CONFIG="using clang : : clang++ ;"
|
||||
CXXSTD=03,11
|
||||
- compiler: clang
|
||||
env: |
|
||||
USER_CONFIG="using clang : : clang++ -D_HAS_AUTO_PTR_ETC=0 ;"
|
||||
CXXSTD=11
|
||||
|
||||
before_script:
|
||||
- export BOOST_VERSION=1.67.0
|
||||
- export BOOST_FILENAME=boost_1_67_0
|
||||
- export BOOST_ROOT=${HOME}/boost
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- touch Jamroot.jam
|
||||
- cd $HOME
|
||||
- echo $USER_CONFIG > ~/user-config.jam
|
||||
- cat ~/user-config.jam
|
||||
- |
|
||||
mkdir $HOME/download
|
||||
mkdir $HOME/extract
|
||||
cd $HOME/download
|
||||
if [ "$TRAVIS_EVENT_TYPE" == "cron" ]
|
||||
then
|
||||
if [ "$TRAVIS_BRANCH" == "master" ]
|
||||
then
|
||||
snapshot_branch=master
|
||||
else
|
||||
snapshot_branch=develop
|
||||
fi
|
||||
download_url=$(curl https://api.bintray.com/packages/boostorg/$snapshot_branch/snapshot/files |
|
||||
python -c "import os.path, sys, json; x = json.load(sys.stdin); print '\n'.join(a['path'] for a in x if os.path.splitext(a['path'])[1] == '.bz2')" |
|
||||
head -n 1 |
|
||||
sed "s/^/http:\/\/dl.bintray.com\/boostorg\/$snapshot_branch\//")
|
||||
else
|
||||
download_url=https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/${BOOST_FILENAME}.tar.bz2/download
|
||||
fi
|
||||
echo "Downloading ${download_url}"
|
||||
wget -O boost.tar.bz2 $download_url
|
||||
cd $HOME/extract
|
||||
tar -xjf $HOME/download/boost.tar.bz2
|
||||
mv * ${BOOST_ROOT}
|
||||
- rm -r ${BOOST_ROOT}/boost/functional
|
||||
- cd ${BOOST_ROOT}/tools/build
|
||||
- mkdir ${HOME}/opt
|
||||
- ./bootstrap.sh
|
||||
- ./b2 install --prefix=$HOME/opt
|
||||
|
||||
script:
|
||||
- cd ${TRAVIS_BUILD_DIR}/test
|
||||
- ${HOME}/opt/bin/b2 --verbose-test -j 3 cxxstd=$CXXSTD -q ${BJAM_TOOLSET} include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include hash_info
|
||||
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q ${BJAM_TOOLSET} include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
|
||||
@@ -15,5 +15,11 @@ boostbook standalone : hash :
|
||||
<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
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/container_hash/doc/html
|
||||
;
|
||||
|
||||
###############################################################################
|
||||
alias boostdoc : hash ;
|
||||
explicit boostdoc ;
|
||||
alias boostrelease ;
|
||||
explicit boostrelease ;
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
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
|
||||
* 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]:
|
||||
@@ -71,11 +71,11 @@
|
||||
|
||||
* 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`
|
||||
* Moved detail headers out of `boost/container_hash/detail`, since they are part of
|
||||
functional/hash, not container_hash. `boost/container_hash/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
|
||||
@@ -132,7 +132,7 @@
|
||||
* [@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`.
|
||||
`boost/container_hash/detail/container_fwd.hpp`.
|
||||
|
||||
[h2 Boost 1.51.0]
|
||||
|
||||
@@ -168,5 +168,55 @@
|
||||
([ticket 8822]).
|
||||
* Suppress Visual C++ infinite loop warning ([ticket 8568]).
|
||||
|
||||
[h2 Boost 1.56.0]
|
||||
|
||||
* Removed some Visual C++ 6 workarounds.
|
||||
* Ongoing work on improving `hash_combine`. This changes the combine function
|
||||
which was previously defined in the reference documentation.
|
||||
|
||||
[h2 Boost 1.58.0]
|
||||
|
||||
* Fixed strict aliasing violation
|
||||
([@https://github.com/boostorg/container_hash/pull/3 GitHub #3]).
|
||||
|
||||
[h2 Boost 1.63.0]
|
||||
|
||||
* Fixed some warnings.
|
||||
* Only define hash for `std::wstring` when we know we have a `wchar_t`.
|
||||
Otherwise there's a compile error as there's no overload for hashing
|
||||
the characters in wide strings ([ticket 8552]).
|
||||
|
||||
[h2 Boost 1.64.0]
|
||||
|
||||
* Fix for recent versions of Visual C++ which have removed `std::unary_function`
|
||||
and `std::binary_function` ([ticket 12353]).
|
||||
|
||||
[h2 Boost 1.65.0]
|
||||
|
||||
* Support for `char16_t`, `char32_t`, `u16string`, `u32string`
|
||||
|
||||
[h2 Boost 1.66.0]
|
||||
|
||||
* Avoid float comparison warning when using Clang - this workaround was
|
||||
already in place for GCC, and was used when Clang pretends to be GCC,
|
||||
but the warning was appearing when running Clang in other contexts.
|
||||
|
||||
[h2 Boost 1.67.0]
|
||||
|
||||
* Moved library into its own module, `container_hash`.
|
||||
* Moved headers for new module name, now at:
|
||||
`<boost/container_hash/hash.hpp>`,
|
||||
`<boost/container_hash/hash_fwd.hpp>`,
|
||||
`<boost/container_hash/extensions.hpp>`.
|
||||
* Added forwarding headers to support the old headers locations.
|
||||
* Support `std::string_view`, `std::error_code`, `std::error_condition`
|
||||
`std::optional`, `std::variant`, `std::monostate` where available.
|
||||
* Update include paths from other Boost libraries.
|
||||
* Manually write out tuple overloads, rather than using the
|
||||
preprocessor to generate them. Should improve usability, due
|
||||
to better error messages, and easier debugging.
|
||||
* Fix tutorial example ([ticket 11017]).
|
||||
* Quick fix for hashing `vector<bool>` when using libc++. Will try to introduce
|
||||
a more general fix in the next release.
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -10,7 +10,7 @@ to turn them of in order to check that your code will work with other
|
||||
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
|
||||
When this macro is defined, only the specialisations detailed
|
||||
in TR1 will be declared. But, if you later undefine the macro and include
|
||||
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
|
||||
<[headerref boost/container_hash/hash.hpp]> then the non-specialised form will be defined
|
||||
- activating the extensions.
|
||||
|
||||
It is strongly recommended that you never undefine the macro - and only define
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[library Boost.Functional/Hash
|
||||
[library Boost.ContainerHash
|
||||
[quickbook 1.5]
|
||||
[authors [James, Daniel]]
|
||||
[copyright 2005 2006 2007 2008 Daniel James]
|
||||
@@ -6,7 +6,7 @@
|
||||
defined types]
|
||||
[category higher-order]
|
||||
[id hash]
|
||||
[dirname functional/hash]
|
||||
[dirname container_hash]
|
||||
[license
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -88,6 +88,6 @@ boost namespace:
|
||||
}
|
||||
|
||||
Full code for this example is at
|
||||
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
|
||||
[@boost:/libs/container_hash/examples/portable.cpp /libs/container_hash/examples/portable.cpp].
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -34,7 +34,7 @@ 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://www.concentric.net/~ttwang/tech/inthash.htm
|
||||
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.
|
||||
|
||||
|
||||
123
doc/ref.xml
123
doc/ref.xml
@@ -13,7 +13,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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">
|
||||
<header name="boost/container_hash/hash.hpp">
|
||||
<para>
|
||||
Defines <code><classname>boost::hash</classname></code>,
|
||||
and helper functions.
|
||||
@@ -57,7 +57,12 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</para>
|
||||
<para>
|
||||
Forward declared in
|
||||
<code><boost/functional/hash_fwd.hpp></code>
|
||||
<code><boost/container_hash/hash_fwd.hpp></code>
|
||||
</para>
|
||||
<para>
|
||||
This hash function is not intended for general use, and isn't
|
||||
guaranteed to be equal during separate runs of a program - so
|
||||
please don't use it for any persistent storage or communication.
|
||||
</para>
|
||||
</notes>
|
||||
<throws><para>
|
||||
@@ -157,6 +162,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
<template-arg>char16_t</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>char16_t</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>char32_t</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>char32_t</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>
|
||||
@@ -391,6 +432,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</method>
|
||||
</struct-specialization>
|
||||
|
||||
<struct-specialization name="hash">
|
||||
<template></template>
|
||||
<specialization>
|
||||
<template-arg>std::u16string</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>std::u16string const&</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>std::u32string</template-arg>
|
||||
</specialization>
|
||||
<method name="operator()" cv="const">
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val">
|
||||
<paramtype>std::u32string const&</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-type-parameter name="T"/>
|
||||
@@ -450,14 +527,27 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
Called repeatedly to incrementally create a hash value from
|
||||
several variables.
|
||||
</simpara></purpose>
|
||||
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);</programlisting></effects>
|
||||
<effects>
|
||||
Updates <code>seed</code> with a new hash value generated by
|
||||
combining it with the result of
|
||||
<code><functionname>hash_value</functionname>(v)</code>. Will
|
||||
always produce the same result for the same combination of
|
||||
<code>seed</code> and
|
||||
<code><functionname>hash_value</functionname>(v)</code> during
|
||||
the single run of a program.
|
||||
</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>
|
||||
<code><boost/container_hash/hash_fwd.hpp></code>
|
||||
</para>
|
||||
<para>
|
||||
This hash function is not intended for general use, and isn't
|
||||
guaranteed to be equal during separate runs of a program - so
|
||||
please don't use it for any persistent storage or communication.
|
||||
</para>
|
||||
</notes>
|
||||
<throws>
|
||||
@@ -525,7 +615,12 @@ for(; first != last; ++first)
|
||||
<para>This is an extension to TR1</para>
|
||||
<para>
|
||||
Forward declared in
|
||||
<code><boost/functional/hash_fwd.hpp></code>
|
||||
<code><boost/container_hash/hash_fwd.hpp></code>
|
||||
</para>
|
||||
<para>
|
||||
This hash function is not intended for general use, and isn't
|
||||
guaranteed to be equal during separate runs of a program - so
|
||||
please don't use it for any persistent storage or communication.
|
||||
</para>
|
||||
</notes>
|
||||
<throws><para>
|
||||
@@ -574,6 +669,16 @@ for(; first != last; ++first)
|
||||
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>char16_t</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>char32_t</paramtype></parameter>
|
||||
</signature>
|
||||
|
||||
<signature>
|
||||
<type>std::size_t</type>
|
||||
<parameter name="val"><paramtype>short</paramtype></parameter>
|
||||
@@ -784,6 +889,11 @@ for(; first != last; ++first)
|
||||
|
||||
<notes>
|
||||
<para>This is an extension to TR1</para>
|
||||
<para>
|
||||
This hash function is not intended for general use, and isn't
|
||||
guaranteed to be equal during separate runs of a program - so
|
||||
please don't use it for any persistent storage or communication.
|
||||
</para>
|
||||
</notes>
|
||||
|
||||
<throws>
|
||||
@@ -805,7 +915,8 @@ for(; first != last; ++first)
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>bool</code>,
|
||||
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>,
|
||||
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>,
|
||||
<code>wchar_t</code>, <code>char16_t</code>, <code>char32_t</code>,
|
||||
<code>short</code>, <code>unsigned short</code>,
|
||||
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
|
||||
</entry>
|
||||
|
||||
27
doc/samples/tutorial.cpp
Normal file
27
doc/samples/tutorial.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
//[ get_hashes
|
||||
template <class Container>
|
||||
std::vector<std::size_t> get_hashes(Container const& x)
|
||||
{
|
||||
std::vector<std::size_t> hashes;
|
||||
std::transform(x.begin(), x.end(), std::back_inserter(hashes),
|
||||
boost::hash<typename Container::value_type>());
|
||||
|
||||
return hashes;
|
||||
}
|
||||
//]
|
||||
|
||||
int main() {
|
||||
std::vector<int> values;
|
||||
values.push_back(10);
|
||||
values.push_back(20);
|
||||
|
||||
std::vector<std::size_t> hashes = get_hashes(values);
|
||||
assert(hashes[0] = boost::hash<int>()(values[0]));
|
||||
assert(hashes[1] = boost::hash<int>()(values[1]));
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
/ 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) ]
|
||||
|
||||
[quickbook 1.7]
|
||||
[import samples/tutorial.cpp]
|
||||
|
||||
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
||||
Boost.MultiIndex]]
|
||||
|
||||
@@ -27,7 +30,7 @@ associative containers and you wish to use
|
||||
|
||||
To use [classref boost::hash] directly, create an instance and call it as a function:
|
||||
|
||||
#include <``[headerref boost/functional/hash.hpp]``>
|
||||
#include <``[headerref boost/container_hash/hash.hpp]``>
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -39,15 +42,7 @@ To use [classref boost::hash] directly, create an instance and call it as a func
|
||||
For an example of generic use, here is a function to generate a vector
|
||||
containing the hashes of the elements of a container:
|
||||
|
||||
template <class Container>
|
||||
std::vector<std::size_t> get_hashes(Container const& x)
|
||||
{
|
||||
std::vector<std::size_t> hashes;
|
||||
std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
|
||||
``[classref boost::hash]``<typename Container::value_type>());
|
||||
|
||||
return hashes;
|
||||
}
|
||||
[get_hashes]
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -110,9 +105,9 @@ And you can now use [classref boost::hash] with book:
|
||||
assert(books.find(dandelion) == books.end());
|
||||
|
||||
The full example can be found in:
|
||||
[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
|
||||
[@boost:/libs/container_hash/examples/books.hpp /libs/container_hash/examples/books.hpp]
|
||||
and
|
||||
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
|
||||
[@boost:/libs/container_hash/examples/books.cpp /libs/container_hash/examples/books.cpp].
|
||||
|
||||
[tip
|
||||
When writing a hash function, first look at how the equality function works.
|
||||
@@ -170,7 +165,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
|
||||
[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
|
||||
[@boost:/libs/container_hash/examples/point.cpp /libs/container_hash/examples/point.cpp].
|
||||
|
||||
[note
|
||||
When using [funcref boost::hash_combine] the order of the
|
||||
@@ -200,13 +195,13 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
|
||||
|
||||
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>`
|
||||
headers, so instead you can include the `<boost/container_hash/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].
|
||||
in [@boost:/libs/container_hash/examples/template.hpp template.hpp] and
|
||||
[@boost:/libs/container_hash/examples/template.cpp template.cpp].
|
||||
|
||||
[endsect]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "./books.hpp"
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <cassert>
|
||||
|
||||
// If std::unordered_set was available:
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
// 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>
|
||||
// Force use of assert.
|
||||
#if defined(NDEBUG)
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <cassert>
|
||||
|
||||
// This example illustrates how to use boost::hash_combine to generate a hash
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
// 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>
|
||||
// Force use of assert.
|
||||
#if defined(NDEBUG)
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <cassert>
|
||||
|
||||
// This example illustrates how to customise boost::hash portably, so that
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// This is an example of how to write a hash function for a template
|
||||
// class.
|
||||
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
|
||||
template <typename A, typename B>
|
||||
class my_pair
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#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.
|
||||
@@ -6,14 +6,14 @@
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/container_hash/detail/float_functions.hpp>
|
||||
#include <boost/container_hash/detail/limits.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/integer/static_log2.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
@@ -68,7 +68,7 @@ namespace boost
|
||||
std::size_t seed = 0;
|
||||
|
||||
if (length >= sizeof(std::size_t)) {
|
||||
seed = *(std::size_t*) ptr;
|
||||
std::memcpy(&seed, ptr, sizeof(std::size_t));
|
||||
length -= sizeof(std::size_t);
|
||||
ptr += sizeof(std::size_t);
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace boost
|
||||
hash_float_combine(seed, part);
|
||||
}
|
||||
|
||||
hash_float_combine(seed, exp);
|
||||
hash_float_combine(seed, static_cast<std::size_t>(exp));
|
||||
|
||||
return seed;
|
||||
}
|
||||
@@ -241,7 +241,7 @@ namespace boost
|
||||
template <class T>
|
||||
inline bool is_zero(T v)
|
||||
{
|
||||
#if !defined(__GNUC__)
|
||||
#if !defined(__GNUC__) && !defined(__clang__)
|
||||
return v == 0;
|
||||
#else
|
||||
// GCC's '-Wfloat-equal' will complain about comparing
|
||||
@@ -9,8 +9,9 @@
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
|
||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
414
include/boost/container_hash/extensions.hpp
Normal file
414
include/boost/container_hash/extensions.hpp
Normal file
@@ -0,0 +1,414 @@
|
||||
|
||||
// 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/container_hash/hash.hpp>
|
||||
#include <boost/detail/container_fwd.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
inline std::size_t hash_range(
|
||||
std::vector<bool>::iterator first,
|
||||
std::vector<bool>::iterator last)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine<bool>(seed, *first);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline std::size_t hash_range(
|
||||
std::vector<bool>::const_iterator first,
|
||||
std::vector<bool>::const_iterator last)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine<bool>(seed, *first);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline void hash_range(
|
||||
std::size_t& seed,
|
||||
std::vector<bool>::iterator first,
|
||||
std::vector<bool>::iterator last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine<bool>(seed, *first);
|
||||
}
|
||||
}
|
||||
|
||||
inline void hash_range(
|
||||
std::size_t& seed,
|
||||
std::vector<bool>::const_iterator first,
|
||||
std::vector<bool>::const_iterator last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine<bool>(seed, *first);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename A0>
|
||||
inline std::size_t hash_value(std::tuple<A0> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
|
||||
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v)
|
||||
{
|
||||
return boost::hash_detail::hash_tuple(v);
|
||||
}
|
||||
|
||||
#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
|
||||
//
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T> struct hash
|
||||
: boost::hash_detail::hash_base<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]>
|
||||
: boost::hash_detail::hash_base<T[n]>
|
||||
{
|
||||
std::size_t operator()(const T* val) const
|
||||
{
|
||||
return boost::hash_range(val, val+n);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// 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 of hash_impl.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
struct hash_impl;
|
||||
|
||||
template <>
|
||||
struct hash_impl<false>
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: boost::hash_detail::hash_base<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
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}
|
||||
|
||||
#endif
|
||||
761
include/boost/container_hash/hash.hpp
Normal file
761
include/boost/container_hash/hash.hpp
Normal file
@@ -0,0 +1,761 @@
|
||||
|
||||
// Copyright 2005-2014 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 also contains public domain code from MurmurHash. From the
|
||||
// MurmurHash header:
|
||||
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <functional>
|
||||
#include <boost/container_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/core/enable_if.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
#include <typeindex>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
#include <system_error>
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
#endif
|
||||
|
||||
#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(_MSC_VER)
|
||||
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
|
||||
#else
|
||||
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
|
||||
#endif
|
||||
|
||||
// Detect whether standard library has C++17 headers
|
||||
|
||||
#if !defined(BOOST_HASH_CXX17)
|
||||
# if defined(BOOST_MSVC)
|
||||
# if defined(_HAS_CXX17) && _HAS_CXX17
|
||||
# define BOOST_HASH_CXX17 1
|
||||
# endif
|
||||
# elif defined(__cplusplus) && __cplusplus >= 201703
|
||||
# define BOOST_HASH_CXX17 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HASH_CXX17)
|
||||
# define BOOST_HASH_CXX17 0
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_CXX17 && defined(__has_include)
|
||||
# if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include(<string_view>)
|
||||
# define BOOST_HASH_HAS_STRING_VIEW 1
|
||||
# endif
|
||||
# if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include(<optional>)
|
||||
# define BOOST_HASH_HAS_OPTIONAL 1
|
||||
# endif
|
||||
# if !defined(BOOST_HASH_HAS_VARIANT) && __has_include(<variant>)
|
||||
# define BOOST_HASH_HAS_VARIANT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HASH_HAS_STRING_VIEW)
|
||||
# define BOOST_HASH_HAS_STRING_VIEW 0
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HASH_HAS_OPTIONAL)
|
||||
# define BOOST_HASH_HAS_OPTIONAL 0
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HASH_HAS_VARIANT)
|
||||
# define BOOST_HASH_HAS_VARIANT 0
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_STRING_VIEW
|
||||
# include <string_view>
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_OPTIONAL
|
||||
# include <optional>
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_VARIANT
|
||||
# include <variant>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
|
||||
template <typename T>
|
||||
struct hash_base
|
||||
{
|
||||
typedef T argument_type;
|
||||
typedef std::size_t result_type;
|
||||
};
|
||||
#else
|
||||
template <typename T>
|
||||
struct hash_base : std::unary_function<T, std::size_t> {};
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
template <> struct basic_numbers<char16_t> :
|
||||
boost::hash_detail::enable_hash_value {};
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
template <> struct basic_numbers<char32_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 (&x)[N]);
|
||||
|
||||
template< class T, unsigned N >
|
||||
std::size_t hash_value(T (&x)[N]);
|
||||
#endif
|
||||
|
||||
template <class Ch, class A>
|
||||
std::size_t hash_value(
|
||||
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
|
||||
|
||||
#if BOOST_HASH_HAS_STRING_VIEW
|
||||
template <class Ch>
|
||||
std::size_t hash_value(
|
||||
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const&);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
|
||||
|
||||
#if BOOST_HASH_HAS_OPTIONAL
|
||||
template <typename T>
|
||||
std::size_t hash_value(std::optional<T> const&);
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_VARIANT
|
||||
std::size_t hash_value(std::monostate);
|
||||
template <typename... Types>
|
||||
std::size_t hash_value(std::variant<Types...> const&);
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
std::size_t hash_value(std::type_index);
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
std::size_t hash_value(std::error_code const&);
|
||||
std::size_t hash_value(std::error_condition const&);
|
||||
#endif
|
||||
|
||||
// Implementation
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <class T>
|
||||
inline std::size_t hash_value_signed(T val)
|
||||
{
|
||||
const unsigned 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)
|
||||
/ static_cast<int>(size_t_bits);
|
||||
|
||||
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 unsigned 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)
|
||||
/ static_cast<int>(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 SizeT>
|
||||
inline void hash_combine_impl(SizeT& seed, SizeT value)
|
||||
{
|
||||
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
inline void hash_combine_impl(boost::uint32_t& h1,
|
||||
boost::uint32_t k1)
|
||||
{
|
||||
const uint32_t c1 = 0xcc9e2d51;
|
||||
const uint32_t c2 = 0x1b873593;
|
||||
|
||||
k1 *= c1;
|
||||
k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
|
||||
k1 *= c2;
|
||||
|
||||
h1 ^= k1;
|
||||
h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
|
||||
h1 = h1*5+0xe6546b64;
|
||||
}
|
||||
|
||||
|
||||
// Don't define 64-bit hash combine on platforms without 64 bit integers,
|
||||
// and also not for 32-bit gcc as it warns about the 64-bit constant.
|
||||
#if !defined(BOOST_NO_INT64_T) && \
|
||||
!(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
|
||||
|
||||
inline void hash_combine_impl(boost::uint64_t& h,
|
||||
boost::uint64_t k)
|
||||
{
|
||||
const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
|
||||
const int r = 47;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h ^= k;
|
||||
h *= m;
|
||||
|
||||
// Completely arbitrary number, to prevent 0's
|
||||
// from hashing to 0.
|
||||
h += 0xe6546b64;
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_INT64_T
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return hash_detail::hash_value_signed(v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return hash_detail::hash_value_unsigned(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 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)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
return boost::hash_detail::hash_combine_impl(seed, hasher(v));
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class It>
|
||||
inline std::size_t hash_range(It first, It last)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
inline void hash_range(std::size_t& seed, It first, It last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template <class T>
|
||||
inline std::size_t hash_range(T* first, T* last)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void hash_range(std::size_t& seed, T* first, T* last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(const T (&x)[N])
|
||||
{
|
||||
return hash_range(x, x + N);
|
||||
}
|
||||
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(T (&x)[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)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
#if BOOST_HASH_HAS_STRING_VIEW
|
||||
template <class Ch>
|
||||
inline std::size_t hash_value(
|
||||
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const& v)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
#if BOOST_HASH_HAS_OPTIONAL
|
||||
template <typename T>
|
||||
inline std::size_t hash_value(std::optional<T> const& v) {
|
||||
if (!v) {
|
||||
// Arbitray value for empty optional.
|
||||
return 0x12345678;
|
||||
} else {
|
||||
boost::hash<T> hf;
|
||||
return hf(*v);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_VARIANT
|
||||
inline std::size_t hash_value(std::monostate) {
|
||||
return 0x87654321;
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
inline std::size_t hash_value(std::variant<Types...> const& v) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.index());
|
||||
std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v);
|
||||
return seed;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
inline std::size_t hash_value(std::type_index v)
|
||||
{
|
||||
return v.hash_code();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
inline std::size_t hash_value(std::error_code const& v) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.value());
|
||||
hash_combine(seed, &v.category());
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline std::size_t hash_value(std::error_condition const& v) {
|
||||
std::size_t seed = 0;
|
||||
hash_combine(seed, v.value());
|
||||
hash_combine(seed, &v.category());
|
||||
return seed;
|
||||
}
|
||||
#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 const reference.
|
||||
//
|
||||
// These are undefined later.
|
||||
|
||||
#define BOOST_HASH_SPECIALIZE(type) \
|
||||
template <> struct hash<type> \
|
||||
: public boost::hash_detail::hash_base<type> \
|
||||
{ \
|
||||
std::size_t operator()(type v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BOOST_HASH_SPECIALIZE_REF(type) \
|
||||
template <> struct hash<type> \
|
||||
: public boost::hash_detail::hash_base<type> \
|
||||
{ \
|
||||
std::size_t operator()(type const& v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
|
||||
#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \
|
||||
struct hash<type> \
|
||||
: public boost::hash_detail::hash_base<type> \
|
||||
{ \
|
||||
std::size_t operator()(type const& v) const \
|
||||
{ \
|
||||
return boost::hash_value(v); \
|
||||
} \
|
||||
};
|
||||
|
||||
BOOST_HASH_SPECIALIZE(bool)
|
||||
BOOST_HASH_SPECIALIZE(char)
|
||||
BOOST_HASH_SPECIALIZE(signed char)
|
||||
BOOST_HASH_SPECIALIZE(unsigned char)
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_HASH_SPECIALIZE(wchar_t)
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
BOOST_HASH_SPECIALIZE(char16_t)
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
BOOST_HASH_SPECIALIZE(char32_t)
|
||||
#endif
|
||||
BOOST_HASH_SPECIALIZE(short)
|
||||
BOOST_HASH_SPECIALIZE(unsigned short)
|
||||
BOOST_HASH_SPECIALIZE(int)
|
||||
BOOST_HASH_SPECIALIZE(unsigned int)
|
||||
BOOST_HASH_SPECIALIZE(long)
|
||||
BOOST_HASH_SPECIALIZE(unsigned long)
|
||||
|
||||
BOOST_HASH_SPECIALIZE(float)
|
||||
BOOST_HASH_SPECIALIZE(double)
|
||||
BOOST_HASH_SPECIALIZE(long double)
|
||||
|
||||
BOOST_HASH_SPECIALIZE_REF(std::string)
|
||||
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::wstring)
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::basic_string<char16_t>)
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
|
||||
#endif
|
||||
|
||||
#if BOOST_HASH_HAS_STRING_VIEW
|
||||
BOOST_HASH_SPECIALIZE_REF(std::string_view)
|
||||
# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::wstring_view)
|
||||
# endif
|
||||
# if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
|
||||
# endif
|
||||
# if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
|
||||
# endif
|
||||
#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 BOOST_HASH_HAS_OPTIONAL
|
||||
template <typename T>
|
||||
BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_HASH_HAS_VARIANT)
|
||||
template <typename... T>
|
||||
BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant<T...>)
|
||||
BOOST_HASH_SPECIALIZE(std::monostate)
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
BOOST_HASH_SPECIALIZE(std::type_index)
|
||||
#endif
|
||||
|
||||
#undef BOOST_HASH_SPECIALIZE
|
||||
#undef BOOST_HASH_SPECIALIZE_REF
|
||||
#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF
|
||||
|
||||
// Specializing boost::hash for pointers.
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T>
|
||||
struct hash<T*>
|
||||
: public boost::hash_detail::hash_base<T*>
|
||||
{
|
||||
std::size_t operator()(T* v) const
|
||||
{
|
||||
#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));
|
||||
|
||||
return x + (x >> 3);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// For compilers without partial specialization, we define a
|
||||
// boost::hash for all remaining types. But hash_impl is only defined
|
||||
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
|
||||
// is defined there will still be a compile error for types not supported
|
||||
// in the standard.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
struct hash_impl;
|
||||
|
||||
template <>
|
||||
struct hash_impl<true>
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: public boost::hash_detail::hash_base<T>
|
||||
{
|
||||
std::size_t operator()(T val) const
|
||||
{
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
|
||||
return boost::hash_value(val);
|
||||
#else
|
||||
std::size_t x = static_cast<std::size_t>(
|
||||
reinterpret_cast<std::ptrdiff_t>(val));
|
||||
|
||||
return x + (x >> 3);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <class T> struct hash
|
||||
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef BOOST_HASH_CHAR_TRAITS
|
||||
#undef BOOST_FUNCTIONAL_HASH_ROTL32
|
||||
|
||||
#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)
|
||||
#include <boost/container_hash/extensions.hpp>
|
||||
#endif
|
||||
36
include/boost/container_hash/hash_fwd.hpp
Normal file
36
include/boost/container_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/workaround.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
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
|
||||
@@ -3,5 +3,4 @@
|
||||
// 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>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
@@ -1,379 +1,6 @@
|
||||
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Copyright 2017 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/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(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#endif
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
#include <boost/type_traits/is_const.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
|
||||
{
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
static std::size_t call(Array const& v)
|
||||
#else
|
||||
static std::size_t call(Array& v)
|
||||
#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
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// 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 of hash_impl.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
struct hash_impl;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
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
|
||||
|
||||
// Visual C++ 6.5 has problems with nested member functions and
|
||||
// applying const to const types in templates. So we get this:
|
||||
|
||||
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 // Visual C++ 6.5
|
||||
}
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
}
|
||||
|
||||
#endif
|
||||
#include <boost/container_hash/extensions.hpp>
|
||||
|
||||
@@ -3,539 +3,4 @@
|
||||
// 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_HASH_HPP)
|
||||
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
#include <boost/functional/hash/hash_fwd.hpp>
|
||||
#include <functional>
|
||||
#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>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
#include <typeindex>
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#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(__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
|
||||
|
||||
namespace boost
|
||||
{
|
||||
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 (&x)[N]);
|
||||
|
||||
template< class T, unsigned N >
|
||||
std::size_t hash_value(T (&x)[N]);
|
||||
#endif
|
||||
|
||||
template <class Ch, class A>
|
||||
std::size_t hash_value(
|
||||
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
|
||||
|
||||
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
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return hash_detail::hash_value_signed(v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return hash_detail::hash_value_unsigned(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 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
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
template <class T>
|
||||
inline void hash_combine(std::size_t& seed, T& v)
|
||||
#else
|
||||
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)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
inline void hash_range(std::size_t& seed, It first, It last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
hash_combine(seed, *first);
|
||||
}
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template <class T>
|
||||
inline std::size_t hash_range(T* first, T* last)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void hash_range(std::size_t& seed, T* first, T* last)
|
||||
{
|
||||
for(; first != last; ++first)
|
||||
{
|
||||
boost::hash<T> hasher;
|
||||
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(const T (&x)[N])
|
||||
{
|
||||
return hash_range(x, x + N);
|
||||
}
|
||||
|
||||
template< class T, unsigned N >
|
||||
inline std::size_t hash_value(T (&x)[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)
|
||||
{
|
||||
return hash_range(v.begin(), v.end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
|
||||
{
|
||||
return boost::hash_detail::float_hash_value(v);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
inline std::size_t hash_value(std::type_index v)
|
||||
{
|
||||
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> \
|
||||
{ \
|
||||
std::size_t operator()(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); \
|
||||
} \
|
||||
};
|
||||
#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)
|
||||
BOOST_HASH_SPECIALIZE(signed char)
|
||||
BOOST_HASH_SPECIALIZE(unsigned char)
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
BOOST_HASH_SPECIALIZE(wchar_t)
|
||||
#endif
|
||||
BOOST_HASH_SPECIALIZE(short)
|
||||
BOOST_HASH_SPECIALIZE(unsigned short)
|
||||
BOOST_HASH_SPECIALIZE(int)
|
||||
BOOST_HASH_SPECIALIZE(unsigned int)
|
||||
BOOST_HASH_SPECIALIZE(long)
|
||||
BOOST_HASH_SPECIALIZE(unsigned long)
|
||||
|
||||
BOOST_HASH_SPECIALIZE(float)
|
||||
BOOST_HASH_SPECIALIZE(double)
|
||||
BOOST_HASH_SPECIALIZE(long double)
|
||||
|
||||
BOOST_HASH_SPECIALIZE_REF(std::string)
|
||||
#if !defined(BOOST_NO_STD_WSTRING)
|
||||
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
|
||||
|
||||
// Specializing boost::hash for pointers.
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <class T>
|
||||
struct hash<T*>
|
||||
: public std::unary_function<T*, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T* v) const
|
||||
{
|
||||
#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));
|
||||
|
||||
return x + (x >> 3);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// For compilers without partial specialization, we define a
|
||||
// boost::hash for all remaining types. But hash_impl is only defined
|
||||
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
|
||||
// is defined there will still be a compile error for types not supported
|
||||
// in the standard.
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template <bool IsPointer>
|
||||
struct hash_impl;
|
||||
|
||||
template <>
|
||||
struct hash_impl<true>
|
||||
{
|
||||
template <class T>
|
||||
struct inner
|
||||
: public std::unary_function<T, std::size_t>
|
||||
{
|
||||
std::size_t operator()(T val) const
|
||||
{
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
|
||||
return boost::hash_value(val);
|
||||
#else
|
||||
std::size_t x = static_cast<std::size_t>(
|
||||
reinterpret_cast<std::ptrdiff_t>(val));
|
||||
|
||||
return x + (x >> 3);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <class T> struct hash
|
||||
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
|
||||
::BOOST_NESTED_TEMPLATE inner<T>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef BOOST_HASH_CHAR_TRAITS
|
||||
|
||||
#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)
|
||||
#include <boost/functional/hash/extensions.hpp>
|
||||
#endif
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
@@ -3,38 +3,4 @@
|
||||
// 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
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#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/container_hash/hash_fwd.hpp>
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
// 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_fwd.hpp>
|
||||
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
|
||||
96
meta/explicit-failures-markup.xml
Normal file
96
meta/explicit-failures-markup.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 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)
|
||||
-->
|
||||
<explicit-failures-markup>
|
||||
<!-- container_hash -->
|
||||
<library name="container_hash">
|
||||
<mark-expected-failures>
|
||||
<test name="hash_value_array_test"/>
|
||||
<toolset name="msvc-6.5*"/>
|
||||
<toolset name="msvc-7.0*"/>
|
||||
<note author="Daniel James">
|
||||
hash_value is not overloaded for arrays for older versions
|
||||
of Visual C++. There is a work around so that
|
||||
boost::hash<T[N]>, boost::hash_combine and boost::hash_range
|
||||
work.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="hash_function_pointer_test"/>
|
||||
<toolset name="msvc-6.5*"/>
|
||||
<toolset name="msvc-7.0*"/>
|
||||
<note refid="2" author="Daniel James"/>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="hash_function_pointer_test"/>
|
||||
<toolset name="sun-5.7"/>
|
||||
<toolset name="sun-5.8"/>
|
||||
<toolset name="sun-5.9"/>
|
||||
<note author="Daniel James">
|
||||
On these compilers the wrong overload of hash_value is called
|
||||
when the argument is a hash function pointer. So calling
|
||||
hash_value doesn't work but boost::hash does work (and it's
|
||||
recommended that user never call hash_value directly so this
|
||||
shouldn't be a problem).
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="hash_long_double_test"/>
|
||||
<toolset name="gcc-3.4.3_sunos"/>
|
||||
<toolset name="*pa_risc"/>
|
||||
<note author="Daniel James">
|
||||
This platform has poor support for <code>long double</code> so
|
||||
the hash function perform poorly for values out of the range
|
||||
of <code>double</code> or if they differ at a greater precision
|
||||
that <code>double</code> is capable of representing.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="point" />
|
||||
<test name="books" />
|
||||
<toolset name="msvc-6.5*"/>
|
||||
<toolset name="msvc-7.0*"/>
|
||||
<note author="Daniel James">
|
||||
These examples only work on compilers with support for ADL.
|
||||
It is possible to work around this, but I wanted to keep the
|
||||
example code as clean as possible.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="point" />
|
||||
<toolset name="borland-*"/>
|
||||
<note author="Daniel James">
|
||||
It appears that Borland doesn't find friend functions defined
|
||||
in a class by ADL. This is easily fixed but this example is
|
||||
meant to show the typical way of customising boost::hash, not
|
||||
the portable way.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="hash_global_namespace_test" />
|
||||
<toolset name="borland-*"/>
|
||||
<note author="Daniel James">
|
||||
The test demonstrates a Borland bug - functions that aren't
|
||||
in a namespace don't appear to be found by ADL.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
|
||||
<mark-expected-failures>
|
||||
<test name="container_fwd_gcc_debug"/>
|
||||
<toolset name="darwin-4.2"/>
|
||||
<note author="Daniel James">
|
||||
Debug containers aren't supported on Apple's version of gcc 4.2.
|
||||
</note>
|
||||
</mark-expected-failures>
|
||||
</library>
|
||||
</explicit-failures-markup>
|
||||
20
meta/libraries.json
Normal file
20
meta/libraries.json
Normal file
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"key": "functional/hash",
|
||||
"boost-version": "1.33.0",
|
||||
"name": "Container Hash",
|
||||
"authors": [
|
||||
"Daniel James"
|
||||
],
|
||||
"maintainers": [
|
||||
"Daniel James <dnljms -at- gmail.com>"
|
||||
],
|
||||
"description": "An STL-compatible hash function object that can be extended to hash user defined types.",
|
||||
"std": [
|
||||
"tr1"
|
||||
],
|
||||
"category": [
|
||||
"Function-objects"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -12,13 +12,16 @@ project hash-tests
|
||||
#<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>clang:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wsign-conversion -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
|
||||
test-suite container_hash/hash
|
||||
:
|
||||
[ run hash_info.cpp : : : <test-info>always_show_run_output ]
|
||||
[ compile check_float_funcs.cpp ]
|
||||
[ run hash_fwd_test_1.cpp ]
|
||||
[ run hash_fwd_test_2.cpp ]
|
||||
[ run hash_number_test.cpp ]
|
||||
@@ -40,7 +43,10 @@ test-suite functional/hash
|
||||
[ run hash_set_test.cpp ]
|
||||
[ run hash_map_test.cpp ]
|
||||
[ run hash_complex_test.cpp ]
|
||||
[ run hash_optional_test.cpp ]
|
||||
[ run hash_variant_test.cpp ]
|
||||
[ run hash_type_index_test.cpp ]
|
||||
[ run hash_system_error_test.cpp ]
|
||||
[ run hash_std_array_test.cpp ]
|
||||
[ run hash_std_tuple_test.cpp ]
|
||||
[ run hash_std_smart_ptr_test.cpp ]
|
||||
@@ -54,7 +60,7 @@ test-suite functional/hash
|
||||
[ run hash_no_ext_macro_2.cpp ]
|
||||
;
|
||||
|
||||
test-suite functional/hash_no_ext
|
||||
test-suite container_hash/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 ]
|
||||
@@ -67,7 +73,7 @@ test-suite functional/hash_no_ext
|
||||
|
||||
# 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
|
||||
test-suite container_hash/hash_no_generic_float
|
||||
:
|
||||
[ run hash_float_test.cpp
|
||||
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||
@@ -76,6 +82,6 @@ test-suite functional/hash_no_generic_float
|
||||
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||
: hash_long_double_test_no_generic ]
|
||||
;
|
||||
explicit functional/hash_no_generic_float ;
|
||||
explicit container_hash/hash_no_generic_float ;
|
||||
|
||||
build-project ../examples ;
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
template <class T>
|
||||
void compile_time_tests(T*)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
|
||||
std::unary_function<T, std::size_t>, BOOST_HASH_TEST_NAMESPACE::hash<T> >::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T,
|
||||
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::argument_type
|
||||
>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<std::size_t,
|
||||
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::result_type
|
||||
>::value));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,4 +18,8 @@
|
||||
// before doing anything else.
|
||||
#pragma warning(disable:4201) // nonstandard extension used :
|
||||
// nameless struct/union
|
||||
|
||||
#endif
|
||||
|
||||
#define HASH_TEST_CAT(x, y) HASH_TEST_CAT2(x, y)
|
||||
#define HASH_TEST_CAT2(x, y) x##y
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
// 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.
|
||||
// Check that boost/container_hash/extensions.hpp works okay.
|
||||
//
|
||||
// It probably should be in boost/functional/hash/detail, but since it isn't it
|
||||
// It probably should be in boost/container_hash/detail, but since it isn't it
|
||||
// should work.
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash/extensions.hpp>
|
||||
#include <boost/container_hash/extensions.hpp>
|
||||
|
||||
int main() {
|
||||
int x[2] = { 2, 3 };
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
# 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 ]
|
||||
;
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ int main() {}
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4244) // conversion from 'unsigned long' to
|
||||
@@ -84,8 +84,8 @@ void complex_integral_tests(Integer*)
|
||||
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));
|
||||
generic_complex_tests(complex(Integer(-243897),Integer(-49923874)));
|
||||
generic_complex_tests(complex(Integer(-543),Integer(763)));
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace test
|
||||
|
||||
std::size_t hash() const
|
||||
{
|
||||
return value_ * 10;
|
||||
return static_cast<std::size_t>(value_ * 10);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
@@ -45,11 +45,11 @@ namespace boost
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
namespace test {
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/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 <boost/container_hash/detail/limits.hpp>
|
||||
#include <boost/container_hash/detail/float_functions.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace test
|
||||
|
||||
std::size_t hash() const
|
||||
{
|
||||
return value_ * 10;
|
||||
return static_cast<std::size_t>(value_ * 10);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
@@ -48,11 +48,11 @@ namespace boost
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
void void_func1() { static int x = 1; ++x; }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "./config.hpp"
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <string>
|
||||
|
||||
void fwd_test1()
|
||||
|
||||
@@ -15,7 +15,7 @@ int main() {}
|
||||
#else
|
||||
|
||||
#include "./hash_fwd_test.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
template <class T> void unused(T const&) {}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ struct custom
|
||||
|
||||
std::size_t hash() const
|
||||
{
|
||||
return value_ * 10;
|
||||
return static_cast<std::size_t>(value_ * 10);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
@@ -46,11 +46,11 @@ namespace boost
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
102
test/hash_info.cpp
Normal file
102
test/hash_info.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
// Copyright 2017 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)
|
||||
|
||||
// Not a test, just a small program to write out configuration info
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
|
||||
struct msvc_version {
|
||||
unsigned version;
|
||||
char const* description;
|
||||
|
||||
friend bool operator<(msvc_version const& v1, msvc_version const& v2) {
|
||||
return v1.version < v2.version;
|
||||
}
|
||||
};
|
||||
|
||||
void write_compiler_info() {
|
||||
// From:
|
||||
// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
|
||||
// https://blogs.msdn.microsoft.com/vcblog/2017/11/15/side-by-side-minor-version-msvc-toolsets-in-visual-studio-2017/
|
||||
msvc_version versions[] = {
|
||||
{0, "Old Visual C++"},
|
||||
{1000, "Visual C++ 4.x, VS4.0?"},
|
||||
{1100, "Visual C++ 5.0, VS97"},
|
||||
{1200, "Visual C++ 6.0, VS6.0"},
|
||||
{1300, "Visual C++ 7.0, VS.NET 2002"},
|
||||
{1310, "Visual C++ 7.1, VS.NET 2003"},
|
||||
{1400, "Visual C++ 8.0, VS2005"},
|
||||
{1500, "Visual C++ 9.0, VS2008"},
|
||||
{1600, "Visual C++ 10.0, VS2010"},
|
||||
{1700, "Visual C++ 11.0, VS2012"},
|
||||
{1800, "Visual C++ 12.0, VS2013"},
|
||||
{1900, "Visual C++ 14.00, VS2015"},
|
||||
{1910, "Visual C++ 14.10, VS2017 15.1/2"},
|
||||
{1911, "Visual C++ 14.11, VS2017 15.3/4"},
|
||||
{1912, "Visual C++ 14.12, VS2017 15.5"},
|
||||
{1913, "Visual C++ 14.13, VS2017 15.6"}
|
||||
};
|
||||
|
||||
msvc_version msvc = { BOOST_MSVC, "" };
|
||||
msvc_version* v = std::upper_bound(versions,
|
||||
versions + sizeof(versions) / sizeof(*versions),
|
||||
msvc) - 1;
|
||||
unsigned difference = msvc.version - v->version;
|
||||
|
||||
std::cout << v->description << std::endl;
|
||||
if (difference) {
|
||||
std::cout << "+" << difference << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void write_compiler_info() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
write_compiler_info();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
std::cout << "__cplusplus: "
|
||||
<< __cplusplus
|
||||
<< std::endl;
|
||||
#endif
|
||||
|
||||
std::cout << "BOOST_HASH_CXX17: "
|
||||
<< BOOST_HASH_CXX17
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "BOOST_HASH_HAS_STRING_VIEW: "
|
||||
<< BOOST_HASH_HAS_STRING_VIEW
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "BOOST_HASH_HAS_OPTIONAL: "
|
||||
<< BOOST_HASH_HAS_OPTIONAL
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "BOOST_HASH_HAS_VARIANT: "
|
||||
<< BOOST_HASH_HAS_VARIANT
|
||||
<< std::endl;
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
std::cout << "No <typeindex>" << std::endl;
|
||||
#else
|
||||
std::cout << "<typeindex>" << std::endl;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
std::cout << "No <system_error>" << std::endl;
|
||||
#else
|
||||
std::cout << "<system_error>" << std::endl;
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
@@ -7,15 +7,13 @@
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
#else
|
||||
|
||||
#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)
|
||||
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
void integer_tests(T* = 0)
|
||||
@@ -59,7 +57,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
{
|
||||
integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
|
||||
integer_tests((CONTAINER_TYPE<int, float>*) 0);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
template <class T> void ignore(T const&) {}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
# if defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# undef BOOST_HASH_NO_EXTENSIONS
|
||||
# endif
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
|
||||
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
||||
# define BOOST_HASH_NO_EXTENSIONS
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <deque>
|
||||
|
||||
int main()
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||
# define BOOST_HASH_NO_EXTENSIONS
|
||||
# endif
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
|
||||
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
||||
# undef BOOST_HASH_NO_EXTENSIONS
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <map>
|
||||
|
||||
int main()
|
||||
|
||||
@@ -8,15 +8,14 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/functional/hash/detail/limits.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/container_hash/detail/limits.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
@@ -58,8 +57,6 @@ void numeric_extra_tests(typename
|
||||
template <class T>
|
||||
void numeric_test(T*)
|
||||
{
|
||||
typedef boost::hash_detail::limits<T> limits;
|
||||
|
||||
compile_time_tests((T*) 0);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||
@@ -129,16 +126,20 @@ void poor_quality_tests(T*)
|
||||
BOOST_TEST(x1(T(1)) != x2(T(-1)));
|
||||
if(T(1) != T(2))
|
||||
BOOST_TEST(x1(T(1)) != x2(T(2)));
|
||||
if((limits::max)() != (limits::max)() - 1)
|
||||
BOOST_TEST(x1(static_cast<T>((limits::max)()))
|
||||
!= x2(static_cast<T>((limits::max)() - 1)));
|
||||
|
||||
// TODO: This test is useless for floating point numbers.
|
||||
T max_number = static_cast<T>((limits::max)());
|
||||
T max_minus_one = static_cast<T>(max_number - 1);
|
||||
if (max_number != max_minus_one) {
|
||||
BOOST_TEST(x1(max_number) != x1(max_minus_one));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -162,6 +163,12 @@ int main()
|
||||
NUMERIC_TEST(unsigned char, uchar)
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||
NUMERIC_TEST(wchar_t, wchar)
|
||||
#endif
|
||||
#ifndef BOOST_NO_CXX11_CHAR16_T
|
||||
NUMERIC_TEST(char16_t, char16)
|
||||
#endif
|
||||
#ifndef BOOST_NO_CXX11_CHAR32_T
|
||||
NUMERIC_TEST(char32_t, char32)
|
||||
#endif
|
||||
NUMERIC_TEST(short, short)
|
||||
NUMERIC_TEST(unsigned short, ushort)
|
||||
|
||||
70
test/hash_optional_test.cpp
Normal file
70
test/hash_optional_test.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
// Copyright 2018 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"
|
||||
|
||||
#ifndef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if BOOST_HASH_HAS_OPTIONAL
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
void test_optional_int()
|
||||
{
|
||||
std::optional<int> x1a;
|
||||
std::optional<int> x1b;
|
||||
std::optional<int> x2a(10);
|
||||
std::optional<int> x2b(x2a);
|
||||
std::optional<int> x3(20);
|
||||
|
||||
boost::hash<std::optional<int> > hasher;
|
||||
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1a));
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1b));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x2a));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x2a) == hasher(x2a));
|
||||
BOOST_TEST(hasher(x2b) == hasher(x2b));
|
||||
BOOST_TEST(hasher(x2a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x3) == hasher(x3));
|
||||
}
|
||||
|
||||
void test_optional_string()
|
||||
{
|
||||
std::optional<std::string> x1a;
|
||||
std::optional<std::string> x1b;
|
||||
std::optional<std::string> x2a("10");
|
||||
std::optional<std::string> x2b(x2a);
|
||||
std::optional<std::string> x3("20");
|
||||
|
||||
boost::hash<std::optional<std::string> > hasher;
|
||||
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1a));
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1b));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x2a));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x2a) == hasher(x2a));
|
||||
BOOST_TEST(hasher(x2b) == hasher(x2b));
|
||||
BOOST_TEST(hasher(x2a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x3) == hasher(x3));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if BOOST_HASH_HAS_OPTIONAL
|
||||
test_optional_int();
|
||||
test_optional_string();
|
||||
#else
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<optional> not available." << std::endl;
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ int main() {}
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
#else
|
||||
|
||||
#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)
|
||||
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
void integer_tests(T* = 0)
|
||||
{
|
||||
typedef typename T::value_type value_type;
|
||||
|
||||
const int number_of_containers = 11;
|
||||
T containers[number_of_containers];
|
||||
|
||||
@@ -27,16 +27,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
containers[i].push_back(0);
|
||||
}
|
||||
|
||||
containers[5].push_back(1);
|
||||
containers[6].push_back(1);
|
||||
containers[6].push_back(1);
|
||||
containers[7].push_back(-1);
|
||||
containers[8].push_back(-1);
|
||||
containers[8].push_back(-1);
|
||||
containers[9].push_back(1);
|
||||
containers[9].push_back(-1);
|
||||
containers[10].push_back(-1);
|
||||
containers[10].push_back(1);
|
||||
containers[5].push_back(value_type(1));
|
||||
containers[6].push_back(value_type(1));
|
||||
containers[6].push_back(value_type(1));
|
||||
containers[7].push_back(value_type(-1));
|
||||
containers[8].push_back(value_type(-1));
|
||||
containers[8].push_back(value_type(-1));
|
||||
containers[9].push_back(value_type(1));
|
||||
containers[9].push_back(value_type(-1));
|
||||
containers[10].push_back(value_type(-1));
|
||||
containers[10].push_back(value_type(1));
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
{
|
||||
integer_tests((CONTAINER_TYPE<char>*) 0);
|
||||
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
#error "CONTAINER_TYPE not defined"
|
||||
#else
|
||||
|
||||
#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)
|
||||
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||
{
|
||||
template <class T>
|
||||
void integer_tests(T* = 0)
|
||||
{
|
||||
typedef typename T::value_type value_type;
|
||||
|
||||
const int number_of_containers = 12;
|
||||
T containers[number_of_containers];
|
||||
|
||||
@@ -27,19 +27,19 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
containers[i].insert(0);
|
||||
}
|
||||
|
||||
containers[6].insert(1);
|
||||
containers[7].insert(1);
|
||||
containers[7].insert(1);
|
||||
containers[8].insert(-1);
|
||||
containers[9].insert(-1);
|
||||
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);
|
||||
containers[6].insert(value_type(1));
|
||||
containers[7].insert(value_type(1));
|
||||
containers[7].insert(value_type(1));
|
||||
containers[8].insert(value_type(-1));
|
||||
containers[9].insert(value_type(-1));
|
||||
containers[9].insert(value_type(-1));
|
||||
containers[10].insert(value_type(-1));
|
||||
containers[10].insert(value_type(1));
|
||||
containers[11].insert(value_type(1));
|
||||
containers[11].insert(value_type(2));
|
||||
containers[11].insert(value_type(3));
|
||||
containers[11].insert(value_type(4));
|
||||
containers[11].insert(value_type(5));
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
||||
}
|
||||
}
|
||||
|
||||
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
|
||||
{
|
||||
integer_tests((CONTAINER_TYPE<char>*) 0);
|
||||
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||
#define TEST_ARRAY
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#define TEST_TUPLE
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <string>
|
||||
#include "./compile_time.hpp"
|
||||
|
||||
@@ -38,7 +38,24 @@ void string_tests()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_STD_WSTRING)
|
||||
void string0_tests()
|
||||
{
|
||||
std::string x1(1, '\0');
|
||||
std::string x2(2, '\0');
|
||||
std::string x3(3, '\0');
|
||||
std::string x4(10, '\0');
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher;
|
||||
|
||||
BOOST_TEST(hasher(x1) != hasher(x2));
|
||||
BOOST_TEST(hasher(x1) != hasher(x3));
|
||||
BOOST_TEST(hasher(x1) != hasher(x4));
|
||||
BOOST_TEST(hasher(x2) != hasher(x3));
|
||||
BOOST_TEST(hasher(x2) != hasher(x4));
|
||||
BOOST_TEST(hasher(x3) != hasher(x4));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
void wstring_tests()
|
||||
{
|
||||
compile_time_tests((std::wstring*) 0);
|
||||
@@ -63,11 +80,105 @@ void wstring_tests()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
void u16string_tests()
|
||||
{
|
||||
compile_time_tests((std::u16string*) 0);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::u16string> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::u16string> x2;
|
||||
|
||||
BOOST_TEST(x1(u"Hello") == x2(std::u16string(u"Hel") + u"lo"));
|
||||
BOOST_TEST(x1(u"") == x2(std::u16string()));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::u16string value1;
|
||||
std::u16string value2(u"Hello");
|
||||
|
||||
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
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
void u32string_tests()
|
||||
{
|
||||
compile_time_tests((std::u32string*) 0);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::u32string> x1;
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::u32string> x2;
|
||||
|
||||
BOOST_TEST(x1(U"Hello") == x2(std::u32string(U"Hel") + U"lo"));
|
||||
BOOST_TEST(x1(U"") == x2(std::u32string()));
|
||||
|
||||
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||
std::u32string value1;
|
||||
std::u32string value2(U"Hello");
|
||||
|
||||
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
|
||||
|
||||
template <typename StringType>
|
||||
void generic_string_tests(StringType*)
|
||||
{
|
||||
std::string x1(1, '\0');
|
||||
std::string x2(2, '\0');
|
||||
std::string x3(3, '\0');
|
||||
std::string x4(10, '\0');
|
||||
std::string x5 = x2 + "hello" + x2;
|
||||
|
||||
StringType strings[] = {
|
||||
"",
|
||||
"hello",
|
||||
x1,
|
||||
x2,
|
||||
x3,
|
||||
x4,
|
||||
x5
|
||||
};
|
||||
|
||||
std::size_t const strings_length = sizeof(strings) / sizeof(StringType);
|
||||
boost::hash<StringType> hash;
|
||||
|
||||
for (std::size_t i = 0; i < strings_length; ++i) {
|
||||
std::size_t hash_i = hash(strings[i]);
|
||||
for (std::size_t j = 0; j < strings_length; ++j) {
|
||||
std::size_t hash_j = hash(strings[j]);
|
||||
BOOST_TEST((hash_i == hash_j) == (i == j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string_tests();
|
||||
#if !defined(BOOST_NO_STD_WSTRING)
|
||||
string0_tests();
|
||||
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
wstring_tests();
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||
u16string_tests();
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||
u32string_tests();
|
||||
#endif
|
||||
|
||||
generic_string_tests((std::string*) 0);
|
||||
#if BOOST_HASH_HAS_STRING_VIEW
|
||||
generic_string_tests((std::string_view*) 0);
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
55
test/hash_system_error_test.cpp
Normal file
55
test/hash_system_error_test.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
// Copyright 2018 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"
|
||||
|
||||
#ifndef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
|
||||
#include <system_error>
|
||||
|
||||
void test_error_code()
|
||||
{
|
||||
std::error_code err1a = std::make_error_code(std::errc::argument_list_too_long);
|
||||
std::error_code err1b = std::make_error_code(std::errc::argument_list_too_long);
|
||||
std::error_code err2 = std::make_error_code(std::errc::bad_file_descriptor);
|
||||
|
||||
boost::hash<std::error_code> hasher;
|
||||
|
||||
BOOST_TEST(hasher(err1a) == hasher(err1a));
|
||||
BOOST_TEST(hasher(err1a) == hasher(err1b));
|
||||
BOOST_TEST(hasher(err1a) != hasher(err2));
|
||||
}
|
||||
|
||||
void test_error_condition()
|
||||
{
|
||||
std::error_condition err1a = std::make_error_condition(std::errc::directory_not_empty);
|
||||
std::error_condition err1b = std::make_error_condition(std::errc::directory_not_empty);
|
||||
std::error_condition err2 = std::make_error_condition(std::errc::filename_too_long);
|
||||
|
||||
boost::hash<std::error_condition> hasher;
|
||||
|
||||
BOOST_TEST(hasher(err1a) == hasher(err1a));
|
||||
BOOST_TEST(hasher(err1a) == hasher(err1b));
|
||||
BOOST_TEST(hasher(err1a) != hasher(err2));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
test_error_code();
|
||||
test_error_condition();
|
||||
#else
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<system_error> not available." << std::endl;
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -8,10 +8,10 @@
|
||||
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
#else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
|
||||
100
test/hash_variant_test.cpp
Normal file
100
test/hash_variant_test.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
// Copyright 2018 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"
|
||||
|
||||
#ifndef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#if BOOST_HASH_HAS_VARIANT
|
||||
|
||||
#include <variant>
|
||||
#include <string>
|
||||
|
||||
void test_monostate()
|
||||
{
|
||||
std::monostate x1;
|
||||
std::monostate x2;
|
||||
|
||||
boost::hash<std::monostate> hasher;
|
||||
|
||||
BOOST_TEST(hasher(x1) == hasher(x2));
|
||||
}
|
||||
|
||||
void test_variant_int()
|
||||
{
|
||||
std::variant<std::monostate, int> x1a;
|
||||
std::variant<std::monostate, int> x1b;
|
||||
std::variant<std::monostate, int> x2a(10);
|
||||
std::variant<std::monostate, int> x2b(x2a);
|
||||
std::variant<std::monostate, int> x3(20);
|
||||
|
||||
boost::hash<std::variant<std::monostate, int> > hasher;
|
||||
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1a));
|
||||
BOOST_TEST(hasher(x1a) == hasher(x1b));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x2a));
|
||||
BOOST_TEST(hasher(x1a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x2a) == hasher(x2a));
|
||||
BOOST_TEST(hasher(x2b) == hasher(x2b));
|
||||
BOOST_TEST(hasher(x2a) != hasher(x3));
|
||||
BOOST_TEST(hasher(x3) == hasher(x3));
|
||||
}
|
||||
|
||||
struct custom1 {
|
||||
int value;
|
||||
friend std::size_t hash_value(custom1 v) { return boost::hash_value(v.value); }
|
||||
};
|
||||
|
||||
struct custom2 {
|
||||
int value;
|
||||
friend std::size_t hash_value(custom2 v) { return boost::hash_value(v.value); }
|
||||
};
|
||||
|
||||
void test_variant_unique_types()
|
||||
{
|
||||
custom1 x11 = { 0 };
|
||||
custom1 x12 = { 1 };
|
||||
custom2 x21 = { 0 };
|
||||
custom2 x22 = { 1 };
|
||||
|
||||
boost::hash<custom1> hasher1;
|
||||
boost::hash<custom2> hasher2;
|
||||
|
||||
BOOST_TEST(hasher1(x11) == hasher2(x21));
|
||||
BOOST_TEST(hasher1(x11) != hasher2(x22));
|
||||
BOOST_TEST(hasher1(x12) != hasher2(x21));
|
||||
BOOST_TEST(hasher1(x12) == hasher2(x22));
|
||||
|
||||
typedef std::variant<custom1, custom2> variant_type;
|
||||
|
||||
variant_type y11(x11);
|
||||
variant_type y12(x12);
|
||||
variant_type y21(x21);
|
||||
variant_type y22(x22);
|
||||
|
||||
boost::hash<variant_type> hasher;
|
||||
|
||||
BOOST_TEST(hasher(y11) != hasher(y21));
|
||||
BOOST_TEST(hasher(y11) != hasher(y22));
|
||||
BOOST_TEST(hasher(y12) != hasher(y21));
|
||||
BOOST_TEST(hasher(y12) != hasher(y22));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#if BOOST_HASH_HAS_VARIANT
|
||||
test_variant_int();
|
||||
test_variant_unique_types();
|
||||
#else
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<variant> not available." << std::endl;
|
||||
#endif
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -9,11 +9,11 @@
|
||||
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||
# include <functional>
|
||||
# else
|
||||
# include <boost/functional/hash.hpp>
|
||||
# include <boost/container_hash/hash.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
@@ -25,11 +25,44 @@ using std::vector;
|
||||
|
||||
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||
|
||||
namespace vector_bool_tests
|
||||
{
|
||||
void vector_bool_test() {
|
||||
std::vector<bool> x_empty1,x_empty2,x1,x1a,x2,x3;
|
||||
|
||||
x1.push_back(0);
|
||||
x1a.push_back(0);
|
||||
x2.push_back(1);
|
||||
x3.push_back(0);
|
||||
x3.push_back(0);
|
||||
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<bool> > hasher;
|
||||
|
||||
BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty1));
|
||||
BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty2));
|
||||
BOOST_TEST_NE(hasher(x_empty1), hasher(x1));
|
||||
BOOST_TEST_NE(hasher(x_empty1), hasher(x2));
|
||||
BOOST_TEST_NE(hasher(x_empty1), hasher(x3));
|
||||
|
||||
BOOST_TEST_EQ(hasher(x1), hasher(x1));
|
||||
BOOST_TEST_EQ(hasher(x1), hasher(x1a));
|
||||
BOOST_TEST_NE(hasher(x1), hasher(x2));
|
||||
BOOST_TEST_NE(hasher(x1), hasher(x3));
|
||||
|
||||
BOOST_TEST_EQ(hasher(x2), hasher(x2));
|
||||
BOOST_TEST_NE(hasher(x2), hasher(x3));
|
||||
|
||||
BOOST_TEST_EQ(hasher(x3), hasher(x3));
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||
vector_tests::vector_hash_integer_tests();
|
||||
#endif
|
||||
|
||||
vector_bool_tests::vector_bool_test();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// 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 <boost/container_hash/hash.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
#include "./config.hpp"
|
||||
|
||||
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <vector>
|
||||
|
||||
int f(std::size_t hash1, int* x1) {
|
||||
@@ -20,7 +20,7 @@ int f(std::size_t hash1, int* x1) {
|
||||
|
||||
// Check that std::vector<std::size_t> is avaiable in this file.
|
||||
std::vector<std::size_t> x;
|
||||
x.push_back(*x1);
|
||||
x.push_back(static_cast<std::size_t>(*x1));
|
||||
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
||||
return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||
#define BOOST_HASH_NO_EXTENSIONS
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
extern int f(std::size_t, int*);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
extern int f();
|
||||
int main() { return f(); }
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
int f() { return 0; }
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "./config.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
typedef list<int> foo;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user