forked from boostorg/container_hash
Compare commits
329 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a7fc581ed | |||
| 5048576921 | |||
| 5f858645a0 | |||
| fd310d2706 | |||
| 90a0e36638 | |||
| 1ce57acc41 | |||
| 81a65eb01c | |||
| 9fbda1a98a | |||
| 62f29ea201 | |||
| f054fe932f | |||
| 83a874ed49 | |||
| 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 | |||
| c3e54942e8 | |||
| 10c83e95d9 | |||
| 734eb87d2a | |||
| af17fa46fb | |||
| e26c102522 | |||
| 378007cf94 | |||
| 61df9052e1 | |||
| dea8d12a04 | |||
| 1870aa9534 | |||
| b1ca4cf0d4 | |||
| 0d6cee7e64 | |||
| 9dad407f06 | |||
| 7d148af8d2 | |||
| 4aec4be0ed | |||
| bb8ebafca1 | |||
| 7e162c4f03 | |||
| 061e0d9d6d | |||
| cc091d5d98 | |||
| e5f3356742 | |||
| 9721f9c764 | |||
| 713b688159 | |||
| 8a8ab9ec70 | |||
| 13a86a7a26 | |||
| 0e0906b0a4 | |||
| 67ad8c2151 | |||
| be4292842d | |||
| 473b1da8de | |||
| 8afae2e762 | |||
| 03380087a9 | |||
| 9dcc33ab1b | |||
| d8adc5aa24 | |||
| 7f7ecfc717 | |||
| dfd48ef498 | |||
| a2756e75e8 | |||
| 9c37cd46b1 | |||
| acf1f3bc48 | |||
| b856e6308d | |||
| b4b4a559e0 | |||
| 853a713cf2 | |||
| 043571dabf | |||
| 7b2f73c225 | |||
| eec47991f9 | |||
| f1de575546 | |||
| 05f16beaf0 | |||
| 34a6eebf7e | |||
| 9119b2646b | |||
| 12f49f7c53 | |||
| 0757aea7cb | |||
| 92fe67f714 | |||
| 73b507c728 | |||
| 330040aea9 | |||
| 5ebe3ad87d | |||
| 411ac66581 | |||
| 75bcfdeb36 | |||
| af3a31090c | |||
| dfe0ad3a60 | |||
| 806abd0ddf | |||
| c409903f5e | |||
| 8ef04ed807 | |||
| 6be66ba092 | |||
| 033ef4b507 | |||
| 0d4c55854b | |||
| 18b143cad1 | |||
| 8bc410f571 | |||
| 68f0d9bc6b | |||
| 5611f4238e | |||
| 346e62f53f | |||
| 963d06acb8 | |||
| f3229da836 | |||
| 441cea413d | |||
| 4f3265079d | |||
| 98953a28c7 | |||
| c3d01123fa | |||
| f98a942e2e | |||
| 9a38ebf8c3 | |||
| a6f8c51afb | |||
| 903b1e409e | |||
| eb040cb89b | |||
| d92209d725 | |||
| 58e42260d5 | |||
| 56293f4313 | |||
| 335930c652 | |||
| da096ddf8c | |||
| 15bc3339e2 | |||
| 8c0e9a2b09 | |||
| 664522596f | |||
| cc0710b8a2 | |||
| ce885af9b0 | |||
| 9e641187c6 | |||
| 7dc95d044d | |||
| ad614b3d5f | |||
| fc7eb28826 | |||
| ed598f865e | |||
| 482f038837 | |||
| a2e947588d | |||
| 982b350d71 | |||
| 80b88f24c1 | |||
| 577054de93 | |||
| a98b37d12f | |||
| fc3b3863b4 | |||
| 906f632706 | |||
| afc4d6664f | |||
| bbfb6fd32c | |||
| 38d131c158 | |||
| 2553a5fbdc | |||
| 55fac118e9 | |||
| 5ce1a71c84 | |||
| 425de7d1dd | |||
| a60758dec2 | |||
| f544265741 | |||
| 7af7c59420 | |||
| 733422d1b9 | |||
| f3072d2023 | |||
| 77f856e3cf | |||
| 6544b32920 | |||
| 538b8fb95a | |||
| fdc0995489 | |||
| e042170fb9 | |||
| 316b1aa9f0 | |||
| 692d65d0e4 | |||
| 0ba3e9b282 | |||
| 98f0f11423 | |||
| e67ee6032a | |||
| 6e37c616db | |||
| 5860602e5c | |||
| 5f10c2bb7e | |||
| 6d7a55a4f7 | |||
| 0ed492ba18 | |||
| 2734e22b50 | |||
| 9938fad017 | |||
| 4787563f96 | |||
| 01630b4053 | |||
| 78eeabaeb2 | |||
| d45d471e34 | |||
| 3882189584 | |||
| 079f8025b3 | |||
| b43c9fa145 | |||
| b0ceeca154 | |||
| d8bfb81914 | |||
| 9958072d2a | |||
| 99c6e89390 | |||
| 84e1b951f5 | |||
| 3ee9d7d507 | |||
| 1d792ecb45 | |||
| e75f94f71d | |||
| 5db98a2dda | |||
| 07b565143f | |||
| d8980c3f09 | |||
| 83b052b784 | |||
| c51bebf8a4 | |||
| 8b98036bb8 | |||
| 4774d24966 | |||
| 13f44653b5 | |||
| e20c872440 | |||
| 600740e2ae | |||
| 52a964ae91 | |||
| 3d79c2f1e4 | |||
| 3cf1a67771 | |||
| 9cc8c20413 | |||
| 9f4a6a966e | |||
| 15d4153c37 | |||
| 326a338add | |||
| b0459a20da | |||
| 909d0c9547 | |||
| 912aed0b57 | |||
| e5d343faea | |||
| 3e320b7ae5 | |||
| 8bc6175fa0 | |||
| 6751e9cf47 | |||
| 004e4df2a2 | |||
| 411f559730 | |||
| 8a6aba46c7 | |||
| 65b103e812 | |||
| c160428eff | |||
| dda32a279a | |||
| f1a8a0fde8 | |||
| 814476afa2 | |||
| 9ef99e556a | |||
| 2aff9855bb | |||
| 72cb0e7788 | |||
| 220c3a4e62 | |||
| b0b7f17984 | |||
| 342284f4cf | |||
| fe6449fea6 | |||
| a3e434ec47 | |||
| 7c72c09288 | |||
| 45dfe7d9c5 | |||
| 2560590a2b | |||
| c984bbb5f0 | |||
| 0480bcf503 |
@@ -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
@@ -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
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright 2018 Mike Dev
|
||||||
|
# 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
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(BoostContainerHash LANGUAGES CXX)
|
||||||
|
|
||||||
|
add_library(boost_container_hash INTERFACE)
|
||||||
|
add_library(Boost::container_hash ALIAS boost_container_hash)
|
||||||
|
|
||||||
|
target_include_directories(boost_container_hash INTERFACE include)
|
||||||
|
|
||||||
|
target_link_libraries(boost_container_hash
|
||||||
|
INTERFACE
|
||||||
|
Boost::assert
|
||||||
|
Boost::config
|
||||||
|
Boost::core
|
||||||
|
Boost::detail
|
||||||
|
Boost::integer
|
||||||
|
Boost::static_assert
|
||||||
|
Boost::type_traits
|
||||||
|
)
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright Troy D. Straszheim
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# See http://www.boost.org/LICENSE_1_0.txt
|
|
||||||
#
|
|
||||||
message(STATUS "functional/hash docs need love")
|
|
||||||
|
|
||||||
+10
-4
@@ -3,17 +3,23 @@
|
|||||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
# 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)
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
using boostbook ;
|
||||||
|
using quickbook ;
|
||||||
|
|
||||||
xml hash : hash.qbk ;
|
xml hash : hash.qbk ;
|
||||||
boostbook standalone : hash :
|
boostbook standalone : hash :
|
||||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
|
||||||
<xsl:param>boost.root=../../../..
|
<xsl:param>boost.root=../../../..
|
||||||
<xsl:param>boost.libraries=../../../libraries.htm
|
|
||||||
<xsl:param>navig.graphics=1
|
|
||||||
|
|
||||||
<xsl:param>chunk.first.sections=1
|
<xsl:param>chunk.first.sections=1
|
||||||
<xsl:param>chunk.section.depth=2
|
<xsl:param>chunk.section.depth=2
|
||||||
<xsl:param>generate.section.toc.level=2
|
<xsl:param>generate.section.toc.level=2
|
||||||
<xsl:param>toc.section.depth=1
|
<xsl:param>toc.section.depth=1
|
||||||
<xsl:param>toc.max.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 ;
|
||||||
|
|||||||
+133
-4
@@ -3,6 +3,8 @@
|
|||||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
/ 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) ]
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||||
|
|
||||||
|
[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
|
||||||
|
|
||||||
[section:changes Change Log]
|
[section:changes Change Log]
|
||||||
|
|
||||||
[h2 Boost 1.33.0]
|
[h2 Boost 1.33.0]
|
||||||
@@ -41,7 +43,7 @@
|
|||||||
the number of times combine is called and hopefully give a better
|
the number of times combine is called and hopefully give a better
|
||||||
quality hash function.
|
quality hash function.
|
||||||
* Improved the algorithm for hashing floating point numbers.
|
* 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`.
|
Cygwin doesn't have decent floating point functions for `long double`.
|
||||||
* Never uses `fpclass` which doesn't support `long double`.
|
* Never uses `fpclass` which doesn't support `long double`.
|
||||||
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
|
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
|
||||||
@@ -69,11 +71,11 @@
|
|||||||
|
|
||||||
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
|
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
|
||||||
will be removed in a future version of Boost.
|
will be removed in a future version of Boost.
|
||||||
* Moved detail headers out of `boost/functional/detail`, since they are part of
|
* Moved detail headers out of `boost/container_hash/detail`, since they are part of
|
||||||
functional/hash, not functional. `boost/functional/detail/container_fwd.hpp`
|
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
|
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`.
|
this library, the others have been moved to `boost/functional/hash/detail`.
|
||||||
|
|
||||||
[h2 Boost 1.39.0]
|
[h2 Boost 1.39.0]
|
||||||
|
|
||||||
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
|
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
|
||||||
@@ -90,4 +92,131 @@
|
|||||||
instead of trying to configure every possibility manually.
|
instead of trying to configure every possibility manually.
|
||||||
* Workaround for when STLport doesn't support long double.
|
* Workaround for when STLport doesn't support long double.
|
||||||
|
|
||||||
|
[h2 Boost 1.42.0]
|
||||||
|
|
||||||
|
* Reduce the number of warnings for Visual C++ warning level 4.
|
||||||
|
* Some code formatting changes to fit lines into 80 characters.
|
||||||
|
* Rename an internal namespace.
|
||||||
|
|
||||||
|
[h2 Boost 1.43.0]
|
||||||
|
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
|
||||||
|
Don't foward declare containers when using gcc's parallel library,
|
||||||
|
allow user to stop forward declaration by defining the
|
||||||
|
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
|
||||||
|
Avoid hashing 0.5 and 0 to the same number.
|
||||||
|
* Stop using deprecated `BOOST_HAS_*` macros.
|
||||||
|
|
||||||
|
[h2 Boost 1.44.0]
|
||||||
|
|
||||||
|
* Add option to prevent implicit conversions when calling `hash_value` by
|
||||||
|
defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
|
||||||
|
for a type that does not have `hash_value` declared but does have
|
||||||
|
an implicit conversion to a type that does, it would use that
|
||||||
|
implicit conversion to hash it. Which can sometimes go very wrong,
|
||||||
|
e.g. using a conversion to bool and only hashing to 2 possible
|
||||||
|
values. Since fixing this is a breaking change and was only
|
||||||
|
approached quite late in the release cycle with little discussion
|
||||||
|
it's opt-in for now. This, or something like it, will become the
|
||||||
|
default in a future version.
|
||||||
|
|
||||||
|
[h2 Boost 1.46.0]
|
||||||
|
|
||||||
|
* Avoid warning due with gcc's `-Wconversion` flag.
|
||||||
|
|
||||||
|
[h2 Boost 1.50.0]
|
||||||
|
|
||||||
|
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
|
||||||
|
Avoid gcc's `-Wfloat-equal` warning.
|
||||||
|
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
|
||||||
|
Support `std::array` and `std::tuple` when available.
|
||||||
|
* Add deprecation warning to the long deprecated
|
||||||
|
`boost/container_hash/detail/container_fwd.hpp`.
|
||||||
|
|
||||||
|
[h2 Boost 1.51.0]
|
||||||
|
|
||||||
|
* Support the standard smart pointers.
|
||||||
|
* `hash_value` now implemented using SFINAE to avoid implicit casts to built
|
||||||
|
in types when calling it.
|
||||||
|
* Updated to use the new config macros.
|
||||||
|
|
||||||
|
[h2 Boost 1.52.0]
|
||||||
|
|
||||||
|
* Restore `enum` support, which was accidentally removed in the last version.
|
||||||
|
* New floating point hasher - will hash the binary representation on more
|
||||||
|
platforms, which should be faster.
|
||||||
|
|
||||||
|
[h2 Boost 1.53.0]
|
||||||
|
|
||||||
|
* Add support for `boost::int128_type` and `boost::uint128_type` where
|
||||||
|
available - currently only `__int128` and `unsigned __int128` on some
|
||||||
|
versions of gcc.
|
||||||
|
* On platforms that are known to have the standard floating point functions,
|
||||||
|
don't use automatic detection - which can break if there are ambiguous
|
||||||
|
overloads.
|
||||||
|
* Fix undefined behaviour when using the binary float hash (Thomas Heller).
|
||||||
|
|
||||||
|
[h2 Boost 1.54.0]
|
||||||
|
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]:
|
||||||
|
Fixed a typo.
|
||||||
|
|
||||||
|
[h2 Boost 1.55.0]
|
||||||
|
|
||||||
|
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9
|
||||||
|
([ticket 8822]).
|
||||||
|
* Suppress Visual C++ infinite loop warning ([ticket 8568]).
|
||||||
|
|
||||||
|
[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]
|
[endsect]
|
||||||
|
|||||||
+1
-1
@@ -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`.
|
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
|
||||||
When this macro is defined, only the specialisations detailed
|
When this macro is defined, only the specialisations detailed
|
||||||
in TR1 will be declared. But, if you later undefine the macro and include
|
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.
|
- activating the extensions.
|
||||||
|
|
||||||
It is strongly recommended that you never undefine the macro - and only define
|
It is strongly recommended that you never undefine the macro - and only define
|
||||||
|
|||||||
+8
-3
@@ -1,12 +1,12 @@
|
|||||||
[library Boost.Functional/Hash
|
[library Boost.ContainerHash
|
||||||
[quickbook 1.4]
|
[quickbook 1.5]
|
||||||
[authors [James, Daniel]]
|
[authors [James, Daniel]]
|
||||||
[copyright 2005 2006 2007 2008 Daniel James]
|
[copyright 2005 2006 2007 2008 Daniel James]
|
||||||
[purpose A TR1 hash function object that can be extended to hash user
|
[purpose A TR1 hash function object that can be extended to hash user
|
||||||
defined types]
|
defined types]
|
||||||
[category higher-order]
|
[category higher-order]
|
||||||
[id hash]
|
[id hash]
|
||||||
[dirname functional/hash]
|
[dirname container_hash]
|
||||||
[license
|
[license
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
Distributed under the Boost Software License, Version 1.0.
|
||||||
(See accompanying file LICENSE_1_0.txt or copy at
|
(See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -14,11 +14,16 @@
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[def __issues__
|
||||||
|
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
|
||||||
|
Library Extension Technical Report Issues List]]
|
||||||
|
|
||||||
[include:hash intro.qbk]
|
[include:hash intro.qbk]
|
||||||
[include:hash tutorial.qbk]
|
[include:hash tutorial.qbk]
|
||||||
[include:hash portability.qbk]
|
[include:hash portability.qbk]
|
||||||
[include:hash disable.qbk]
|
[include:hash disable.qbk]
|
||||||
[include:hash changes.qbk]
|
[include:hash changes.qbk]
|
||||||
|
[include:hash rationale.qbk]
|
||||||
[xinclude ref.xml]
|
[xinclude ref.xml]
|
||||||
[include:hash links.qbk]
|
[include:hash links.qbk]
|
||||||
[include:hash thanks.qbk]
|
[include:hash thanks.qbk]
|
||||||
|
|||||||
+7
-3
@@ -18,9 +18,6 @@
|
|||||||
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
||||||
Boost.MultiIndex]]
|
Boost.MultiIndex]]
|
||||||
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
|
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
|
||||||
[def __issues__
|
|
||||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
|
|
||||||
Library Extension Technical Report Issues List]]
|
|
||||||
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
|
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
|
||||||
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
|
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
|
||||||
|
|
||||||
@@ -44,5 +41,12 @@ __issues__ (page 63), this adds support for:
|
|||||||
* the standard containers.
|
* the standard containers.
|
||||||
* extending [classref boost::hash] for custom types.
|
* extending [classref boost::hash] for custom types.
|
||||||
|
|
||||||
|
[note
|
||||||
|
This hash function is designed to be used in containers based on
|
||||||
|
the STL and is not suitable as a general purpose hash function.
|
||||||
|
For more details see the [link hash.rationale rationale].
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
|||||||
+1
-13
@@ -88,18 +88,6 @@ boost namespace:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Full code for this example is at
|
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].
|
||||||
|
|
||||||
[h2 Other Issues]
|
|
||||||
|
|
||||||
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
|
|
||||||
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
|
|
||||||
support built in arrays so this shouldn't be a problem in most cases.
|
|
||||||
|
|
||||||
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
|
|
||||||
|
|
||||||
When using GCC on Solaris, `boost::hash_value(long double)` treats
|
|
||||||
`long double`s as `double`s - so the hash function doesn't take into account the
|
|
||||||
full range of values.
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
[/ Copyright 2011 Daniel James.
|
||||||
|
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
|
||||||
|
|
||||||
|
[section:rationale Rationale]
|
||||||
|
|
||||||
|
The rationale can be found in the original design
|
||||||
|
[footnote issue 6.18 of the __issues__ (page 63)].
|
||||||
|
|
||||||
|
[heading Quality of the hash function]
|
||||||
|
|
||||||
|
Many hash functions strive to have little correlation between the input
|
||||||
|
and output values. They attempt to uniformally distribute the output
|
||||||
|
values for very similar inputs. This hash function makes no such
|
||||||
|
attempt. In fact, for integers, the result of the hash function is often
|
||||||
|
just the input value. So similar but different input values will often
|
||||||
|
result in similar but different output values.
|
||||||
|
This means that it is not appropriate as a general hash function. For
|
||||||
|
example, a hash table may discard bits from the hash function resulting
|
||||||
|
in likely collisions, or might have poor collision resolution when hash
|
||||||
|
values are clustered together. In such cases this hash function will
|
||||||
|
preform poorly.
|
||||||
|
|
||||||
|
But the standard has no such requirement for the hash function,
|
||||||
|
it just requires that the hashes of two different values are unlikely
|
||||||
|
to collide. Containers or algorithms
|
||||||
|
designed to work with the standard hash function will have to be
|
||||||
|
implemented to work well when the hash function's output is correlated
|
||||||
|
to its input. Since they are paying that cost a higher quality hash function
|
||||||
|
would be wasteful.
|
||||||
|
|
||||||
|
For other use cases, if you do need a higher quality hash function,
|
||||||
|
then neither the standard hash function or `boost::hash` are appropriate.
|
||||||
|
There are several options
|
||||||
|
available. One is to use a second hash on the output of this hash
|
||||||
|
function, such as [@http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm
|
||||||
|
Thomas Wang's hash function]. This this may not work as
|
||||||
|
well as a hash algorithm tailored for the input.
|
||||||
|
|
||||||
|
For strings there are several fast, high quality hash functions
|
||||||
|
available (for example [@http://code.google.com/p/smhasher/ MurmurHash3]
|
||||||
|
and [@http://code.google.com/p/cityhash/ Google's CityHash]),
|
||||||
|
although they tend to be more machine specific.
|
||||||
|
These may also be appropriate for hashing a binary representation of
|
||||||
|
your data - providing that all equal values have an equal
|
||||||
|
representation, which is not always the case (e.g. for floating point
|
||||||
|
values).
|
||||||
|
|
||||||
|
[endsect]
|
||||||
+191
-7
@@ -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).
|
<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>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
<header name="boost/functional/hash.hpp">
|
<header name="boost/container_hash/hash.hpp">
|
||||||
<para>
|
<para>
|
||||||
Defines <code><classname>boost::hash</classname></code>,
|
Defines <code><classname>boost::hash</classname></code>,
|
||||||
and helper functions.
|
and helper functions.
|
||||||
@@ -55,6 +55,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|||||||
is defined. The specializations are still defined, so only the specializations
|
is defined. The specializations are still defined, so only the specializations
|
||||||
required by TR1 are defined.
|
required by TR1 are defined.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
Forward declared in
|
||||||
|
<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>
|
</notes>
|
||||||
<throws><para>
|
<throws><para>
|
||||||
Only throws if
|
Only throws if
|
||||||
@@ -153,6 +162,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|||||||
</method>
|
</method>
|
||||||
</struct-specialization>
|
</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">
|
<struct-specialization name="hash">
|
||||||
<template></template>
|
<template></template>
|
||||||
<specialization>
|
<specialization>
|
||||||
@@ -387,6 +432,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|||||||
</method>
|
</method>
|
||||||
</struct-specialization>
|
</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">
|
<struct-specialization name="hash">
|
||||||
<template>
|
<template>
|
||||||
<template-type-parameter name="T"/>
|
<template-type-parameter name="T"/>
|
||||||
@@ -406,6 +487,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|||||||
</method>
|
</method>
|
||||||
</struct-specialization>
|
</struct-specialization>
|
||||||
|
|
||||||
|
<struct-specialization name="hash">
|
||||||
|
<template></template>
|
||||||
|
<specialization>
|
||||||
|
<template-arg>std::type_index</template-arg>
|
||||||
|
</specialization>
|
||||||
|
<method name="operator()" cv="const">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val">
|
||||||
|
<paramtype>std::type_index</paramtype>
|
||||||
|
</parameter>
|
||||||
|
<returns>
|
||||||
|
<para><code>val.hash_code()</code></para>
|
||||||
|
</returns>
|
||||||
|
<throws><para>Doesn't throw</para></throws>
|
||||||
|
</method>
|
||||||
|
<notes>
|
||||||
|
<para>
|
||||||
|
Only available if it's in your standard library and Boost.Config
|
||||||
|
is aware of it.
|
||||||
|
</para>
|
||||||
|
</notes>
|
||||||
|
</struct-specialization>
|
||||||
|
|
||||||
<free-function-group name="Support functions (Boost extension).">
|
<free-function-group name="Support functions (Boost extension).">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -423,11 +527,28 @@ 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
|
Called repeatedly to incrementally create a hash value from
|
||||||
several variables.
|
several variables.
|
||||||
</simpara></purpose>
|
</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>
|
<notes>
|
||||||
<para><functionname>hash_value</functionname> is called without
|
<para><functionname>hash_value</functionname> is called without
|
||||||
qualification, so that overloads can be found via ADL.</para>
|
qualification, so that overloads can be found via ADL.</para>
|
||||||
<para>This is an extension to TR1</para>
|
<para>This is an extension to TR1</para>
|
||||||
|
<para>
|
||||||
|
Forward declared in
|
||||||
|
<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>
|
</notes>
|
||||||
<throws>
|
<throws>
|
||||||
Only throws if <functionname>hash_value</functionname>(T) throws.
|
Only throws if <functionname>hash_value</functionname>(T) throws.
|
||||||
@@ -476,15 +597,14 @@ for(; first != last; ++first)
|
|||||||
|
|
||||||
return seed;
|
return seed;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>For the three arguments overload:
|
</para>
|
||||||
|
<para>For the three arguments overload:</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
for(; first != last; ++first)
|
for(; first != last; ++first)
|
||||||
{
|
{
|
||||||
<functionname>hash_combine</functionname>(seed, *first);
|
<functionname>hash_combine</functionname>(seed, *first);
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
<para>
|
|
||||||
</para>
|
|
||||||
</effects>
|
</effects>
|
||||||
<notes>
|
<notes>
|
||||||
<para>
|
<para>
|
||||||
@@ -493,6 +613,15 @@ for(; first != last; ++first)
|
|||||||
container.
|
container.
|
||||||
</para>
|
</para>
|
||||||
<para>This is an extension to TR1</para>
|
<para>This is an extension to TR1</para>
|
||||||
|
<para>
|
||||||
|
Forward declared in
|
||||||
|
<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>
|
</notes>
|
||||||
<throws><para>
|
<throws><para>
|
||||||
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
|
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits<It>::value_type)</code>
|
||||||
@@ -540,6 +669,16 @@ for(; first != last; ++first)
|
|||||||
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
|
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
|
||||||
</signature>
|
</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>
|
<signature>
|
||||||
<type>std::size_t</type>
|
<type>std::size_t</type>
|
||||||
<parameter name="val"><paramtype>short</paramtype></parameter>
|
<parameter name="val"><paramtype>short</paramtype></parameter>
|
||||||
@@ -716,6 +855,30 @@ for(; first != last; ++first)
|
|||||||
<parameter name="val"><paramtype>std::complex<T> const&</paramtype></parameter>
|
<parameter name="val"><paramtype>std::complex<T> const&</paramtype></parameter>
|
||||||
</signature>
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::type_index</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T"/>
|
||||||
|
<template-nontype-parameter name="N">
|
||||||
|
<type>std::size_t</type>
|
||||||
|
</template-nontype-parameter>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::array<T, N> const&</paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
|
<signature>
|
||||||
|
<template>
|
||||||
|
<template-type-parameter name="T" pack="1"/>
|
||||||
|
</template>
|
||||||
|
<type>std::size_t</type>
|
||||||
|
<parameter name="val"><paramtype>std::tuple<T...></paramtype></parameter>
|
||||||
|
</signature>
|
||||||
|
|
||||||
<description><para>
|
<description><para>
|
||||||
Generally shouldn't be called directly by users, instead they should use
|
Generally shouldn't be called directly by users, instead they should use
|
||||||
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
|
||||||
@@ -726,6 +889,11 @@ for(; first != last; ++first)
|
|||||||
|
|
||||||
<notes>
|
<notes>
|
||||||
<para>This is an extension to TR1</para>
|
<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>
|
</notes>
|
||||||
|
|
||||||
<throws>
|
<throws>
|
||||||
@@ -747,7 +915,8 @@ for(; first != last; ++first)
|
|||||||
<tbody>
|
<tbody>
|
||||||
<row>
|
<row>
|
||||||
<entry><code>bool</code>,
|
<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>short</code>, <code>unsigned short</code>,
|
||||||
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
|
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
|
||||||
</entry>
|
</entry>
|
||||||
@@ -781,7 +950,8 @@ for(; first != last; ++first)
|
|||||||
<code>std::set<K, C, A></code>,
|
<code>std::set<K, C, A></code>,
|
||||||
<code>std::multiset<K, C, A></code>,
|
<code>std::multiset<K, C, A></code>,
|
||||||
<code>std::map<K, T, C, A></code>,
|
<code>std::map<K, T, C, A></code>,
|
||||||
<code>std::multimap<K, T, C, A></code>
|
<code>std::multimap<K, T, C, A></code>,
|
||||||
|
<code>std::array<T, N></code>
|
||||||
</entry>
|
</entry>
|
||||||
<entry><code>hash_range(val.begin(), val.end())</code></entry>
|
<entry><code>hash_range(val.begin(), val.end())</code></entry>
|
||||||
</row>
|
</row>
|
||||||
@@ -790,6 +960,14 @@ for(; first != last; ++first)
|
|||||||
<entry><programlisting>size_t seed = 0;
|
<entry><programlisting>size_t seed = 0;
|
||||||
<functionname>hash_combine</functionname>(seed, val.first);
|
<functionname>hash_combine</functionname>(seed, val.first);
|
||||||
<functionname>hash_combine</functionname>(seed, val.second);
|
<functionname>hash_combine</functionname>(seed, val.second);
|
||||||
|
return seed;</programlisting></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry><code>std::tuple<T...></code></entry>
|
||||||
|
<entry><programlisting>size_t seed = 0;
|
||||||
|
<functionname>hash_combine</functionname>(seed, get<0>(val));
|
||||||
|
<functionname>hash_combine</functionname>(seed, get<1>(val));
|
||||||
|
// ....
|
||||||
return seed;</programlisting></entry>
|
return seed;</programlisting></entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
@@ -798,6 +976,12 @@ return seed;</programlisting></entry>
|
|||||||
</entry>
|
</entry>
|
||||||
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
|
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<code>std::type_index</code>
|
||||||
|
</entry>
|
||||||
|
<entry><code>val.hash_code()</code></entry>
|
||||||
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</informaltable>
|
</informaltable>
|
||||||
|
|||||||
@@ -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]));
|
||||||
|
}
|
||||||
+19
-14
@@ -3,6 +3,9 @@
|
|||||||
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
|
/ 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) ]
|
/ 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
|
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
|
||||||
Boost.MultiIndex]]
|
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:
|
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()
|
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
|
For an example of generic use, here is a function to generate a vector
|
||||||
containing the hashes of the elements of a container:
|
containing the hashes of the elements of a container:
|
||||||
|
|
||||||
template <class Container>
|
[get_hashes]
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
@@ -110,9 +105,9 @@ And you can now use [classref boost::hash] with book:
|
|||||||
assert(books.find(dandelion) == books.end());
|
assert(books.find(dandelion) == books.end());
|
||||||
|
|
||||||
The full example can be found in:
|
The full example can be found in:
|
||||||
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp]
|
[@boost:/libs/container_hash/examples/books.hpp /libs/container_hash/examples/books.hpp]
|
||||||
and
|
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
|
[tip
|
||||||
When writing a hash function, first look at how the equality function works.
|
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.
|
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
|
||||||
|
|
||||||
Full code for this example is at
|
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
|
[note
|
||||||
When using [funcref boost::hash_combine] the order of the
|
When using [funcref boost::hash_combine] the order of the
|
||||||
@@ -198,5 +193,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
|
|||||||
std::vector<std::string> some_strings;
|
std::vector<std::string> some_strings;
|
||||||
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
|
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
|
||||||
|
|
||||||
[endsect]
|
Note that when writing template classes, you might not want to include the main
|
||||||
|
hash header as it's quite an expensive include that brings in a lot of other
|
||||||
|
headers, so instead you can include the `<boost/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/container_hash/examples/template.hpp template.hpp] and
|
||||||
|
[@boost:/libs/container_hash/examples/template.cpp template.cpp].
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright Troy D. Straszheim
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# See http://www.boost.org/LICENSE_1_0.txt
|
|
||||||
#
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
#-- Needed include directories for the tests
|
|
||||||
boost_additional_test_dependencies(config BOOST_DEPENDS test)
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
boost_test_run(books)
|
|
||||||
boost_test_run(point)
|
|
||||||
boost_test_run(portable)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,3 +6,4 @@
|
|||||||
run books.cpp ;
|
run books.cpp ;
|
||||||
run point.cpp ;
|
run point.cpp ;
|
||||||
run portable.cpp ;
|
run portable.cpp ;
|
||||||
|
run template.cpp ;
|
||||||
|
|||||||
+2
-1
@@ -4,7 +4,7 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include "./books.hpp"
|
#include "./books.hpp"
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
// If std::unordered_set was available:
|
// If std::unordered_set was available:
|
||||||
@@ -20,6 +20,7 @@ int main()
|
|||||||
|
|
||||||
boost::hash<library::book> book_hasher;
|
boost::hash<library::book> book_hasher;
|
||||||
std::size_t knife_hash_value = book_hasher(knife);
|
std::size_t knife_hash_value = book_hasher(knife);
|
||||||
|
(void)knife_hash_value; // suppress unused variable warning
|
||||||
|
|
||||||
// If std::unordered_set was available:
|
// If std::unordered_set was available:
|
||||||
//
|
//
|
||||||
|
|||||||
+6
-1
@@ -3,7 +3,12 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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>
|
#include <cassert>
|
||||||
|
|
||||||
// This example illustrates how to use boost::hash_combine to generate a hash
|
// 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
|
// 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)
|
// 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>
|
#include <cassert>
|
||||||
|
|
||||||
// This example illustrates how to customise boost::hash portably, so that
|
// This example illustrates how to customise boost::hash portably, so that
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "template.hpp"
|
||||||
|
#include <cassert>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
typedef my_pair<int, float> pair;
|
||||||
|
boost::unordered_set<pair> pair_set;
|
||||||
|
pair_set.emplace(10, 0.5f);
|
||||||
|
|
||||||
|
assert(pair_set.find(pair(10, 0.5f)) != pair_set.end());
|
||||||
|
assert(pair_set.find(pair(10, 0.6f)) == pair_set.end());
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// This is an example of how to write a hash function for a template
|
||||||
|
// class.
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash_fwd.hpp>
|
||||||
|
|
||||||
|
template <typename A, typename B>
|
||||||
|
class my_pair
|
||||||
|
{
|
||||||
|
A value1;
|
||||||
|
B value2;
|
||||||
|
public:
|
||||||
|
my_pair(A const& v1, B const& v2)
|
||||||
|
: value1(v1), value2(v2)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator==(my_pair const& other) const
|
||||||
|
{
|
||||||
|
return value1 == other.value1 &&
|
||||||
|
value2 == other.value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::size_t hash_value(my_pair const& p)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, p.value1);
|
||||||
|
boost::hash_combine(seed, p.value2);
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
+95
-5
@@ -7,12 +7,100 @@
|
|||||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
|
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/config/no_tr1/cmath.hpp>
|
#include <boost/config/no_tr1/cmath.hpp>
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
|
||||||
# pragma once
|
// sufficiently good floating point support to not require any
|
||||||
|
// workarounds.
|
||||||
|
//
|
||||||
|
// When set to 0, the library tries to automatically
|
||||||
|
// use the best available implementation. This normally works well, but
|
||||||
|
// breaks when ambiguities are created by odd namespacing of the functions.
|
||||||
|
//
|
||||||
|
// Note that if this is set to 0, the library should still take full
|
||||||
|
// advantage of the platform's floating point support.
|
||||||
|
|
||||||
|
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif defined(__LIBCOMO__)
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
|
||||||
|
// Rogue Wave library:
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif defined(_LIBCPP_VERSION)
|
||||||
|
// libc++
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||||
|
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||||
|
// GNU libstdc++ 3
|
||||||
|
# if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||||
|
# else
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
# endif
|
||||||
|
#elif defined(__STL_CONFIG_H)
|
||||||
|
// generic SGI STL
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif defined(__MSL_CPP__)
|
||||||
|
// MSL standard lib:
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif defined(__IBMCPP__)
|
||||||
|
// VACPP std lib (probably conformant for much earlier version).
|
||||||
|
# if __IBMCPP__ >= 1210
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||||
|
# else
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
# endif
|
||||||
|
#elif defined(MSIPL_COMPILE_H)
|
||||||
|
// Modena C++ standard library
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
|
||||||
|
// Dinkumware Library (this has to appear after any possible replacement libraries):
|
||||||
|
# if _CPPLIB_VER >= 405
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 1
|
||||||
|
# else
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define BOOST_HASH_CONFORMANT_FLOATS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_HASH_CONFORMANT_FLOATS
|
||||||
|
|
||||||
|
// The standard library is known to be compliant, so don't use the
|
||||||
|
// configuration mechanism.
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace hash_detail {
|
||||||
|
template <typename Float>
|
||||||
|
struct call_ldexp {
|
||||||
|
typedef Float float_type;
|
||||||
|
inline Float operator()(Float x, int y) const {
|
||||||
|
return std::ldexp(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
struct call_frexp {
|
||||||
|
typedef Float float_type;
|
||||||
|
inline Float operator()(Float x, int* y) const {
|
||||||
|
return std::frexp(x, y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
struct select_hash_type
|
||||||
|
{
|
||||||
|
typedef Float type;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
|
||||||
|
|
||||||
// The C++ standard requires that the C float functions are overloarded
|
// The C++ standard requires that the C float functions are overloarded
|
||||||
// for float, double and long double in the std namespace, but some of the older
|
// for float, double and long double in the std namespace, but some of the older
|
||||||
// library implementations don't support this. On some that don't, the C99
|
// library implementations don't support this. On some that don't, the C99
|
||||||
@@ -84,7 +172,7 @@ namespace boost {
|
|||||||
// the boost namespace they'll always be preferable to any other function
|
// the boost namespace they'll always be preferable to any other function
|
||||||
// (since the arguments are built in types, ADL can't be used).
|
// (since the arguments are built in types, ADL can't be used).
|
||||||
|
|
||||||
namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
|
namespace boost_hash_detect_float_functions {
|
||||||
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
|
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
|
||||||
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
|
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
|
||||||
}
|
}
|
||||||
@@ -103,7 +191,7 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
|
|||||||
// happen mainly when there's a template in the same namesapce.
|
// happen mainly when there's a template in the same namesapce.
|
||||||
|
|
||||||
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
|
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
|
||||||
namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \
|
namespace boost_hash_detect_float_functions { \
|
||||||
template <class Float> \
|
template <class Float> \
|
||||||
boost::hash_detail::not_found c99_func(Float, type2); \
|
boost::hash_detail::not_found c99_func(Float, type2); \
|
||||||
} \
|
} \
|
||||||
@@ -112,7 +200,7 @@ namespace boost { \
|
|||||||
namespace hash_detail { \
|
namespace hash_detail { \
|
||||||
namespace c99_func##_detect { \
|
namespace c99_func##_detect { \
|
||||||
using namespace std; \
|
using namespace std; \
|
||||||
using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \
|
using namespace boost_hash_detect_float_functions; \
|
||||||
\
|
\
|
||||||
struct check { \
|
struct check { \
|
||||||
static type1 x; \
|
static type1 x; \
|
||||||
@@ -243,4 +331,6 @@ namespace boost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_HASH_CONFORMANT_FLOATS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,271 @@
|
|||||||
|
|
||||||
|
// Copyright 2005-2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
|
||||||
|
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/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>
|
||||||
|
#include <boost/limits.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(push)
|
||||||
|
#if BOOST_MSVC >= 1400
|
||||||
|
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
|
||||||
|
// not satisfy test. Loop body not executed
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Can we use fpclassify?
|
||||||
|
|
||||||
|
// STLport
|
||||||
|
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||||
|
#define BOOST_HASH_USE_FPCLASSIFY 0
|
||||||
|
|
||||||
|
// GNU libstdc++ 3
|
||||||
|
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
||||||
|
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
|
||||||
|
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
|
||||||
|
# define BOOST_HASH_USE_FPCLASSIFY 1
|
||||||
|
# else
|
||||||
|
# define BOOST_HASH_USE_FPCLASSIFY 0
|
||||||
|
# endif
|
||||||
|
|
||||||
|
// Everything else
|
||||||
|
#else
|
||||||
|
# define BOOST_HASH_USE_FPCLASSIFY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
||||||
|
{
|
||||||
|
seed ^= value + (seed<<6) + (seed>>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Binary hash function
|
||||||
|
//
|
||||||
|
// Only used for floats with known iec559 floats, and certain values in
|
||||||
|
// numeric_limits
|
||||||
|
|
||||||
|
inline std::size_t hash_binary(char* ptr, std::size_t length)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
|
||||||
|
if (length >= sizeof(std::size_t)) {
|
||||||
|
std::memcpy(&seed, ptr, sizeof(std::size_t));
|
||||||
|
length -= sizeof(std::size_t);
|
||||||
|
ptr += sizeof(std::size_t);
|
||||||
|
|
||||||
|
while(length >= sizeof(std::size_t)) {
|
||||||
|
std::size_t buffer = 0;
|
||||||
|
std::memcpy(&buffer, ptr, sizeof(std::size_t));
|
||||||
|
hash_float_combine(seed, buffer);
|
||||||
|
length -= sizeof(std::size_t);
|
||||||
|
ptr += sizeof(std::size_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
std::size_t buffer = 0;
|
||||||
|
std::memcpy(&buffer, ptr, length);
|
||||||
|
hash_float_combine(seed, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float, unsigned digits, unsigned max_exponent>
|
||||||
|
struct enable_binary_hash
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value =
|
||||||
|
std::numeric_limits<Float>::is_iec559 &&
|
||||||
|
std::numeric_limits<Float>::digits == digits &&
|
||||||
|
std::numeric_limits<Float>::radix == 2 &&
|
||||||
|
std::numeric_limits<Float>::max_exponent == max_exponent);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
inline std::size_t float_hash_impl(Float v,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||||
|
enable_binary_hash<Float, 24, 128>::value,
|
||||||
|
std::size_t>::type)
|
||||||
|
{
|
||||||
|
return hash_binary((char*) &v, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
inline std::size_t float_hash_impl(Float v,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||||
|
enable_binary_hash<Float, 53, 1024>::value,
|
||||||
|
std::size_t>::type)
|
||||||
|
{
|
||||||
|
return hash_binary((char*) &v, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
inline std::size_t float_hash_impl(Float v,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||||
|
enable_binary_hash<Float, 64, 16384>::value,
|
||||||
|
std::size_t>::type)
|
||||||
|
{
|
||||||
|
return hash_binary((char*) &v, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Float>
|
||||||
|
inline std::size_t float_hash_impl(Float v,
|
||||||
|
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
|
||||||
|
enable_binary_hash<Float, 113, 16384>::value,
|
||||||
|
std::size_t>::type)
|
||||||
|
{
|
||||||
|
return hash_binary((char*) &v, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Portable hash function
|
||||||
|
//
|
||||||
|
// Used as a fallback when the binary hash function isn't supported.
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t float_hash_impl2(T v)
|
||||||
|
{
|
||||||
|
boost::hash_detail::call_frexp<T> frexp;
|
||||||
|
boost::hash_detail::call_ldexp<T> ldexp;
|
||||||
|
|
||||||
|
int exp = 0;
|
||||||
|
|
||||||
|
v = frexp(v, &exp);
|
||||||
|
|
||||||
|
// A postive value is easier to hash, so combine the
|
||||||
|
// sign with the exponent and use the absolute value.
|
||||||
|
if(v < 0) {
|
||||||
|
v = -v;
|
||||||
|
exp += limits<T>::max_exponent -
|
||||||
|
limits<T>::min_exponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
v = ldexp(v, limits<std::size_t>::digits);
|
||||||
|
std::size_t seed = static_cast<std::size_t>(v);
|
||||||
|
v -= static_cast<T>(seed);
|
||||||
|
|
||||||
|
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
|
||||||
|
std::size_t const length
|
||||||
|
= (limits<T>::digits *
|
||||||
|
boost::static_log2<limits<T>::radix>::value
|
||||||
|
+ limits<std::size_t>::digits - 1)
|
||||||
|
/ limits<std::size_t>::digits;
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i != length; ++i)
|
||||||
|
{
|
||||||
|
v = ldexp(v, limits<std::size_t>::digits);
|
||||||
|
std::size_t part = static_cast<std::size_t>(v);
|
||||||
|
v -= static_cast<T>(part);
|
||||||
|
hash_float_combine(seed, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_float_combine(seed, static_cast<std::size_t>(exp));
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t float_hash_impl(T v, ...)
|
||||||
|
{
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
|
||||||
|
return float_hash_impl2(static_cast<type>(v));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
|
||||||
|
#include <boost/config/no_tr1/cmath.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t float_hash_value(T v)
|
||||||
|
{
|
||||||
|
#if defined(fpclassify)
|
||||||
|
switch (fpclassify(v))
|
||||||
|
#elif BOOST_HASH_CONFORMANT_FLOATS
|
||||||
|
switch (std::fpclassify(v))
|
||||||
|
#else
|
||||||
|
using namespace std;
|
||||||
|
switch (fpclassify(v))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
case FP_ZERO:
|
||||||
|
return 0;
|
||||||
|
case FP_INFINITE:
|
||||||
|
return (std::size_t)(v > 0 ? -1 : -2);
|
||||||
|
case FP_NAN:
|
||||||
|
return (std::size_t)(-3);
|
||||||
|
case FP_NORMAL:
|
||||||
|
case FP_SUBNORMAL:
|
||||||
|
return float_hash_impl(v, 0);
|
||||||
|
default:
|
||||||
|
BOOST_ASSERT(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace hash_detail
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
inline bool is_zero(T v)
|
||||||
|
{
|
||||||
|
#if !defined(__GNUC__) && !defined(__clang__)
|
||||||
|
return v == 0;
|
||||||
|
#else
|
||||||
|
// GCC's '-Wfloat-equal' will complain about comparing
|
||||||
|
// v to 0, but because it disables warnings for system
|
||||||
|
// headers it won't complain if you use std::equal_to to
|
||||||
|
// compare with 0. Resulting in this silliness:
|
||||||
|
return std::equal_to<T>()(v, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline std::size_t float_hash_value(T v)
|
||||||
|
{
|
||||||
|
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
|
||||||
|
#undef BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
+3
-2
@@ -9,8 +9,9 @@
|
|||||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
|
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
|
||||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
|
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
#include <boost/config.hpp>
|
||||||
# pragma once
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
@@ -0,0 +1,363 @@
|
|||||||
|
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||||
|
# include <array>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||||
|
# include <tuple>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
|
||||||
|
# include <memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||||
|
#include <boost/type_traits/is_array.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template <class A, class B>
|
||||||
|
std::size_t hash_value(std::pair<A, B> const&);
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::vector<T, A> const&);
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::list<T, A> const& v);
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::deque<T, A> const& v);
|
||||||
|
template <class K, class C, class A>
|
||||||
|
std::size_t hash_value(std::set<K, C, A> const& v);
|
||||||
|
template <class K, class C, class A>
|
||||||
|
std::size_t hash_value(std::multiset<K, C, A> const& v);
|
||||||
|
template <class K, class T, class C, class A>
|
||||||
|
std::size_t hash_value(std::map<K, T, C, A> const& v);
|
||||||
|
template <class K, class T, class C, class A>
|
||||||
|
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(std::complex<T> const&);
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
std::size_t hash_value(std::pair<A, B> const& v)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_combine(seed, v.first);
|
||||||
|
boost::hash_combine(seed, v.second);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::vector<T, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::list<T, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A>
|
||||||
|
std::size_t hash_value(std::deque<T, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class C, class A>
|
||||||
|
std::size_t hash_value(std::set<K, C, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class C, class A>
|
||||||
|
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class T, class C, class A>
|
||||||
|
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class T, class C, class A>
|
||||||
|
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::size_t hash_value(std::complex<T> const& v)
|
||||||
|
{
|
||||||
|
boost::hash<T> hasher;
|
||||||
|
std::size_t seed = hasher(v.imag());
|
||||||
|
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||||
|
template <class T, std::size_t N>
|
||||||
|
std::size_t hash_value(std::array<T, N> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_range(v.begin(), v.end());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||||
|
namespace hash_detail {
|
||||||
|
template <std::size_t I, typename T>
|
||||||
|
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
|
||||||
|
void>::type
|
||||||
|
hash_combine_tuple(std::size_t&, T const&)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t I, typename T>
|
||||||
|
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
|
||||||
|
void>::type
|
||||||
|
hash_combine_tuple(std::size_t& seed, T const& v)
|
||||||
|
{
|
||||||
|
boost::hash_combine(seed, std::get<I>(v));
|
||||||
|
boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline std::size_t hash_tuple(T const& v)
|
||||||
|
{
|
||||||
|
std::size_t seed = 0;
|
||||||
|
boost::hash_detail::hash_combine_tuple<0>(seed, v);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template <typename... T>
|
||||||
|
inline std::size_t hash_value(std::tuple<T...> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_detail::hash_tuple(v);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
inline std::size_t hash_value(std::tuple<> const& v)
|
||||||
|
{
|
||||||
|
return boost::hash_detail::hash_tuple(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
@@ -0,0 +1,762 @@
|
|||||||
|
|
||||||
|
// 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 <iterator>
|
||||||
|
#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(BOOST_NO_CXX98_FUNCTION_BASE)
|
||||||
|
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<typename std::iterator_traits<It>::value_type>(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<typename std::iterator_traits<It>::value_type>(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
|
||||||
@@ -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
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
// Copyright 2005-2008 Daniel James.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
// Forwarding header for container_fwd.hpp's new location.
|
|
||||||
// This header is deprecated, I'll be adding a warning in a future release,
|
|
||||||
// then converting it to an error and finally removing this header completely.
|
|
||||||
|
|
||||||
#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
|
|
||||||
#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||||
# pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/detail/container_fwd.hpp>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -3,5 +3,4 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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,101 +0,0 @@
|
|||||||
|
|
||||||
// Copyright 2005-2009 Daniel James.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
|
|
||||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||||
# pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
|
||||||
#include <boost/functional/hash/detail/limits.hpp>
|
|
||||||
#include <boost/integer/static_log2.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
// Include hash implementation for the current platform.
|
|
||||||
|
|
||||||
// Cygwn
|
|
||||||
#if defined(__CYGWIN__)
|
|
||||||
# if defined(__i386__) || defined(_M_IX86)
|
|
||||||
# include <boost/functional/hash/detail/hash_float_x86.hpp>
|
|
||||||
# else
|
|
||||||
# include <boost/functional/hash/detail/hash_float_generic.hpp>
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# include <boost/functional/hash/detail/hash_float_generic.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Can we use fpclassify?
|
|
||||||
|
|
||||||
// STLport
|
|
||||||
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
|
||||||
#define BOOST_HASH_USE_FPCLASSIFY 0
|
|
||||||
|
|
||||||
// GNU libstdc++ 3
|
|
||||||
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
|
|
||||||
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
|
|
||||||
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
|
|
||||||
# define BOOST_HASH_USE_FPCLASSIFY 1
|
|
||||||
# else
|
|
||||||
# define BOOST_HASH_USE_FPCLASSIFY 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
// Everything else
|
|
||||||
#else
|
|
||||||
# define BOOST_HASH_USE_FPCLASSIFY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if BOOST_HASH_USE_FPCLASSIFY
|
|
||||||
|
|
||||||
#include <boost/config/no_tr1/cmath.hpp>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
inline std::size_t float_hash_value(T v)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
switch (fpclassify(v)) {
|
|
||||||
case FP_ZERO:
|
|
||||||
return 0;
|
|
||||||
case FP_INFINITE:
|
|
||||||
return (std::size_t)(v > 0 ? -1 : -2);
|
|
||||||
case FP_NAN:
|
|
||||||
return (std::size_t)(-3);
|
|
||||||
case FP_NORMAL:
|
|
||||||
case FP_SUBNORMAL:
|
|
||||||
return float_hash_impl(v);
|
|
||||||
default:
|
|
||||||
BOOST_ASSERT(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // !BOOST_HASH_USE_FPCLASSIFY
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
template <class T>
|
|
||||||
inline std::size_t float_hash_value(T v)
|
|
||||||
{
|
|
||||||
return v == 0 ? 0 : float_hash_impl(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BOOST_HASH_USE_FPCLASSIFY
|
|
||||||
|
|
||||||
#undef BOOST_HASH_USE_FPCLASSIFY
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// A general purpose hash function for non-zero floating point values.
|
|
||||||
|
|
||||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
|
|
||||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
|
|
||||||
|
|
||||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
|
||||||
#include <boost/integer/static_log2.hpp>
|
|
||||||
#include <boost/functional/hash/detail/limits.hpp>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||||
# pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
#pragma warning(push)
|
|
||||||
#if BOOST_MSVC >= 1400
|
|
||||||
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
|
|
||||||
// not satisfy test. Loop body not executed
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
|
||||||
{
|
|
||||||
seed ^= value + (seed<<6) + (seed>>2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline std::size_t float_hash_impl2(T v)
|
|
||||||
{
|
|
||||||
boost::hash_detail::call_frexp<T> frexp;
|
|
||||||
boost::hash_detail::call_ldexp<T> ldexp;
|
|
||||||
|
|
||||||
int exp = 0;
|
|
||||||
|
|
||||||
v = frexp(v, &exp);
|
|
||||||
|
|
||||||
// A postive value is easier to hash, so combine the
|
|
||||||
// sign with the exponent and use the absolute value.
|
|
||||||
if(v < 0) {
|
|
||||||
v = -v;
|
|
||||||
exp += limits<T>::max_exponent -
|
|
||||||
limits<T>::min_exponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The result of frexp is always between 0.5 and 1, so its
|
|
||||||
// top bit will always be 1. Subtract by 0.5 to remove that.
|
|
||||||
v -= T(0.5);
|
|
||||||
v = ldexp(v, limits<std::size_t>::digits + 1);
|
|
||||||
std::size_t seed = static_cast<std::size_t>(v);
|
|
||||||
v -= seed;
|
|
||||||
|
|
||||||
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
|
|
||||||
std::size_t const length
|
|
||||||
= (limits<T>::digits *
|
|
||||||
boost::static_log2<limits<T>::radix>::value - 1)
|
|
||||||
/ limits<std::size_t>::digits;
|
|
||||||
|
|
||||||
for(std::size_t i = 0; i != length; ++i)
|
|
||||||
{
|
|
||||||
v = ldexp(v, limits<std::size_t>::digits);
|
|
||||||
std::size_t part = static_cast<std::size_t>(v);
|
|
||||||
v -= part;
|
|
||||||
hash_float_combine(seed, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_float_combine(seed, exp);
|
|
||||||
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline std::size_t float_hash_impl(T v)
|
|
||||||
{
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
|
|
||||||
return float_hash_impl2(static_cast<type>(v));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// A non-portable hash function form non-zero floats on x86.
|
|
||||||
//
|
|
||||||
// Even if you're on an x86 platform, this might not work if their floating
|
|
||||||
// point isn't set up as this expects. So this should only be used if it's
|
|
||||||
// absolutely certain that it will work.
|
|
||||||
|
|
||||||
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER)
|
|
||||||
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER
|
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||||
# pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace hash_detail
|
|
||||||
{
|
|
||||||
inline void hash_float_combine(std::size_t& seed, std::size_t value)
|
|
||||||
{
|
|
||||||
seed ^= value + (seed<<6) + (seed>>2);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t float_hash_impl(float v)
|
|
||||||
{
|
|
||||||
boost::uint32_t* ptr = (boost::uint32_t*)&v;
|
|
||||||
std::size_t seed = *ptr;
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t float_hash_impl(double v)
|
|
||||||
{
|
|
||||||
boost::uint32_t* ptr = (boost::uint32_t*)&v;
|
|
||||||
std::size_t seed = *ptr++;
|
|
||||||
hash_float_combine(seed, *ptr);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t float_hash_impl(long double v)
|
|
||||||
{
|
|
||||||
boost::uint32_t* ptr = (boost::uint32_t*)&v;
|
|
||||||
std::size_t seed = *ptr++;
|
|
||||||
hash_float_combine(seed, *ptr++);
|
|
||||||
hash_float_combine(seed, *(boost::uint16_t*)ptr);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,286 +1,6 @@
|
|||||||
|
|
||||||
// Copyright 2005-2009 Daniel James.
|
// Copyright 2017 Daniel James.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// Based on Peter Dimov's proposal
|
#include <boost/container_hash/extensions.hpp>
|
||||||
// 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>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
hash_combine(seed, v.first);
|
|
||||||
hash_combine(seed, v.second);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class A>
|
|
||||||
std::size_t hash_value(std::vector<T, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class A>
|
|
||||||
std::size_t hash_value(std::list<T, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class A>
|
|
||||||
std::size_t hash_value(std::deque<T, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K, class C, class A>
|
|
||||||
std::size_t hash_value(std::set<K, C, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K, class C, class A>
|
|
||||||
std::size_t hash_value(std::multiset<K, C, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K, class T, class C, class A>
|
|
||||||
std::size_t hash_value(std::map<K, T, C, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class K, class T, class C, class A>
|
|
||||||
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
|
|
||||||
{
|
|
||||||
return hash_range(v.begin(), v.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
|
|||||||
@@ -3,476 +3,4 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// Based on Peter Dimov's proposal
|
#include <boost/container_hash/hash.hpp>
|
||||||
// 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>
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
#include <boost/type_traits/is_pointer.hpp>
|
|
||||||
#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
|
|
||||||
{
|
|
||||||
std::size_t hash_value(bool);
|
|
||||||
std::size_t hash_value(char);
|
|
||||||
std::size_t hash_value(unsigned char);
|
|
||||||
std::size_t hash_value(signed char);
|
|
||||||
std::size_t hash_value(short);
|
|
||||||
std::size_t hash_value(unsigned short);
|
|
||||||
std::size_t hash_value(int);
|
|
||||||
std::size_t hash_value(unsigned int);
|
|
||||||
std::size_t hash_value(long);
|
|
||||||
std::size_t hash_value(unsigned long);
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
|
||||||
std::size_t hash_value(wchar_t);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_HAS_LONG_LONG)
|
|
||||||
std::size_t hash_value(boost::long_long_type);
|
|
||||||
std::size_t hash_value(boost::ulong_long_type);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
std::size_t hash_value(float v);
|
|
||||||
std::size_t hash_value(double v);
|
|
||||||
std::size_t hash_value(long double v);
|
|
||||||
|
|
||||||
template <class Ch, class A>
|
|
||||||
std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(bool v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(char v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(unsigned char v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(signed char v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(short v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(unsigned short v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(int v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(unsigned int v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(long v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(unsigned long v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
|
||||||
inline std::size_t hash_value(wchar_t v)
|
|
||||||
{
|
|
||||||
return static_cast<std::size_t>(v);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_HAS_LONG_LONG)
|
|
||||||
inline std::size_t hash_value(boost::long_long_type v)
|
|
||||||
{
|
|
||||||
return hash_detail::hash_value_signed(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(boost::ulong_long_type v)
|
|
||||||
{
|
|
||||||
return hash_detail::hash_value_unsigned(v);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
std::size_t x = static_cast<std::size_t>(
|
|
||||||
reinterpret_cast<std::ptrdiff_t>(v));
|
|
||||||
|
|
||||||
return x + (x >> 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(float v)
|
|
||||||
{
|
|
||||||
return boost::hash_detail::float_hash_value(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(double v)
|
|
||||||
{
|
|
||||||
return boost::hash_detail::float_hash_value(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t hash_value(long double v)
|
|
||||||
{
|
|
||||||
return boost::hash_detail::float_hash_value(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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_HAS_LONG_LONG)
|
|
||||||
BOOST_HASH_SPECIALIZE(boost::long_long_type)
|
|
||||||
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
|
|
||||||
#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
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|||||||
@@ -3,38 +3,4 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// Based on Peter Dimov's proposal
|
#include <boost/container_hash/hash_fwd.hpp>
|
||||||
// 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
|
|
||||||
|
|||||||
@@ -3,5 +3,4 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright Troy D. Straszheim
|
|
||||||
#
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# See http://www.boost.org/LICENSE_1_0.txt
|
|
||||||
#
|
|
||||||
#project hash-tests
|
|
||||||
# : requirements
|
|
||||||
# <toolset>gcc:<define>_GLIBCXX_DEBUG
|
|
||||||
# ;
|
|
||||||
if (GCC)
|
|
||||||
ADD_DEFINITIONS(-D_GLIBCXX_DEBUG)
|
|
||||||
endif(GCC)
|
|
||||||
|
|
||||||
# [ run .cpp : : : <test-info>always_show_run_output ]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
#-- Needed include directories for the tests
|
|
||||||
boost_additional_test_dependencies(functional BOOST_DEPENDS test)
|
|
||||||
#-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
SET(tests
|
|
||||||
hash_fwd_test_1
|
|
||||||
hash_fwd_test_2
|
|
||||||
hash_number_test
|
|
||||||
hash_pointer_test
|
|
||||||
hash_function_pointer_test
|
|
||||||
hash_float_test
|
|
||||||
hash_long_double_test
|
|
||||||
hash_string_test
|
|
||||||
hash_range_test
|
|
||||||
hash_custom_test
|
|
||||||
hash_global_namespace_test
|
|
||||||
hash_friend_test
|
|
||||||
hash_built_in_array_test
|
|
||||||
hash_value_array_test
|
|
||||||
hash_vector_test
|
|
||||||
hash_list_test
|
|
||||||
hash_deque_test
|
|
||||||
hash_set_test
|
|
||||||
hash_map_test
|
|
||||||
hash_complex_test
|
|
||||||
container_fwd_test
|
|
||||||
hash_no_ext_macro_1
|
|
||||||
hash_no_ext_macro_2
|
|
||||||
)
|
|
||||||
|
|
||||||
boost_test_run(link_test link_test.cpp link_test_2.cpp)
|
|
||||||
boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp
|
|
||||||
)
|
|
||||||
foreach(test ${tests})
|
|
||||||
boost_test_run(${test})
|
|
||||||
endforeach(test ${tests})
|
|
||||||
|
|
||||||
boost_test_compile_fail(hash_no_ext_fail_test)
|
|
||||||
|
|
||||||
+38
-9
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# Copyright 2005-2008 Daniel James.
|
# Copyright 2005-2012 Daniel James.
|
||||||
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
# 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)
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@@ -7,20 +7,29 @@ import testing ;
|
|||||||
|
|
||||||
project hash-tests
|
project hash-tests
|
||||||
: requirements
|
: requirements
|
||||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
<warnings>all
|
||||||
<toolset>gcc:<cxxflags>-Wsign-promo
|
<toolset>intel:<warnings>on
|
||||||
#<toolset>gcc:<cxxflags>-Wextra
|
#<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_1.cpp ]
|
||||||
[ run hash_fwd_test_2.cpp ]
|
[ run hash_fwd_test_2.cpp ]
|
||||||
[ run hash_number_test.cpp ]
|
[ run hash_number_test.cpp ]
|
||||||
|
[ run hash_enum_test.cpp ]
|
||||||
[ run hash_pointer_test.cpp ]
|
[ run hash_pointer_test.cpp ]
|
||||||
[ run hash_function_pointer_test.cpp ]
|
[ run hash_function_pointer_test.cpp ]
|
||||||
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
|
[ run hash_float_test.cpp ]
|
||||||
[ run hash_long_double_test.cpp : : : <test-info>always_show_run_output ]
|
[ run hash_long_double_test.cpp ]
|
||||||
[ run hash_string_test.cpp ]
|
[ run hash_string_test.cpp ]
|
||||||
[ run hash_range_test.cpp ]
|
[ run hash_range_test.cpp ]
|
||||||
[ run hash_custom_test.cpp ]
|
[ run hash_custom_test.cpp ]
|
||||||
@@ -34,17 +43,24 @@ test-suite functional/hash
|
|||||||
[ run hash_set_test.cpp ]
|
[ run hash_set_test.cpp ]
|
||||||
[ run hash_map_test.cpp ]
|
[ run hash_map_test.cpp ]
|
||||||
[ run hash_complex_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 ]
|
||||||
[ run link_test.cpp link_test_2.cpp ]
|
[ run link_test.cpp link_test_2.cpp ]
|
||||||
[ run link_ext_test.cpp link_no_ext_test.cpp ]
|
[ run link_ext_test.cpp link_no_ext_test.cpp ]
|
||||||
[ run extensions_hpp_test.cpp ]
|
[ run extensions_hpp_test.cpp ]
|
||||||
[ run container_fwd_test.cpp ]
|
|
||||||
[ compile-fail hash_no_ext_fail_test.cpp ]
|
[ compile-fail hash_no_ext_fail_test.cpp ]
|
||||||
[ compile-fail namespace_fail_test.cpp ]
|
[ compile-fail namespace_fail_test.cpp ]
|
||||||
|
[ run implicit_test.cpp ]
|
||||||
[ run hash_no_ext_macro_1.cpp ]
|
[ run hash_no_ext_macro_1.cpp ]
|
||||||
[ run hash_no_ext_macro_2.cpp ]
|
[ 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_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
|
||||||
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
|
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
|
||||||
@@ -55,4 +71,17 @@ test-suite functional/hash_no_ext
|
|||||||
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
|
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
# Tests to see if the floating point hash is using the binary hash.
|
||||||
|
# Not run normally because on some platforms these should fail.
|
||||||
|
test-suite container_hash/hash_no_generic_float
|
||||||
|
:
|
||||||
|
[ run hash_float_test.cpp
|
||||||
|
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||||
|
: hash_float_test_no_generic ]
|
||||||
|
[ run hash_long_double_test.cpp
|
||||||
|
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
|
||||||
|
: hash_long_double_test_no_generic ]
|
||||||
|
;
|
||||||
|
explicit container_hash/hash_no_generic_float ;
|
||||||
|
|
||||||
build-project ../examples ;
|
build-project ../examples ;
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
template <class T1>
|
||||||
|
struct check_return_type
|
||||||
|
{
|
||||||
|
template <class T2>
|
||||||
|
static void equals(T2)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T2>
|
||||||
|
static void equals_ref(T2&)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T2>
|
||||||
|
static void convertible(T2)
|
||||||
|
{
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
float f = 0;
|
||||||
|
double d = 0;
|
||||||
|
long double l = 0;
|
||||||
|
|
||||||
|
test::check_return_type<float>::equals(std::ldexp(f, 0));
|
||||||
|
test::check_return_type<double>::equals(std::ldexp(d, 0));
|
||||||
|
test::check_return_type<long double>::equals(std::ldexp(l, 0));
|
||||||
|
|
||||||
|
int dummy = 0;
|
||||||
|
|
||||||
|
test::check_return_type<float>::equals(std::frexp(f, &dummy));
|
||||||
|
test::check_return_type<double>::equals(std::frexp(d, &dummy));
|
||||||
|
test::check_return_type<long double>::equals(std::frexp(l, &dummy));
|
||||||
|
|
||||||
|
#if BOOST_HASH_USE_FPCLASSIFY
|
||||||
|
|
||||||
|
int (*fpc1)(float) = std::fpclassify;
|
||||||
|
int (*fpc2)(double) = std::fpclassify;
|
||||||
|
int (*fpc3)(long double) = std::fpclassify;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -5,12 +5,16 @@
|
|||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/static_assert.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>
|
template <class T>
|
||||||
void compile_time_tests(T*)
|
void compile_time_tests(T*)
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
|
BOOST_STATIC_ASSERT((boost::is_same<T,
|
||||||
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-5
@@ -3,12 +3,23 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#if defined(TEST_STD)
|
#if defined(BOOST_HASH_TEST_STD)
|
||||||
# define TEST_STD_INCLUDES
|
# define BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# define HASH_NAMESPACE std
|
# define BOOST_HASH_TEST_NAMESPACE std
|
||||||
#else
|
#else
|
||||||
# define HASH_NAMESPACE boost
|
# define BOOST_HASH_TEST_NAMESPACE boost
|
||||||
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||||
# define TEST_EXTENSIONS
|
# define BOOST_HASH_TEST_EXTENSIONS
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32_WCE)
|
||||||
|
// The standard windows mobile headers trigger this warning so I disable it
|
||||||
|
// before doing anything else.
|
||||||
|
#pragma warning(disable:4201) // nonstandard extension used :
|
||||||
|
// nameless struct/union
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HASH_TEST_CAT(x, y) HASH_TEST_CAT2(x, y)
|
||||||
|
#define HASH_TEST_CAT2(x, y) x##y
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
|
|
||||||
// Copyright 2005-2009 Daniel James.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
#include <boost/functional/detail/container_fwd.hpp>
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
|
|
||||||
template <class charT, class Allocator>
|
|
||||||
static void test(std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <class charT, class Allocator>
|
|
||||||
static void test(std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class T, class Allocator>
|
|
||||||
static void test(std::deque<T, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class Allocator>
|
|
||||||
static void test(std::list<T, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T, class Allocator>
|
|
||||||
static void test(std::vector<T, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Compare, class Allocator>
|
|
||||||
static void test(std::map<Key, T, Compare, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class T, class Compare, class Allocator>
|
|
||||||
static void test(std::multimap<Key, T, Compare, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Compare, class Allocator>
|
|
||||||
static void test(std::set<Key, Compare, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Key, class Compare, class Allocator>
|
|
||||||
static void test(std::multiset<Key, Compare, Allocator> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <std::size_t N>
|
|
||||||
static void test(std::bitset<N> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void test(std::complex<T> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class X, class Y>
|
|
||||||
static void test(std::pair<X, Y> const&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
#include <bitset>
|
|
||||||
#include <string>
|
|
||||||
#include <complex>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
std::deque<int> x1;
|
|
||||||
std::list<std::string> x2;
|
|
||||||
std::vector<float> x3;
|
|
||||||
std::vector<bool> x4;
|
|
||||||
std::map<int, int> x5;
|
|
||||||
std::multimap<float, int*> x6;
|
|
||||||
std::set<std::string> x7;
|
|
||||||
std::multiset<std::vector<int> > x8;
|
|
||||||
std::bitset<10> x9;
|
|
||||||
std::string x10;
|
|
||||||
std::complex<double> x11;
|
|
||||||
std::pair<std::list<int>, char***> x12;
|
|
||||||
|
|
||||||
test(x1);
|
|
||||||
test(x2);
|
|
||||||
test(x3);
|
|
||||||
test(x4);
|
|
||||||
test(x5);
|
|
||||||
test(x6);
|
|
||||||
test(x7);
|
|
||||||
test(x8);
|
|
||||||
test(x9);
|
|
||||||
test(x10);
|
|
||||||
test(x11);
|
|
||||||
test(x12);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -3,12 +3,14 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// 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.
|
// should work.
|
||||||
|
|
||||||
#include <boost/functional/hash/extensions.hpp>
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#include <boost/container_hash/extensions.hpp>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int x[2] = { 2, 3 };
|
int x[2] = { 2, 3 };
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
void array_int_test()
|
void array_int_test()
|
||||||
{
|
{
|
||||||
@@ -27,47 +27,47 @@ void array_int_test()
|
|||||||
8, -12, 23, 65, 45,
|
8, -12, 23, 65, 45,
|
||||||
-1, 93, -54, 987, 3
|
-1, 93, -54, 987, 3
|
||||||
};
|
};
|
||||||
HASH_NAMESPACE::hash<int[25]> hasher1;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
|
||||||
|
|
||||||
const int length2 = 1;
|
const int length2 = 1;
|
||||||
int array2[1] = {3};
|
int array2[1] = {3};
|
||||||
HASH_NAMESPACE::hash<int[1]> hasher2;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
|
||||||
|
|
||||||
const int length3 = 2;
|
const int length3 = 2;
|
||||||
int array3[2] = {2, 3};
|
int array3[2] = {2, 3};
|
||||||
HASH_NAMESPACE::hash<int[2]> hasher3;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
|
||||||
|
|
||||||
BOOST_TEST(hasher1(array1)
|
BOOST_TEST(hasher1(array1)
|
||||||
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
|
||||||
BOOST_TEST(hasher2(array2)
|
BOOST_TEST(hasher2(array2)
|
||||||
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
|
||||||
BOOST_TEST(hasher3(array3)
|
BOOST_TEST(hasher3(array3)
|
||||||
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void two_dimensional_array_test()
|
void two_dimensional_array_test()
|
||||||
{
|
{
|
||||||
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||||
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
|
||||||
|
|
||||||
std::size_t seed1 = 0;
|
std::size_t seed1 = 0;
|
||||||
for(int i = 0; i < 3; ++i)
|
for(int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
std::size_t seed2 = 0;
|
std::size_t seed2 = 0;
|
||||||
for(int j = 0; j < 2; ++j)
|
for(int j = 0; j < 2; ++j)
|
||||||
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
|
||||||
HASH_NAMESPACE::hash_combine(seed1, seed2);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TEST(hasher(array) == seed1);
|
BOOST_TEST(hasher(array) == seed1);
|
||||||
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
|
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
array_int_test();
|
array_int_test();
|
||||||
two_dimensional_array_test();
|
two_dimensional_array_test();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+36
-22
@@ -5,42 +5,52 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#if !defined(TEST_EXTENSIONS)
|
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable:4244) // conversion from 'unsigned long' to
|
||||||
|
// 'unsigned short', possible loss of data
|
||||||
|
#pragma warning(disable:4245) // conversion from 'int' to
|
||||||
|
// 'const unsigned short',
|
||||||
|
// signed/unsigned mismatch
|
||||||
|
#pragma warning(disable:4305) // truncation from 'double' to
|
||||||
|
// 'const std::complex<float>::_Ty'
|
||||||
|
#pragma warning(disable:4309) // truncation of constant value
|
||||||
|
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||||
|
#if BOOST_MSVC < 1400
|
||||||
|
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||||
|
// possible loss of data
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data
|
|
||||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void generic_complex_tests(std::complex<T> v)
|
void generic_complex_tests(std::complex<T> v)
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<std::complex<T> > complex_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
|
||||||
|
|
||||||
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
|
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> real_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
|
||||||
T real = v.real();
|
T real = v.real();
|
||||||
T imag = v.imag();
|
T imag = v.imag();
|
||||||
|
|
||||||
@@ -63,7 +73,7 @@ void complex_float_tests(Float*)
|
|||||||
generic_complex_tests(complex(0.5,0));
|
generic_complex_tests(complex(0.5,0));
|
||||||
generic_complex_tests(complex(25,0));
|
generic_complex_tests(complex(25,0));
|
||||||
generic_complex_tests(complex(25,0));
|
generic_complex_tests(complex(25,0));
|
||||||
generic_complex_tests(complex(-67.5324535,56.23578678));
|
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Integer>
|
template <class Integer>
|
||||||
@@ -74,23 +84,27 @@ void complex_integral_tests(Integer*)
|
|||||||
generic_complex_tests(complex(15342,124));
|
generic_complex_tests(complex(15342,124));
|
||||||
generic_complex_tests(complex(25,54356));
|
generic_complex_tests(complex(25,54356));
|
||||||
generic_complex_tests(complex(5325,2346));
|
generic_complex_tests(complex(5325,2346));
|
||||||
generic_complex_tests(complex(-243897,-49923874));
|
generic_complex_tests(complex(Integer(-243897),Integer(-49923874)));
|
||||||
generic_complex_tests(complex(-543,763));
|
generic_complex_tests(complex(Integer(-543),Integer(763)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
// I've comments out the short and unsigned short tests
|
||||||
|
// as they cause warnings and don't really test
|
||||||
|
// anything that the other tests already deal with.
|
||||||
|
|
||||||
complex_float_tests((float*) 0);
|
complex_float_tests((float*) 0);
|
||||||
complex_float_tests((double*) 0);
|
complex_float_tests((double*) 0);
|
||||||
complex_float_tests((long double*) 0);
|
complex_float_tests((long double*) 0);
|
||||||
complex_integral_tests((short*) 0);
|
//complex_integral_tests((short*) 0);
|
||||||
complex_integral_tests((int*) 0);
|
complex_integral_tests((int*) 0);
|
||||||
complex_integral_tests((long*) 0);
|
complex_integral_tests((long*) 0);
|
||||||
complex_integral_tests((unsigned short*) 0);
|
//complex_integral_tests((unsigned short*) 0);
|
||||||
complex_integral_tests((unsigned int*) 0);
|
complex_integral_tests((unsigned int*) 0);
|
||||||
complex_integral_tests((unsigned long*) 0);
|
complex_integral_tests((unsigned long*) 0);
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|||||||
+19
-18
@@ -3,6 +3,7 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ namespace test
|
|||||||
|
|
||||||
std::size_t hash() const
|
std::size_t hash() const
|
||||||
{
|
{
|
||||||
return value_ * 10;
|
return static_cast<std::size_t>(value_ * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
@@ -40,17 +41,17 @@ namespace boost
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -58,13 +59,13 @@ namespace boost
|
|||||||
|
|
||||||
void custom_tests()
|
void custom_tests()
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<test::custom> custom_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
|
||||||
BOOST_TEST(custom_hasher(10) == 100u);
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
test::custom x(55);
|
test::custom x(55);
|
||||||
BOOST_TEST(custom_hasher(x) == 550u);
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace HASH_NAMESPACE;
|
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,25 +75,25 @@ void custom_tests()
|
|||||||
custom_vector.push_back(35);
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
|
||||||
|
|
||||||
std::size_t seed2 = 0;
|
std::size_t seed2 = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||||
|
|
||||||
BOOST_TEST(seed ==
|
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
custom_vector.begin(), custom_vector.end()));
|
||||||
BOOST_TEST(seed == seed2);
|
BOOST_TEST(seed == seed2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
custom_tests();
|
custom_tests();
|
||||||
#endif
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ using std::deque;
|
|||||||
#define CONTAINER_TYPE deque
|
#define CONTAINER_TYPE deque
|
||||||
#include "./hash_sequence_test.hpp"
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
deque_tests::deque_hash_integer_tests();
|
deque_tests::deque_hash_integer_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
#else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
enum enum_override { enum_override1, enum_override2 };
|
||||||
|
std::size_t hash_value(enum_override) { return 896532; }
|
||||||
|
|
||||||
|
enum enum1 { enum1a };
|
||||||
|
enum enum2 { enum2a, enum2b };
|
||||||
|
enum enum3 { enum3a = 574, enum3b };
|
||||||
|
enum enum4 { enum4a = -12574, enum4b };
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
compile_time_tests((test::enum1*) 0);
|
||||||
|
compile_time_tests((test::enum2*) 0);
|
||||||
|
compile_time_tests((test::enum3*) 0);
|
||||||
|
compile_time_tests((test::enum4*) 0);
|
||||||
|
compile_time_tests((test::enum_override*) 0);
|
||||||
|
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<test::enum1> hash1;
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<test::enum2> hash2;
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<test::enum3> hash3;
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<test::enum4> hash4;
|
||||||
|
|
||||||
|
BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
|
||||||
|
|
||||||
|
BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
|
||||||
|
BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
|
||||||
|
BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
|
||||||
|
|
||||||
|
BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
|
||||||
|
BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
|
||||||
|
BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
|
||||||
|
|
||||||
|
BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
|
||||||
|
BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
|
||||||
|
BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
|
||||||
|
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<test::enum_override> hash_override;
|
||||||
|
|
||||||
|
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||||
|
hash_override(test::enum_override1));
|
||||||
|
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||||
|
hash_override(test::enum_override2));
|
||||||
|
BOOST_TEST(hash_override(test::enum_override1) ==
|
||||||
|
hash_override(test::enum_override1));
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
+128
-60
@@ -5,24 +5,33 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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 <cmath>
|
#include <cmath>
|
||||||
#include <boost/functional/hash/detail/limits.hpp>
|
#include <boost/container_hash/detail/limits.hpp>
|
||||||
#include <boost/functional/hash/detail/float_functions.hpp>
|
#include <boost/container_hash/detail/float_functions.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/config/workaround.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4127) // conditional expression is constant
|
#pragma warning(disable:4127) // conditional expression is constant
|
||||||
|
#pragma warning(disable:4723) // conditional expression is constant
|
||||||
|
#if BOOST_MSVC < 1400
|
||||||
|
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||||
|
// possible loss of data
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char const* float_type(float*) { return "float"; }
|
char const* float_type(float*) { return "float"; }
|
||||||
@@ -32,26 +41,36 @@ char const* float_type(long double*) { return "long double"; }
|
|||||||
template <class T>
|
template <class T>
|
||||||
void float_tests(char const* name, T* = 0)
|
void float_tests(char const* name, T* = 0)
|
||||||
{
|
{
|
||||||
std::cerr<<"\n"
|
std::cerr
|
||||||
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
|
<< "\n"
|
||||||
<<"\n"
|
<< "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
|
||||||
<<"boost::hash_detail::limits<T>::digits = "
|
<< name
|
||||||
<<boost::hash_detail::limits<T>::digits<<"\n"
|
<< ">\n"
|
||||||
<<"boost::hash_detail::limits<int>::digits = "
|
<< "\n"
|
||||||
<<boost::hash_detail::limits<int>::digits<<"\n"
|
<< "boost::hash_detail::limits<T>::digits = "
|
||||||
<<"boost::hash_detail::limits<std::size_t>::digits = "
|
<< boost::hash_detail::limits<T>::digits<< "\n"
|
||||||
<<boost::hash_detail::limits<std::size_t>::digits<<"\n"
|
<< "boost::hash_detail::limits<int>::digits = "
|
||||||
<<"\n"
|
<< boost::hash_detail::limits<int>::digits<< "\n"
|
||||||
<<"boost::hash_detail::call_ldexp<T>::float_type = "
|
<< "boost::hash_detail::limits<std::size_t>::digits = "
|
||||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_ldexp<T>::float_type*)0)<<"\n"
|
<< boost::hash_detail::limits<std::size_t>::digits
|
||||||
<<"boost::hash_detail::call_frexp<T>::float_type = "
|
<< "\n"
|
||||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n"
|
<< "\n"
|
||||||
<<"boost::hash_detail::select_hash_type<T>::type = "
|
<< "boost::hash_detail::call_ldexp<T>::float_type = "
|
||||||
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::select_hash_type<T>::type*)0)<<"\n"
|
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||||
<<"\n"
|
boost::hash_detail::call_ldexp<T>::float_type*>(0))
|
||||||
|
<< "\n"
|
||||||
|
<< "boost::hash_detail::call_frexp<T>::float_type = "
|
||||||
|
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||||
|
boost::hash_detail::call_frexp<T>::float_type*>(0))
|
||||||
|
<< "\n"
|
||||||
|
<< "boost::hash_detail::select_hash_type<T>::type = "
|
||||||
|
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
|
||||||
|
boost::hash_detail::select_hash_type<T>::type*>(0))
|
||||||
|
<< "\n"
|
||||||
|
<< "\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||||
|
|
||||||
T zero = 0;
|
T zero = 0;
|
||||||
T minus_zero = (T) -1 * zero;
|
T minus_zero = (T) -1 * zero;
|
||||||
@@ -59,16 +78,23 @@ void float_tests(char const* name, T* = 0)
|
|||||||
BOOST_TEST(zero == minus_zero);
|
BOOST_TEST(zero == minus_zero);
|
||||||
BOOST_TEST(x1(zero) == x1(minus_zero));
|
BOOST_TEST(x1(zero) == x1(minus_zero));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
|
BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
|
||||||
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
|
BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BOOST_TEST(x1(zero) != x1(0.5));
|
||||||
|
BOOST_TEST(x1(minus_zero) != x1(0.5));
|
||||||
|
BOOST_TEST(x1(0.5) != x1(-0.5));
|
||||||
|
BOOST_TEST(x1(1) != x1(-1));
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Doing anything with infinity causes borland to crash.
|
// Doing anything with infinity causes borland to crash.
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__)
|
||||||
std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n";
|
std::cerr
|
||||||
|
<< "Not running infinity checks on Borland, as it causes it to crash."
|
||||||
|
"\n";
|
||||||
#else
|
#else
|
||||||
if(boost::hash_detail::limits<T>::has_infinity) {
|
if(boost::hash_detail::limits<T>::has_infinity) {
|
||||||
T infinity = -log(zero);
|
T infinity = -log(zero);
|
||||||
@@ -80,10 +106,10 @@ void float_tests(char const* name, T* = 0)
|
|||||||
T minus_infinity2 = (T) -1. / zero;
|
T minus_infinity2 = (T) -1. / zero;
|
||||||
T minus_infinity3 = (T) 1. / minus_zero;
|
T minus_infinity3 = (T) 1. / minus_zero;
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
|
BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
|
||||||
BOOST_TEST(x1(minus_infinity)
|
BOOST_TEST(x1(minus_infinity)
|
||||||
== HASH_NAMESPACE::hash_value(minus_infinity));
|
== BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(infinity == infinity2)
|
if(infinity == infinity2)
|
||||||
@@ -107,19 +133,40 @@ void float_tests(char const* name, T* = 0)
|
|||||||
// This should really be 'has_denorm == denorm_present' but some
|
// This should really be 'has_denorm == denorm_present' but some
|
||||||
// compilers don't have 'denorm_present'. See also a later use.
|
// compilers don't have 'denorm_present'. See also a later use.
|
||||||
if(boost::hash_detail::limits<T>::has_denorm) {
|
if(boost::hash_detail::limits<T>::has_denorm) {
|
||||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity)) {
|
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
|
||||||
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
|
{
|
||||||
|
std::cerr
|
||||||
|
<< "x1(denorm_min) == x1(infinity) == "
|
||||||
|
<< x1(infinity)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(minus_infinity)) {
|
|
||||||
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
if(x1(boost::hash_detail::limits<T>::denorm_min()) ==
|
||||||
|
x1(minus_infinity))
|
||||||
|
{
|
||||||
|
std::cerr
|
||||||
|
<< "x1(denorm_min) == x1(-infinity) == "
|
||||||
|
<< x1(minus_infinity)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
||||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity)) {
|
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
|
||||||
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
|
{
|
||||||
|
std::cerr
|
||||||
|
<< "x1(quiet_NaN) == x1(infinity) == "
|
||||||
|
<< x1(infinity)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(minus_infinity)) {
|
|
||||||
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
|
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
|
||||||
|
x1(minus_infinity))
|
||||||
|
{
|
||||||
|
std::cerr
|
||||||
|
<< "x1(quiet_NaN) == x1(-infinity) == "
|
||||||
|
<< x1(minus_infinity)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,14 +185,22 @@ void float_tests(char const* name, T* = 0)
|
|||||||
BOOST_TEST(half_max != three_quarter_max);
|
BOOST_TEST(half_max != three_quarter_max);
|
||||||
BOOST_TEST(quarter_max != three_quarter_max);
|
BOOST_TEST(quarter_max != three_quarter_max);
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
BOOST_TEST(max != -max);
|
||||||
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
|
BOOST_TEST(half_max != -half_max);
|
||||||
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
|
BOOST_TEST(quarter_max != -quarter_max);
|
||||||
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
|
BOOST_TEST(three_quarter_max != -three_quarter_max);
|
||||||
BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
|
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
|
||||||
|
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
|
||||||
|
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
|
||||||
|
BOOST_TEST(x1(three_quarter_max) ==
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The '!=' tests could legitimately fail, but with my hash it indicates a bug.
|
// The '!=' tests could legitimately fail, but with my hash it indicates a
|
||||||
|
// bug.
|
||||||
BOOST_TEST(x1(max) == x1(max));
|
BOOST_TEST(x1(max) == x1(max));
|
||||||
BOOST_TEST(x1(max) != x1(quarter_max));
|
BOOST_TEST(x1(max) != x1(quarter_max));
|
||||||
BOOST_TEST(x1(max) != x1(half_max));
|
BOOST_TEST(x1(max) != x1(half_max));
|
||||||
@@ -157,6 +212,12 @@ void float_tests(char const* name, T* = 0)
|
|||||||
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
|
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
|
||||||
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
|
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
|
||||||
|
|
||||||
|
BOOST_TEST(x1(max) != x1(-max));
|
||||||
|
BOOST_TEST(x1(half_max) != x1(-half_max));
|
||||||
|
BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
|
||||||
|
BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
|
||||||
|
|
||||||
|
|
||||||
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
|
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
|
||||||
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
|
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
|
||||||
defined(__ICC) || defined(__ECC)) && \
|
defined(__ICC) || defined(__ECC)) && \
|
||||||
@@ -166,16 +227,17 @@ void float_tests(char const* name, T* = 0)
|
|||||||
if(v1 == v2)
|
if(v1 == v2)
|
||||||
BOOST_TEST(x1(v1) == x1(v2));
|
BOOST_TEST(x1(v1) == x1(v2));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
|
BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
|
||||||
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
|
BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
|
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
|
||||||
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::epsilon()));
|
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||||
|
boost::hash_detail::limits<T>::epsilon()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
|
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
|
||||||
@@ -207,31 +269,37 @@ void float_tests(char const* name, T* = 0)
|
|||||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
|
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
|
||||||
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
|
||||||
}
|
}
|
||||||
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(TEST_EXTENSIONS)
|
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
|
||||||
// specialization of boost::hash_detail::limits::denorm_min() for long
|
// specialization of boost::hash_detail::limits::denorm_min() for long
|
||||||
// doubles which causes this test to fail.
|
// doubles which causes this test to fail.
|
||||||
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
|
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
|
||||||
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::denorm_min()))
|
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||||
|
boost::hash_detail::limits<T>::denorm_min()))
|
||||||
{
|
{
|
||||||
std::cerr<<"x1(boost::hash_detail::limits<T>::denorm_min()) = "
|
std::cerr
|
||||||
<< x1(boost::hash_detail::limits<T>::denorm_min())
|
<< "x1(boost::hash_detail::limits<T>::denorm_min()) = "
|
||||||
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min()) = "
|
<< x1(boost::hash_detail::limits<T>::denorm_min())
|
||||||
<< HASH_NAMESPACE::hash_value(
|
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
|
||||||
|
" = "
|
||||||
|
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||||
boost::hash_detail::limits<T>::denorm_min())
|
boost::hash_detail::limits<T>::denorm_min())
|
||||||
<< "\nx1(0) = "<<x1(0)<<"\n";
|
<< "\nx1(0) = "
|
||||||
|
<< x1(0)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// NaN also causes borland to crash.
|
// NaN also causes borland to crash.
|
||||||
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS)
|
#if !defined(__BORLANDC__) && defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
|
||||||
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
|
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
|
||||||
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
|
||||||
}
|
}
|
||||||
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
|
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
|
||||||
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::quiet_NaN()));
|
BOOST_HASH_TEST_NAMESPACE::hash_value(
|
||||||
|
boost::hash_detail::limits<T>::quiet_NaN()));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-18
@@ -3,6 +3,8 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ namespace test
|
|||||||
|
|
||||||
std::size_t hash() const
|
std::size_t hash() const
|
||||||
{
|
{
|
||||||
return value_ * 10;
|
return static_cast<std::size_t>(value_ * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
@@ -42,17 +44,17 @@ namespace boost
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -60,13 +62,13 @@ namespace boost
|
|||||||
|
|
||||||
void custom_tests()
|
void custom_tests()
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
|
||||||
BOOST_TEST(custom_hasher(10) == 100u);
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
test::custom<int> x(55);
|
test::custom<int> x(55);
|
||||||
BOOST_TEST(custom_hasher(x) == 550u);
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace HASH_NAMESPACE;
|
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,25 +78,25 @@ void custom_tests()
|
|||||||
custom_vector.push_back(35);
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
|
||||||
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
|
||||||
|
|
||||||
std::size_t seed2 = 0;
|
std::size_t seed2 = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||||
|
|
||||||
BOOST_TEST(seed ==
|
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
custom_vector.begin(), custom_vector.end()));
|
||||||
BOOST_TEST(seed == seed2);
|
BOOST_TEST(seed == seed2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
custom_tests();
|
custom_tests();
|
||||||
#endif
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
|
|||||||
@@ -5,17 +5,13 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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 <boost/mpl/assert.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
|
|
||||||
#include "./compile_time.hpp"
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
void void_func1() { static int x = 1; ++x; }
|
void void_func1() { static int x = 1; ++x; }
|
||||||
@@ -28,8 +24,8 @@ void function_pointer_tests()
|
|||||||
compile_time_tests((void(**)()) 0);
|
compile_time_tests((void(**)()) 0);
|
||||||
compile_time_tests((int(**)(int)) 0);
|
compile_time_tests((int(**)(int)) 0);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<void(*)()> hasher_void;
|
BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
|
||||||
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
|
BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
|
||||||
|
|
||||||
BOOST_TEST(&void_func1 != &void_func2);
|
BOOST_TEST(&void_func1 != &void_func2);
|
||||||
BOOST_TEST(&int_func1 != &int_func2);
|
BOOST_TEST(&int_func1 != &int_func2);
|
||||||
@@ -42,11 +38,11 @@ void function_pointer_tests()
|
|||||||
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
|
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
|
||||||
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
|
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
|
||||||
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
|
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(hasher_void(&void_func1)
|
BOOST_TEST(hasher_void(&void_func1)
|
||||||
== HASH_NAMESPACE::hash_value(&void_func1));
|
== BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
|
||||||
BOOST_TEST(hasher_int(&int_func1)
|
BOOST_TEST(hasher_int(&int_func1)
|
||||||
== HASH_NAMESPACE::hash_value(&int_func1));
|
== BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
|
||||||
|
|
||||||
// This isn't specified in Peter's proposal:
|
// This isn't specified in Peter's proposal:
|
||||||
BOOST_TEST(hasher_void(0) == 0);
|
BOOST_TEST(hasher_void(0) == 0);
|
||||||
|
|||||||
+14
-12
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||||
#include <boost/functional/hash_fwd.hpp>
|
#include <boost/container_hash/hash_fwd.hpp>
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -25,7 +25,7 @@ namespace test {
|
|||||||
template <class T>
|
template <class T>
|
||||||
std::size_t hash_value(test_type1<T> const& x)
|
std::size_t hash_value(test_type1<T> const& x)
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<T> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||||
return hasher(x.value);
|
return hasher(x.value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -42,8 +42,8 @@ namespace test {
|
|||||||
std::size_t hash_value(test_type2<T> const& x)
|
std::size_t hash_value(test_type2<T> const& x)
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
|
||||||
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -60,8 +60,9 @@ namespace test {
|
|||||||
template <class T>
|
template <class T>
|
||||||
std::size_t hash_value(test_type3<T> const& x)
|
std::size_t hash_value(test_type3<T> const& x)
|
||||||
{
|
{
|
||||||
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
std::size_t seed =
|
||||||
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -75,7 +76,7 @@ namespace boost
|
|||||||
template <class T>
|
template <class T>
|
||||||
std::size_t hash_value(test::test_type1<T> const& x)
|
std::size_t hash_value(test::test_type1<T> const& x)
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<T> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||||
return hasher(x.value);
|
return hasher(x.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,16 +84,17 @@ namespace boost
|
|||||||
std::size_t hash_value(test::test_type2<T> const& x)
|
std::size_t hash_value(test::test_type2<T> const& x)
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed, x.value1);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
|
||||||
HASH_NAMESPACE::hash_combine(seed, x.value2);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::size_t hash_value(test::test_type3<T> const& x)
|
std::size_t hash_value(test::test_type3<T> const& x)
|
||||||
{
|
{
|
||||||
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
std::size_t seed =
|
||||||
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
|
||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-21
@@ -5,13 +5,15 @@
|
|||||||
|
|
||||||
// This checks that template code implemented using hash_fwd will work.
|
// This checks that template code implemented using hash_fwd will work.
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
#include "./hash_fwd_test.hpp"
|
#include "./hash_fwd_test.hpp"
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
void fwd_test1()
|
void fwd_test1()
|
||||||
@@ -19,10 +21,10 @@ void fwd_test1()
|
|||||||
test::test_type1<int> x(5);
|
test::test_type1<int> x(5);
|
||||||
test::test_type1<std::string> y("Test");
|
test::test_type1<std::string> y("Test");
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<int> hasher_int;
|
BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
|
||||||
HASH_NAMESPACE::hash<std::string> hasher_string;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
|
||||||
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
|
||||||
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
|
||||||
|
|
||||||
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
|
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
|
||||||
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
|
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
|
||||||
@@ -34,15 +36,15 @@ void fwd_test2()
|
|||||||
test::test_type2<std::string> y("Test1", "Test2");
|
test::test_type2<std::string> y("Test1", "Test2");
|
||||||
|
|
||||||
std::size_t seed1 = 0;
|
std::size_t seed1 = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed1, 5);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
|
||||||
HASH_NAMESPACE::hash_combine(seed1, 10);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
|
||||||
|
|
||||||
std::size_t seed2 = 0;
|
std::size_t seed2 = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
|
||||||
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
|
||||||
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
|
||||||
|
|
||||||
BOOST_TEST(seed1 == hasher_test_int(x));
|
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||||
BOOST_TEST(seed2 == hasher_test_string(y));
|
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||||
@@ -66,14 +68,16 @@ void fwd_test3()
|
|||||||
test::test_type3<int> x(values1.begin(), values1.end());
|
test::test_type3<int> x(values1.begin(), values1.end());
|
||||||
test::test_type3<std::string> y(values2.begin(), values2.end());
|
test::test_type3<std::string> y(values2.begin(), values2.end());
|
||||||
|
|
||||||
std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
|
std::size_t seed1 =
|
||||||
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
|
||||||
|
|
||||||
std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
|
std::size_t seed2 =
|
||||||
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
|
||||||
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
|
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
|
||||||
|
|
||||||
BOOST_TEST(seed1 == hasher_test_int(x));
|
BOOST_TEST(seed1 == hasher_test_int(x));
|
||||||
BOOST_TEST(seed2 == hasher_test_string(y));
|
BOOST_TEST(seed2 == hasher_test_string(y));
|
||||||
@@ -83,11 +87,10 @@ void fwd_test3()
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
fwd_test1();
|
fwd_test1();
|
||||||
fwd_test2();
|
fwd_test2();
|
||||||
fwd_test3();
|
fwd_test3();
|
||||||
#endif
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,16 @@
|
|||||||
// This test just makes sure a header which uses hash_fwd can compile without
|
// This test just makes sure a header which uses hash_fwd can compile without
|
||||||
// the main hash headers.
|
// the main hash headers.
|
||||||
|
|
||||||
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "./hash_fwd_test.hpp"
|
#include "./hash_fwd_test.hpp"
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
template <class T> void unused(T const&) {}
|
template <class T> void unused(T const&) {}
|
||||||
|
|
||||||
@@ -42,4 +44,4 @@ int main()
|
|||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
|
#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
|
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
|
||||||
// in the global namespace.
|
// in the global namespace.
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ struct custom
|
|||||||
|
|
||||||
std::size_t hash() const
|
std::size_t hash() const
|
||||||
{
|
{
|
||||||
return value_ * 10;
|
return static_cast<std::size_t>(value_ * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||||
@@ -40,17 +42,17 @@ namespace boost
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -58,13 +60,13 @@ namespace boost
|
|||||||
|
|
||||||
void custom_tests()
|
void custom_tests()
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<custom> custom_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
|
||||||
BOOST_TEST(custom_hasher(10) == 100u);
|
BOOST_TEST(custom_hasher(10) == 100u);
|
||||||
custom x(55);
|
custom x(55);
|
||||||
BOOST_TEST(custom_hasher(x) == 550u);
|
BOOST_TEST(custom_hasher(x) == 550u);
|
||||||
|
|
||||||
{
|
{
|
||||||
using namespace HASH_NAMESPACE;
|
using namespace BOOST_HASH_TEST_NAMESPACE;
|
||||||
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
BOOST_TEST(custom_hasher(x) == hash_value(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,26 +76,26 @@ void custom_tests()
|
|||||||
custom_vector.push_back(35);
|
custom_vector.push_back(35);
|
||||||
|
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed, custom(5));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
|
||||||
HASH_NAMESPACE::hash_combine(seed, custom(25));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
|
||||||
HASH_NAMESPACE::hash_combine(seed, custom(35));
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
|
||||||
|
|
||||||
std::size_t seed2 = 0;
|
std::size_t seed2 = 0;
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 50u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 250u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
|
||||||
HASH_NAMESPACE::hash_combine(seed2, 350u);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
|
||||||
|
|
||||||
BOOST_TEST(seed ==
|
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
|
custom_vector.begin(), custom_vector.end()));
|
||||||
BOOST_TEST(seed == seed2);
|
BOOST_TEST(seed == seed2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
custom_tests();
|
custom_tests();
|
||||||
#endif
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ using std::list;
|
|||||||
#define CONTAINER_TYPE list
|
#define CONTAINER_TYPE list
|
||||||
#include "./hash_sequence_test.hpp"
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
list_tests::list_hash_integer_tests();
|
list_tests::list_hash_integer_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,19 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
using std::map;
|
using std::map;
|
||||||
#define CONTAINER_TYPE map
|
#define CONTAINER_TYPE map
|
||||||
@@ -27,11 +27,11 @@ using std::multimap;
|
|||||||
#define CONTAINER_TYPE multimap
|
#define CONTAINER_TYPE multimap
|
||||||
#include "./hash_map_test.hpp"
|
#include "./hash_map_test.hpp"
|
||||||
|
|
||||||
#endif // TEST_EXTENSTIONS
|
#endif // BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
map_tests::map_hash_integer_tests();
|
map_tests::map_hash_integer_tests();
|
||||||
multimap_tests::multimap_hash_integer_tests();
|
multimap_tests::multimap_hash_integer_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+16
-15
@@ -7,44 +7,45 @@
|
|||||||
#error "CONTAINER_TYPE not defined"
|
#error "CONTAINER_TYPE not defined"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <boost/preprocessor/cat.hpp>
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4244) // conversion from 'int' to 'float'
|
||||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||||
{
|
{
|
||||||
template <class T>
|
template <class T>
|
||||||
void integer_tests(T* = 0)
|
void integer_tests(T* = 0)
|
||||||
{
|
{
|
||||||
const int number_of_containers = 10;
|
const int number_of_containers = 10;
|
||||||
T containers[number_of_containers];
|
T containers[number_of_containers];
|
||||||
typedef typename T::value_type pair;
|
typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::key_type key;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
|
||||||
|
|
||||||
for(int i = 0; i < 5; ++i) {
|
for(int i = 0; i < 5; ++i) {
|
||||||
for(int j = 0; j < i; ++j)
|
for(int j = 0; j < i; ++j)
|
||||||
containers[i].insert(pair(0, 0));
|
containers[i].insert(pair(key(0), value(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
containers[6].insert(pair(1,0));
|
containers[6].insert(pair(key(1),value(0)));
|
||||||
containers[7].insert(pair(1,0));
|
containers[7].insert(pair(key(1),value(0)));
|
||||||
containers[7].insert(pair(1,0));
|
containers[7].insert(pair(key(1),value(0)));
|
||||||
containers[8].insert(pair(-1,1));
|
containers[8].insert(pair(key(-1),value(1)));
|
||||||
containers[9].insert(pair(-1,3));
|
containers[9].insert(pair(key(-1),value(3)));
|
||||||
containers[9].insert(pair(-1,3));
|
containers[9].insert(pair(key(-1),value(3)));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2]) ==
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2])
|
BOOST_TEST(hasher(containers[i2])
|
||||||
== HASH_NAMESPACE::hash_range(
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
containers[i2].begin(), containers[i2].end()));
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
@@ -56,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<char, unsigned char>*) 0);
|
||||||
integer_tests((CONTAINER_TYPE<int, float>*) 0);
|
integer_tests((CONTAINER_TYPE<int, float>*) 0);
|
||||||
|
|||||||
@@ -3,17 +3,26 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#define HASH_NAMESPACE boost
|
#include "./config.hpp"
|
||||||
|
|
||||||
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
|
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
|
||||||
// (or at least one of them).
|
// (or at least one of them).
|
||||||
#define BOOST_HASH_NO_EXTENSIONS
|
#if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||||
|
# define BOOST_HASH_NO_EXTENSIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
#include <boost/functional/hash.hpp>
|
# include <functional>
|
||||||
|
#else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T> void ignore(T const&) {}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash< int[10] > hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
|
||||||
|
ignore(hasher);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,31 +3,35 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#define HASH_NAMESPACE boost
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
|
||||||
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
||||||
#if defined(BOOST_HASH_NO_EXTENSIONS)
|
# if defined(BOOST_HASH_NO_EXTENSIONS)
|
||||||
#undef BOOST_HASH_NO_EXTENSIONS
|
# undef BOOST_HASH_NO_EXTENSIONS
|
||||||
#endif
|
# endif
|
||||||
#include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
||||||
#define BOOST_HASH_NO_EXTENSIONS
|
# 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>
|
#include <deque>
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
std::deque<int> x;
|
std::deque<int> x;
|
||||||
|
|
||||||
x.push_back(1);
|
x.push_back(1);
|
||||||
x.push_back(2);
|
x.push_back(2);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<std::deque<int> > hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
|
||||||
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||||
|
#endif
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,30 +3,35 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#define HASH_NAMESPACE boost
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
|
||||||
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
// Include header with BOOST_HASH_NO_EXTENSIONS defined
|
||||||
#if !defined(BOOST_HASH_NO_EXTENSIONS)
|
# if !defined(BOOST_HASH_NO_EXTENSIONS)
|
||||||
#define BOOST_HASH_NO_EXTENSIONS
|
# define BOOST_HASH_NO_EXTENSIONS
|
||||||
#endif
|
# endif
|
||||||
#include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
// Include header without BOOST_HASH_NO_EXTENSIONS defined
|
||||||
#undef BOOST_HASH_NO_EXTENSIONS
|
# 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>
|
#include <map>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
std::map<int, int> x;
|
std::map<int, int> x;
|
||||||
|
|
||||||
x.insert(std::map<int, int>::value_type(53, -42));
|
x.insert(std::map<int, int>::value_type(53, -42));
|
||||||
x.insert(std::map<int, int>::value_type(14, -75));
|
x.insert(std::map<int, int>::value_type(14, -75));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
|
||||||
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
|
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||||
|
#endif
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-38
@@ -5,19 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <boost/preprocessor/cat.hpp>
|
#include <boost/container_hash/detail/limits.hpp>
|
||||||
#include <boost/functional/hash/detail/limits.hpp>
|
#include <boost/core/enable_if.hpp>
|
||||||
#include <boost/mpl/assert.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
|
|
||||||
#include "./compile_time.hpp"
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
@@ -28,15 +26,41 @@
|
|||||||
#pragma warning(disable:4310) // cast truncates constant value
|
#pragma warning(disable:4310) // cast truncates constant value
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void numeric_test(T*)
|
void numeric_extra_tests(typename
|
||||||
|
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
|
||||||
|
void*>::type = 0)
|
||||||
{
|
{
|
||||||
typedef boost::hash_detail::limits<T> limits;
|
typedef boost::hash_detail::limits<T> limits;
|
||||||
|
|
||||||
|
if(limits::is_signed ||
|
||||||
|
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
|
||||||
|
{
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
|
||||||
|
}
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void numeric_extra_tests(typename
|
||||||
|
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
|
||||||
|
void*>::type = 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void numeric_test(T*)
|
||||||
|
{
|
||||||
compile_time_tests((T*) 0);
|
compile_time_tests((T*) 0);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||||
HASH_NAMESPACE::hash<T> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
T v1 = (T) -5;
|
T v1 = (T) -5;
|
||||||
BOOST_TEST(x1(v1) == x2(v1));
|
BOOST_TEST(x1(v1) == x2(v1));
|
||||||
@@ -47,20 +71,13 @@ void numeric_test(T*)
|
|||||||
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
|
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
|
||||||
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
|
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
|
BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
|
||||||
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
|
BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
|
||||||
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
|
BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
|
||||||
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
|
BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
|
||||||
|
|
||||||
if (limits::is_integer)
|
numeric_extra_tests<T>();
|
||||||
{
|
|
||||||
if(limits::is_signed || limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,8 +88,8 @@ void limits_test(T*)
|
|||||||
|
|
||||||
if(limits::is_specialized)
|
if(limits::is_specialized)
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<T> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||||
HASH_NAMESPACE::hash<T> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
T min_value = (limits::min)();
|
T min_value = (limits::min)();
|
||||||
T max_value = (limits::max)();
|
T max_value = (limits::max)();
|
||||||
@@ -80,15 +97,15 @@ void limits_test(T*)
|
|||||||
BOOST_TEST(x1(min_value) == x2((limits::min)()));
|
BOOST_TEST(x1(min_value) == x2((limits::min)()));
|
||||||
BOOST_TEST(x1(max_value) == x2((limits::max)()));
|
BOOST_TEST(x1(max_value) == x2((limits::max)()));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
|
BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
|
||||||
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
|
BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
|
||||||
|
|
||||||
if (limits::is_integer)
|
if (limits::is_integer)
|
||||||
{
|
{
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
|
||||||
== std::size_t(min_value));
|
== std::size_t(min_value));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
|
||||||
== std::size_t(max_value));
|
== std::size_t(max_value));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -100,8 +117,8 @@ void poor_quality_tests(T*)
|
|||||||
{
|
{
|
||||||
typedef boost::hash_detail::limits<T> limits;
|
typedef boost::hash_detail::limits<T> limits;
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
|
||||||
HASH_NAMESPACE::hash<T> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
|
||||||
|
|
||||||
// A hash function can legally fail these tests, but it'll not be a good
|
// A hash function can legally fail these tests, but it'll not be a good
|
||||||
// sign.
|
// sign.
|
||||||
@@ -109,15 +126,20 @@ void poor_quality_tests(T*)
|
|||||||
BOOST_TEST(x1(T(1)) != x2(T(-1)));
|
BOOST_TEST(x1(T(1)) != x2(T(-1)));
|
||||||
if(T(1) != T(2))
|
if(T(1) != T(2))
|
||||||
BOOST_TEST(x1(T(1)) != x2(T(2)));
|
BOOST_TEST(x1(T(1)) != x2(T(2)));
|
||||||
if((limits::max)() != (limits::max)() - 1)
|
|
||||||
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1));
|
// 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()
|
void bool_test()
|
||||||
{
|
{
|
||||||
HASH_NAMESPACE::hash<bool> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
|
||||||
HASH_NAMESPACE::hash<bool> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
|
||||||
|
|
||||||
BOOST_TEST(x1(true) == x2(true));
|
BOOST_TEST(x1(true) == x2(true));
|
||||||
BOOST_TEST(x1(false) == x2(false));
|
BOOST_TEST(x1(false) == x2(false));
|
||||||
BOOST_TEST(x1(true) != x2(false));
|
BOOST_TEST(x1(true) != x2(false));
|
||||||
@@ -141,6 +163,12 @@ int main()
|
|||||||
NUMERIC_TEST(unsigned char, uchar)
|
NUMERIC_TEST(unsigned char, uchar)
|
||||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||||
NUMERIC_TEST(wchar_t, wchar)
|
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
|
#endif
|
||||||
NUMERIC_TEST(short, short)
|
NUMERIC_TEST(short, short)
|
||||||
NUMERIC_TEST(unsigned short, ushort)
|
NUMERIC_TEST(unsigned short, ushort)
|
||||||
@@ -149,11 +177,16 @@ int main()
|
|||||||
NUMERIC_TEST(long, hash_long)
|
NUMERIC_TEST(long, hash_long)
|
||||||
NUMERIC_TEST(unsigned long, ulong)
|
NUMERIC_TEST(unsigned long, ulong)
|
||||||
|
|
||||||
#if defined(BOOST_HAS_LONG_LONG)
|
#if !defined(BOOST_NO_LONG_LONG)
|
||||||
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
|
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
|
||||||
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
|
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_INT128)
|
||||||
|
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
|
||||||
|
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
|
||||||
|
#endif
|
||||||
|
|
||||||
NUMERIC_TEST(float, float)
|
NUMERIC_TEST(float, float)
|
||||||
NUMERIC_TEST(double, double)
|
NUMERIC_TEST(double, double)
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -5,18 +5,14 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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 <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/mpl/assert.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
|
|
||||||
#include "./compile_time.hpp"
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
void pointer_tests()
|
void pointer_tests()
|
||||||
@@ -24,8 +20,8 @@ void pointer_tests()
|
|||||||
compile_time_tests((int**) 0);
|
compile_time_tests((int**) 0);
|
||||||
compile_time_tests((void**) 0);
|
compile_time_tests((void**) 0);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<int*> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
|
||||||
HASH_NAMESPACE::hash<int*> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
|
||||||
|
|
||||||
int int1;
|
int int1;
|
||||||
int int2;
|
int int2;
|
||||||
@@ -33,9 +29,9 @@ void pointer_tests()
|
|||||||
BOOST_TEST(x1(0) == x2(0));
|
BOOST_TEST(x1(0) == x2(0));
|
||||||
BOOST_TEST(x1(&int1) == x2(&int1));
|
BOOST_TEST(x1(&int1) == x2(&int1));
|
||||||
BOOST_TEST(x1(&int2) == x2(&int2));
|
BOOST_TEST(x1(&int2) == x2(&int2));
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
|
BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
|
||||||
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
|
BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
|
||||||
|
|
||||||
// This isn't specified in Peter's proposal:
|
// This isn't specified in Peter's proposal:
|
||||||
BOOST_TEST(x1(0) == 0);
|
BOOST_TEST(x1(0) == 0);
|
||||||
|
|||||||
+29
-30
@@ -5,23 +5,20 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#if !defined(TEST_EXTENSIONS)
|
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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 <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/mpl/assert.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
void hash_range_tests()
|
void hash_range_tests()
|
||||||
@@ -43,37 +40,39 @@ void hash_range_tests()
|
|||||||
std::vector<int> x;
|
std::vector<int> x;
|
||||||
|
|
||||||
std::size_t x_seed = 0;
|
std::size_t x_seed = 0;
|
||||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
|
!= BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
|
||||||
|
|
||||||
x.push_back(10);
|
x.push_back(10);
|
||||||
HASH_NAMESPACE::hash_combine(x_seed, 10);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
|
||||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
x.push_back(20);
|
x.push_back(20);
|
||||||
HASH_NAMESPACE::hash_combine(x_seed, 20);
|
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
|
||||||
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
|
||||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
|
||||||
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
|
||||||
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
|
||||||
|
|
||||||
std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
|
std::size_t seed =
|
||||||
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
|
||||||
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
|
||||||
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
|
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
|
||||||
|
BOOST_TEST(seed ==
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
|||||||
+17
-17
@@ -7,18 +7,18 @@
|
|||||||
#error "CONTAINER_TYPE not defined"
|
#error "CONTAINER_TYPE not defined"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <boost/preprocessor/cat.hpp>
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||||
{
|
{
|
||||||
template <class T>
|
template <class T>
|
||||||
void integer_tests(T* = 0)
|
void integer_tests(T* = 0)
|
||||||
{
|
{
|
||||||
|
typedef typename T::value_type value_type;
|
||||||
|
|
||||||
const int number_of_containers = 11;
|
const int number_of_containers = 11;
|
||||||
T containers[number_of_containers];
|
T containers[number_of_containers];
|
||||||
|
|
||||||
@@ -27,27 +27,27 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
|||||||
containers[i].push_back(0);
|
containers[i].push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
containers[5].push_back(1);
|
containers[5].push_back(value_type(1));
|
||||||
containers[6].push_back(1);
|
containers[6].push_back(value_type(1));
|
||||||
containers[6].push_back(1);
|
containers[6].push_back(value_type(1));
|
||||||
containers[7].push_back(-1);
|
containers[7].push_back(value_type(-1));
|
||||||
containers[8].push_back(-1);
|
containers[8].push_back(value_type(-1));
|
||||||
containers[8].push_back(-1);
|
containers[8].push_back(value_type(-1));
|
||||||
containers[9].push_back(1);
|
containers[9].push_back(value_type(1));
|
||||||
containers[9].push_back(-1);
|
containers[9].push_back(value_type(-1));
|
||||||
containers[10].push_back(-1);
|
containers[10].push_back(value_type(-1));
|
||||||
containers[10].push_back(1);
|
containers[10].push_back(value_type(1));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2]) ==
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2])
|
BOOST_TEST(hasher(containers[i2])
|
||||||
== HASH_NAMESPACE::hash_range(
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
containers[i2].begin(), containers[i2].end()));
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
@@ -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<char>*) 0);
|
||||||
integer_tests((CONTAINER_TYPE<int>*) 0);
|
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ using std::multiset;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
set_tests::set_hash_integer_tests();
|
set_tests::set_hash_integer_tests();
|
||||||
multiset_tests::multiset_hash_integer_tests();
|
multiset_tests::multiset_hash_integer_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+20
-20
@@ -7,18 +7,18 @@
|
|||||||
#error "CONTAINER_TYPE not defined"
|
#error "CONTAINER_TYPE not defined"
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <boost/preprocessor/cat.hpp>
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
#if defined(BOOST_MSVC)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4245) // signed/unsigned mismatch
|
#pragma warning(disable:4245) // signed/unsigned mismatch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
|
||||||
{
|
{
|
||||||
template <class T>
|
template <class T>
|
||||||
void integer_tests(T* = 0)
|
void integer_tests(T* = 0)
|
||||||
{
|
{
|
||||||
|
typedef typename T::value_type value_type;
|
||||||
|
|
||||||
const int number_of_containers = 12;
|
const int number_of_containers = 12;
|
||||||
T containers[number_of_containers];
|
T containers[number_of_containers];
|
||||||
|
|
||||||
@@ -27,30 +27,30 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
|
|||||||
containers[i].insert(0);
|
containers[i].insert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
containers[6].insert(1);
|
containers[6].insert(value_type(1));
|
||||||
containers[7].insert(1);
|
containers[7].insert(value_type(1));
|
||||||
containers[7].insert(1);
|
containers[7].insert(value_type(1));
|
||||||
containers[8].insert(-1);
|
containers[8].insert(value_type(-1));
|
||||||
containers[9].insert(-1);
|
containers[9].insert(value_type(-1));
|
||||||
containers[9].insert(-1);
|
containers[9].insert(value_type(-1));
|
||||||
containers[10].insert(-1);
|
containers[10].insert(value_type(-1));
|
||||||
containers[10].insert(1);
|
containers[10].insert(value_type(1));
|
||||||
containers[11].insert(1);
|
containers[11].insert(value_type(1));
|
||||||
containers[11].insert(2);
|
containers[11].insert(value_type(2));
|
||||||
containers[11].insert(3);
|
containers[11].insert(value_type(3));
|
||||||
containers[11].insert(4);
|
containers[11].insert(value_type(4));
|
||||||
containers[11].insert(5);
|
containers[11].insert(value_type(5));
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<T> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
|
||||||
|
|
||||||
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
for(int i2 = 0; i2 < number_of_containers; ++i2) {
|
||||||
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2]) ==
|
BOOST_TEST(hasher(containers[i2]) ==
|
||||||
HASH_NAMESPACE::hash_value(containers[i2]));
|
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
|
||||||
|
|
||||||
BOOST_TEST(hasher(containers[i2])
|
BOOST_TEST(hasher(containers[i2])
|
||||||
== HASH_NAMESPACE::hash_range(
|
== BOOST_HASH_TEST_NAMESPACE::hash_range(
|
||||||
containers[i2].begin(), containers[i2].end()));
|
containers[i2].begin(), containers[i2].end()));
|
||||||
|
|
||||||
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
|
||||||
@@ -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<char>*) 0);
|
||||||
integer_tests((CONTAINER_TYPE<int>*) 0);
|
integer_tests((CONTAINER_TYPE<int>*) 0);
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
|
||||||
|
#define TEST_ARRAY
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_ARRAY
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void array_tests(T const& v) {
|
||||||
|
boost::hash<typename T::value_type> hf;
|
||||||
|
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||||
|
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
|
||||||
|
if (i != j)
|
||||||
|
BOOST_TEST(hf(*i) != hf(*j));
|
||||||
|
else
|
||||||
|
BOOST_TEST(hf(*i) == hf(*j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_array_test() {
|
||||||
|
/*
|
||||||
|
boost::hash<std::array<int, 0> > empty_array_hash;
|
||||||
|
std::array<int, 0> empty_array;
|
||||||
|
BOOST_TEST(empty_array_hash(empty_array) == boost::hash_value(empty_array));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void int_1_array_test()
|
||||||
|
{
|
||||||
|
std::vector<std::array<int, 1> > arrays;
|
||||||
|
std::array<int, 1> val;
|
||||||
|
val[0] = 0;
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = 1;
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = 2;
|
||||||
|
arrays.push_back(val);
|
||||||
|
array_tests(arrays);
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_1_array_test()
|
||||||
|
{
|
||||||
|
std::vector<std::array<std::string, 1> > arrays;
|
||||||
|
std::array<std::string, 1> val;
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = "one";
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = "two";
|
||||||
|
arrays.push_back(val);
|
||||||
|
array_tests(arrays);
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_3_array_test()
|
||||||
|
{
|
||||||
|
std::vector<std::array<std::string,3 > > arrays;
|
||||||
|
std::array<std::string, 3> val;
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = "one";
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = ""; val[1] = "one"; val[2] = "";
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = ""; val[1] = ""; val[2] = "one";
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = "one"; val[1] = "one"; val[2] = "one";
|
||||||
|
arrays.push_back(val);
|
||||||
|
val[0] = "one"; val[1] = "two"; val[2] = "three";
|
||||||
|
arrays.push_back(val);
|
||||||
|
array_tests(arrays);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_ARRAY
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_ARRAY
|
||||||
|
empty_array_test();
|
||||||
|
int_1_array_test();
|
||||||
|
string_1_array_test();
|
||||||
|
string_3_array_test();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
#else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||||
|
#define TEST_SMART_PTRS
|
||||||
|
#include <memory>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_SMART_PTRS
|
||||||
|
|
||||||
|
void shared_ptr_tests()
|
||||||
|
{
|
||||||
|
std::shared_ptr<int> x;
|
||||||
|
compile_time_tests(&x);
|
||||||
|
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x1;
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x2;
|
||||||
|
|
||||||
|
std::shared_ptr<int> ptr1(new int(10));
|
||||||
|
std::shared_ptr<int> ptr2;
|
||||||
|
|
||||||
|
BOOST_TEST(x1(x) == x2(ptr2));
|
||||||
|
BOOST_TEST(x1(x) != x2(ptr1));
|
||||||
|
ptr2.reset(new int(10));
|
||||||
|
BOOST_TEST(x1(ptr1) == x2(ptr1));
|
||||||
|
BOOST_TEST(x1(ptr1) != x2(ptr2));
|
||||||
|
ptr2 = ptr1;
|
||||||
|
BOOST_TEST(x1(ptr1) == x2(ptr2));
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||||
|
BOOST_TEST(x1(ptr1) == BOOST_HASH_TEST_NAMESPACE::hash_value(ptr2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void unique_ptr_tests()
|
||||||
|
{
|
||||||
|
std::unique_ptr<int> x;
|
||||||
|
compile_time_tests(&x);
|
||||||
|
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x1;
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x2;
|
||||||
|
|
||||||
|
std::unique_ptr<int> ptr1(new int(10));
|
||||||
|
std::unique_ptr<int> ptr2;
|
||||||
|
|
||||||
|
BOOST_TEST(x1(x) == x2(ptr2));
|
||||||
|
BOOST_TEST(x1(x) != x2(ptr1));
|
||||||
|
ptr2.reset(new int(10));
|
||||||
|
BOOST_TEST(x1(ptr1) == x2(ptr1));
|
||||||
|
BOOST_TEST(x1(ptr1) != x2(ptr2));
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_SMART_PTRS
|
||||||
|
shared_ptr_tests();
|
||||||
|
unique_ptr_tests();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
// Copyright 2012 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
# else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||||
|
#define TEST_TUPLE
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST_TUPLE
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void tuple_tests(T const& v) {
|
||||||
|
boost::hash<typename T::value_type> hf;
|
||||||
|
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||||
|
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
|
||||||
|
if (i != j)
|
||||||
|
BOOST_TEST(hf(*i) != hf(*j));
|
||||||
|
else
|
||||||
|
BOOST_TEST(hf(*i) == hf(*j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void empty_tuple_test() {
|
||||||
|
boost::hash<std::tuple<> > empty_tuple_hash;
|
||||||
|
std::tuple<> empty_tuple;
|
||||||
|
BOOST_TEST(empty_tuple_hash(empty_tuple) == boost::hash_value(empty_tuple));
|
||||||
|
}
|
||||||
|
|
||||||
|
void int_tuple_test() {
|
||||||
|
std::vector<std::tuple<int> > int_tuples;
|
||||||
|
int_tuples.push_back(std::make_tuple(0));
|
||||||
|
int_tuples.push_back(std::make_tuple(1));
|
||||||
|
int_tuples.push_back(std::make_tuple(2));
|
||||||
|
tuple_tests(int_tuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
void int_string_tuple_test() {
|
||||||
|
std::vector<std::tuple<int, std::string> > int_string_tuples;
|
||||||
|
int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(0, std::string("")));
|
||||||
|
int_string_tuples.push_back(std::make_tuple(1, std::string("")));
|
||||||
|
tuple_tests(int_string_tuples);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TEST_TUPLE
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef TEST_TUPLE
|
||||||
|
empty_tuple_test();
|
||||||
|
int_tuple_test();
|
||||||
|
int_string_tuple_test();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
+134
-27
@@ -5,73 +5,180 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_STD_INCLUDES
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
#else
|
#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 <boost/mpl/assert.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "./compile_time.hpp"
|
#include "./compile_time.hpp"
|
||||||
|
|
||||||
void string_tests()
|
void string_tests()
|
||||||
{
|
{
|
||||||
compile_time_tests((std::string*) 0);
|
compile_time_tests((std::string*) 0);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<std::string> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
|
||||||
HASH_NAMESPACE::hash<std::string> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
|
||||||
|
|
||||||
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
|
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
|
||||||
BOOST_TEST(x1("") == x2(std::string()));
|
BOOST_TEST(x1("") == x2(std::string()));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
std::string value1;
|
std::string value1;
|
||||||
std::string value2("Hello");
|
std::string value2("Hello");
|
||||||
|
|
||||||
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
|
||||||
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
|
||||||
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
|
||||||
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||||
#endif
|
#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()
|
void wstring_tests()
|
||||||
{
|
{
|
||||||
compile_time_tests((std::wstring*) 0);
|
compile_time_tests((std::wstring*) 0);
|
||||||
|
|
||||||
HASH_NAMESPACE::hash<std::wstring> x1;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
|
||||||
HASH_NAMESPACE::hash<std::wstring> x2;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
|
||||||
|
|
||||||
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
|
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
|
||||||
BOOST_TEST(x1(L"") == x2(std::wstring()));
|
BOOST_TEST(x1(L"") == x2(std::wstring()));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
std::wstring value1;
|
std::wstring value1;
|
||||||
std::wstring value2(L"Hello");
|
std::wstring value2(L"Hello");
|
||||||
|
|
||||||
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
|
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
|
||||||
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
|
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
|
||||||
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
|
||||||
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
|
||||||
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#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()
|
int main()
|
||||||
{
|
{
|
||||||
string_tests();
|
string_tests();
|
||||||
#if !defined(BOOST_NO_STD_WSTRING)
|
string0_tests();
|
||||||
|
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||||
wstring_tests();
|
wstring_tests();
|
||||||
#endif
|
#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();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
// Copyright 2011 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
|
# include <functional>
|
||||||
|
#else
|
||||||
|
# include <boost/container_hash/hash.hpp>
|
||||||
|
#endif
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||||
|
|
||||||
|
#include <typeindex>
|
||||||
|
|
||||||
|
void test_type_index() {
|
||||||
|
BOOST_HASH_TEST_NAMESPACE::hash<std::type_index> hasher;
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_TYPEID)
|
||||||
|
std::cout<<"Unable to test std::type_index, as typeid isn't available"
|
||||||
|
<<std::endl;
|
||||||
|
#else
|
||||||
|
std::type_index int_index = typeid(int);
|
||||||
|
std::type_index int2_index = typeid(int);
|
||||||
|
std::type_index char_index = typeid(char);
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(int_index) == int_index.hash_code());
|
||||||
|
BOOST_TEST(hasher(int_index) == int2_index.hash_code());
|
||||||
|
BOOST_TEST(hasher(char_index) == char_index.hash_code());
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int_index.hash_code());
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
|
||||||
|
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(char_index) == char_index.hash_code());
|
||||||
|
|
||||||
|
BOOST_TEST(hasher(int_index) == hasher(int2_index));
|
||||||
|
BOOST_TEST(hasher(int_index) != hasher(char_index));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||||
|
test_type_index();
|
||||||
|
#else
|
||||||
|
std::cout<<"<type_index> not available."<<std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
void array_int_test()
|
void array_int_test()
|
||||||
{
|
{
|
||||||
@@ -29,32 +29,32 @@ void array_int_test()
|
|||||||
8, -12, 23, 65, 45,
|
8, -12, 23, 65, 45,
|
||||||
-1, 93, -54, 987, 3
|
-1, 93, -54, 987, 3
|
||||||
};
|
};
|
||||||
HASH_NAMESPACE::hash<int[25]> hasher1;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
|
||||||
|
|
||||||
int array2[1] = {3};
|
int array2[1] = {3};
|
||||||
HASH_NAMESPACE::hash<int[1]> hasher2;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
|
||||||
|
|
||||||
int array3[2] = {2, 3};
|
int array3[2] = {2, 3};
|
||||||
HASH_NAMESPACE::hash<int[2]> hasher3;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
|
||||||
|
|
||||||
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
|
BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
|
||||||
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
|
BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
|
||||||
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
|
BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void two_dimensional_array_test()
|
void two_dimensional_array_test()
|
||||||
{
|
{
|
||||||
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
|
||||||
HASH_NAMESPACE::hash<int[3][2]> hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
|
||||||
|
|
||||||
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
|
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
array_int_test();
|
array_int_test();
|
||||||
two_dimensional_array_test();
|
two_dimensional_array_test();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
#include "./config.hpp"
|
#include "./config.hpp"
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
# ifdef TEST_STD_INCLUDES
|
# ifdef BOOST_HASH_TEST_STD_INCLUDES
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# else
|
# else
|
||||||
# include <boost/functional/hash.hpp>
|
# include <boost/container_hash/hash.hpp>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -23,13 +23,46 @@ using std::vector;
|
|||||||
#define CONTAINER_TYPE vector
|
#define CONTAINER_TYPE vector
|
||||||
#include "./hash_sequence_test.hpp"
|
#include "./hash_sequence_test.hpp"
|
||||||
|
|
||||||
#endif // TEST_EXTENSIONS
|
#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()
|
int main()
|
||||||
{
|
{
|
||||||
#ifdef TEST_EXTENSIONS
|
#ifdef BOOST_HASH_TEST_EXTENSIONS
|
||||||
vector_tests::vector_hash_integer_tests();
|
vector_tests::vector_hash_integer_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vector_bool_tests::vector_bool_test();
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
// Copyright 2010 Daniel James.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
struct base {};
|
||||||
|
std::size_t hash_value(base const&) { return 0; }
|
||||||
|
|
||||||
|
struct converts { operator base() const { return base(); } };
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
boost::hash<test::converts> hash;
|
||||||
|
test::converts x;
|
||||||
|
|
||||||
|
hash(x);
|
||||||
|
}
|
||||||
+11
-9
@@ -3,24 +3,26 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#define HASH_NAMESPACE boost
|
#include "./config.hpp"
|
||||||
#include <boost/functional/hash.hpp>
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
int f(std::size_t hash1, int* x1) {
|
int f(std::size_t hash1, int* x1) {
|
||||||
|
|
||||||
// Check that HASH_NAMESPACE::hash<int*> works in both files.
|
// Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
|
||||||
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
|
||||||
BOOST_TEST(hash1 == ptr_hasher(x1));
|
BOOST_TEST(hash1 == ptr_hasher(x1));
|
||||||
|
|
||||||
#if defined(TEST_EXTENSIONS)
|
#if defined(BOOST_HASH_TEST_EXTENSIONS)
|
||||||
|
|
||||||
// Check that std::vector<std::size_t> is avaiable in this file.
|
// Check that std::vector<std::size_t> is avaiable in this file.
|
||||||
std::vector<std::size_t> x;
|
std::vector<std::size_t> x;
|
||||||
x.push_back(*x1);
|
x.push_back(static_cast<std::size_t>(*x1));
|
||||||
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
|
||||||
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
|
return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,17 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#define HASH_NAMESPACE boost
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#define BOOST_HASH_TEST_NAMESPACE boost
|
||||||
#define BOOST_HASH_NO_EXTENSIONS
|
#define BOOST_HASH_NO_EXTENSIONS
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
extern int f(std::size_t, int*);
|
extern int f(std::size_t, int*);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
HASH_NAMESPACE::hash<int*> ptr_hasher;
|
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
|
||||||
int x = 55;
|
int x = 55;
|
||||||
BOOST_TEST(!f(ptr_hasher(&x), &x));
|
BOOST_TEST(!f(ptr_hasher(&x), &x));
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
|
|||||||
+3
-1
@@ -3,7 +3,9 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
extern int f();
|
extern int f();
|
||||||
int main() { return f(); }
|
int main() { return f(); }
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include <boost/functional/hash.hpp>
|
#include "./config.hpp"
|
||||||
|
|
||||||
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
int f() { return 0; }
|
int f() { return 0; }
|
||||||
|
|||||||
@@ -6,9 +6,11 @@
|
|||||||
// Check that I haven't inadvertantly pulled namespace std into the global
|
// Check that I haven't inadvertantly pulled namespace std into the global
|
||||||
// namespace.
|
// namespace.
|
||||||
|
|
||||||
|
#include "./config.hpp"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/functional/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
typedef list<int> foo;
|
typedef list<int> foo;
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
|||||||
Reference in New Issue
Block a user