Compare commits

..

1 Commits

Author SHA1 Message Date
nobody
42f5aeb552 This commit was manufactured by cvs2svn to create tag
'Version_1_34_0'.

[SVN r37679]
2007-05-12 21:59:40 +00:00
90 changed files with 1910 additions and 5693 deletions

View File

@@ -1,72 +0,0 @@
# Copyright 2017 Daniel James
# Copyright 2016-2021 Peter Dimov
# 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
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17,latest
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\container_hash\
- python tools/boostdep/depinst/depinst.py -I examples container_hash
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 --verbose-test libs/container_hash/test//hash_info toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
- b2 -j3 libs/container_hash/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

View File

@@ -1,204 +0,0 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
install: g++-4.8-multilib
address-model: 32,64
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: g++-5-multilib
address-model: 32,64
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: g++-6-multilib
address-model: 32,64
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-10-multilib
address-model: 32,64
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install: g++-11-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-10.15
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py -I examples --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
./b2 -j3 --verbose-test libs/$LIBRARY/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.1
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2016
- toolset: msvc-14.2
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2019
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py -I examples --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 --verbose-test libs/%LIBRARY%/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release

View File

@@ -1,78 +0,0 @@
# 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

View File

@@ -1,22 +0,0 @@
# 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...3.20)
project(boost_container_hash VERSION "${BOOST_SUPERPROJECT_VERSION}" 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
)

View File

@@ -1,25 +1,9 @@
# Copyright 2005-2008 Daniel James.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# Copyright Daniel James 2005. Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
using boostbook ;
using quickbook ;
xml hash : hash.qbk ;
boostbook standalone : hash :
<xsl:param>boost.root=../../../..
<xsl:param>chunk.first.sections=1
<xsl:param>chunk.section.depth=2
<xsl:param>generate.section.toc.level=2
<xsl:param>toc.section.depth=1
<xsl:param>toc.max.depth=1
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/container_hash/doc/html
;
###############################################################################
alias boostdoc : hash ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;
boostbook standalone : hash ;

View File

@@ -1,222 +1,32 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
[section:changes Change Log]
[h2 Boost 1.33.0]
* Initial Release
[h2 Boost 1.33.1]
[h2 Changes in Boost 1.33.1]
* Fixed the points example, as pointed out by 沈慧峰.
[h2 Boost 1.34.0]
[h2 Changes in Boost 1.34.0]
* Use declarations for standard classes, so that the library
doesn't need to include all of their headers
* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header,
<[headerref boost/functional/hash.hpp]> is used.
* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which
disables the extensions to TR1.
disables the extensions to TR1
* Minor improvements to the hash functions for floating point numbers.
* Update the portable example to hopefully be more generally portable.
[h2 Boost 1.34.1]
[h2 Future Developments]
* [@http://svn.boost.org/trac/boost/ticket/952 Ticket 952]:
Suppress incorrect 64-bit warning on Visual C++.
[h2 Boost 1.35.0]
* Support for `long long`, `std::complex`.
* Improved algorithm for hashing floating point numbers:
* Improved portablity, as described by Daniel Krügler in
[@http://lists.boost.org/boost-users/2005/08/13418.php
a post to the boost users list].
* Fits more information into each combine loop, which can reduce the
the number of times combine is called and hopefully give a better
quality hash function.
* Improved the algorithm for hashing floating point numbers.
* On Cygwin use a binary hash function for floating point numbers, as
Cygwin doesn't have decent floating point functions for `long double`.
* Never uses `fpclass` which doesn't support `long double`.
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
Removed unnecessary use of `errno`.
* Explicitly overload for more built in types.
* Minor improvements to the documentation.
* A few bug and warning fixes:
* [@http://svn.boost.org/trac/boost/ticket/1509 Ticket 1509]:
Suppress another Visual C++ warning.
* Some workarounds for the Sun compilers.
[h2 Boost 1.36.0]
* Stop using OpenBSD's dodgy `std::numeric_limits`.
* Using the boost typedefs for `long long` and `unsigned long long`.
* Move the extensions into their own header.
[h2 Boost 1.37.0]
* [@http://svn.boost.org/trac/boost/ticket/2264 Ticket 2264]:
In Visual C++, always use C99 float functions for `long double` and `float` as
the C++ overloads aren't always availables.
[h2 Boost 1.38.0]
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
will be removed in a future version of Boost.
* Moved detail headers out of `boost/container_hash/detail`, since they are part of
functional/hash, not container_hash. `boost/container_hash/detail/container_fwd.hpp`
has been moved to `boost/detail/container_fwd.hpp` as it's used outside of
this library, the others have been moved to `boost/functional/hash/detail`.
[h2 Boost 1.39.0]
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
forwarding header in the old location. You should still use the old location,
the new location is mainly for implementation and possible modularization.
* [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated
headers.
* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
for vxworks.
[h2 Boost 1.40.0]
* Automatically configure the float functions using template metaprogramming
instead of trying to configure every possibility manually.
* Workaround for when STLport doesn't support long double.
[h2 Boost 1.42.0]
* Reduce the number of warnings for Visual C++ warning level 4.
* Some code formatting changes to fit lines into 80 characters.
* Rename an internal namespace.
[h2 Boost 1.43.0]
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
Don't foward declare containers when using gcc's parallel library,
allow user to stop forward declaration by defining the
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
Avoid hashing 0.5 and 0 to the same number.
* Stop using deprecated `BOOST_HAS_*` macros.
[h2 Boost 1.44.0]
* Add option to prevent implicit conversions when calling `hash_value` by
defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
for a type that does not have `hash_value` declared but does have
an implicit conversion to a type that does, it would use that
implicit conversion to hash it. Which can sometimes go very wrong,
e.g. using a conversion to bool and only hashing to 2 possible
values. Since fixing this is a breaking change and was only
approached quite late in the release cycle with little discussion
it's opt-in for now. This, or something like it, will become the
default in a future version.
[h2 Boost 1.46.0]
* Avoid warning due with gcc's `-Wconversion` flag.
[h2 Boost 1.50.0]
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
Avoid gcc's `-Wfloat-equal` warning.
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
Support `std::array` and `std::tuple` when available.
* Add deprecation warning to the long deprecated
`boost/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.
* A more portable hash function, as described by Daniel Krügler in
[@http://lists.boost.org/boost-users/2005/08/13418.php a post to the boost users list].
* Implement `hash_value` for more classes, including `std::complex`.
[endsect]

View File

@@ -1,5 +1,5 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 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) ]
@@ -10,7 +10,7 @@ to turn them of in order to check that your code will work with other
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
When this macro is defined, only the specialisations detailed
in TR1 will be declared. But, if you later undefine the macro and include
<[headerref boost/container_hash/hash.hpp]> then the non-specialised form will be defined
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
- activating the extensions.
It is strongly recommended that you never undefine the macro - and only define

View File

@@ -1,29 +1,24 @@
[library Boost.ContainerHash
[quickbook 1.5]
[library Boost.Functional/Hash
[quickbook 1.3]
[authors [James, Daniel]]
[copyright 2005 2006 2007 2008 Daniel James]
[copyright 2005 2006 Daniel James]
[purpose A TR1 hash function object that can be extended to hash user
defined types]
[category higher-order]
[id hash]
[dirname container_hash]
[dirname hash]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
[@http://www.boost.org/LICENSE_1_0.txt]
]
]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[include:hash intro.qbk]
[include:hash tutorial.qbk]
[include:hash portability.qbk]
[include:hash disable.qbk]
[include:hash changes.qbk]
[include:hash rationale.qbk]
[xinclude ref.xml]
[include:hash links.qbk]
[include:hash thanks.qbk]

View File

@@ -1,5 +1,5 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 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) ]
@@ -11,20 +11,19 @@
[def __tr1__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
TR1]]
[def __unordered__ [link unordered Boost.Unordered]]
[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
[def __multi-index__ [@boost:/libs/multi_index/doc/index.html
[def __multi-index__ [@../../libs/multi_index/doc/index.html
Boost Multi-Index Containers Library]]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
Boost.MultiIndex]]
[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-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
[classref boost::hash] is an implementation of the __hash-function__ object
specified by the __tr1-full__ (TR1). It is the default hash function for
__unordered__, __intrusive__'s unordered associative containers, and
__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
specified by the __tr1-full__ (TR1). It is intended for use as the default hash function
for unordered associative containers, and the __multi-index__'s hash indexes.
As it is compliant with __tr1__, it will work with:
@@ -41,12 +40,5 @@ __issues__ (page 63), this adds support for:
* the standard containers.
* extending [classref boost::hash] for custom types.
[note
This hash function is designed to be used in containers based on
the STL and is not suitable as a general purpose hash function.
For more details see the [link hash.rationale rationale].
]
[endsect]

View File

@@ -1,26 +1,26 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:links Links]
[*A Proposal to Add Hash Tables to the Standard Library]
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]
[*A Proposal to Add Hash Tables to the Standard Library]\n
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]\n
The hash table proposal explains much of the design. The hash function object
is discussed in Section D.
[*The C++ Standard Library Technical Report.]
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]
[*The C++ Standard Library Technical Report.]\n
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]\n
Contains the hash function specification in section 6.3.2.
[*Library Extension Technical Report Issues List.]
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]
[*Library Extension Technical Report Issues List.]\n
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]\n
The library implements the extension described in Issue 6.18, pages 63-67.
[*Methods for Identifying Versioned and Plagiarised Documents]
Timothy C. Hoad, Justin Zobel
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]
[*Methods for Identifying Versioned and Plagiarised Documents]\n
Timothy C. Hoad, Justin Zobel\n
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]\n
Contains the hash function that [funcref boost::hash_combine] is based on.
[endsect]

View File

@@ -1,5 +1,5 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 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) ]
@@ -10,7 +10,7 @@
__boost_hash__ is written to be as portable as possible, but unfortunately, several
older compilers don't support argument dependent lookup (ADL) - the mechanism
used for customisation. On those compilers custom overloads for `hash_value`
needs to be declared in the boost namespace.
need to be declared in the boost namespace.
On a strictly standards compliant compiler, an overload defined in the
boost namespace won't be found when __boost_hash__ is instantiated,
@@ -88,6 +88,18 @@ boost namespace:
}
Full code for this example is at
[@boost:/libs/container_hash/examples/portable.cpp /libs/container_hash/examples/portable.cpp].
[@../../libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[h2 Other Issues]
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
When using GCC on Solaris, `boost::hash_value(long double)` treats
`long double`s as `double`s - so the hash function doesn't take into account the
full range of values.
[endsect]

View File

@@ -1,50 +0,0 @@
[/ 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]

View File

@@ -1,6 +1,5 @@
<!--
Copyright Daniel James 2005-2009
Copyright 2005-2006 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)
-->
@@ -13,7 +12,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
</para>
</section>
<header name="boost/container_hash/hash.hpp">
<header name="boost/functional/hash.hpp">
<para>
Defines <code><classname>boost::hash</classname></code>,
and helper functions.
@@ -34,7 +33,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<classname>std::unary_function&lt;T, std::size_t&gt;</classname>
</inherit>
<purpose><simpara>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</simpara></purpose>
<purpose>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</purpose>
<method name="operator()" cv="const">
<type>std::size_t</type>
@@ -55,15 +54,6 @@ 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
required by TR1 are defined.
</para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws><para>
Only throws if
@@ -162,42 +152,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>char16_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char16_t</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>char32_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char32_t</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
@@ -306,42 +260,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>long long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>long long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned long long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned long long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
@@ -432,42 +350,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::u16string</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::u16string const&amp;</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&amp;</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template>
<template-type-parameter name="T"/>
@@ -487,31 +369,6 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::type_index</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::type_index</paramtype>
</parameter>
<returns>
<para><code>val.hash_code()</code></para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
<notes>
<para>
Only available if it's in your standard library and Boost.Config
is aware of it.
</para>
</notes>
</struct-specialization>
<free-function-group name="Support functions (Boost extension).">
<!--
boost::hash_combine
-->
@@ -523,32 +380,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<type>void</type>
<parameter name="seed"><paramtype>size_t &amp;</paramtype></parameter>
<parameter name="v"><paramtype>T const&amp;</paramtype></parameter>
<purpose><simpara>
<purpose>
Called repeatedly to incrementally create a hash value from
several variables.
</simpara></purpose>
<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>
</purpose>
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed &lt;&lt; 6) + (seed &gt;&gt; 2);</programlisting></effects>
<notes>
<para><functionname>hash_value</functionname> is called without
qualification, so that overloads can be found via ADL.</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws>
Only throws if <functionname>hash_value</functionname>(T) throws.
@@ -581,10 +421,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<parameter name="last"><paramtype>It</paramtype></parameter>
</signature>
<purpose><simpara>
<purpose>
Calculate the combined hash value of the elements of an iterator
range.
</simpara></purpose>
</purpose>
<effects>
<para>For the two argument overload:
<programlisting>
@@ -597,14 +437,15 @@ for(; first != last; ++first)
return seed;
</programlisting>
</para>
<para>For the three arguments overload:</para>
</para>For the three arguments overload:
<programlisting>
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
</programlisting>
<para>
</para>
</effects>
<notes>
<para>
@@ -613,15 +454,6 @@ for(; first != last; ++first)
container.
</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
@@ -631,63 +463,14 @@ for(; first != last; ++first)
</para></throws>
</overloaded-function>
</free-function-group>
<free-function-group name="Overloadable hash implementation (Boost extension).">
<!--
boost::hash_value - integers
-->
<overloaded-function name="hash_value">
<purpose><simpara>
<purpose>
Implementation of the hash function.
</simpara></purpose>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>bool</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>signed char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char16_t</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char32_t</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>short</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned short</paramtype></parameter>
</signature>
</purpose>
<signature>
<type>std::size_t</type>
@@ -709,16 +492,6 @@ for(; first != last; ++first)
<parameter name="val"><paramtype>unsigned long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned long long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>float</paramtype></parameter>
@@ -847,38 +620,6 @@ for(; first != last; ++first)
<parameter name="val"><paramtype>std::multimap&lt;K, T, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::type_index</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N">
<type>std::size_t</type>
</template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::array&lt;T, N&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T" pack="1"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::tuple&lt;T...&gt;</paramtype></parameter>
</signature>
<description><para>
Generally shouldn't be called directly by users, instead they should use
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
@@ -889,11 +630,6 @@ for(; first != last; ++first)
<notes>
<para>This is an extension to TR1</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws>
@@ -914,18 +650,9 @@ for(; first != last; ++first)
</thead>
<tbody>
<row>
<entry><code>bool</code>,
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>,
<code>wchar_t</code>, <code>char16_t</code>, <code>char32_t</code>,
<code>short</code>, <code>unsigned short</code>,
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
</entry>
<entry><code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code></entry>
<entry><code>val</code></entry>
</row>
<row>
<entry><code>long long</code>, <code>unsigned long long</code></entry>
<entry><code>val</code> when <code>abs(val) &lt;= std::numeric_limits&lt;std::size_t&gt;::max()</code>.</entry>
</row>
<row>
<entry><code>float</code>, <code>double</code>, <code>long double</code></entry>
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
@@ -950,8 +677,7 @@ for(; first != last; ++first)
<code>std::set&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::map&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::array&lt;T,&#160;N&gt;</code>
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>
</entry>
<entry><code>hash_range(val.begin(), val.end())</code></entry>
</row>
@@ -962,32 +688,11 @@ for(; first != last; ++first)
<functionname>hash_combine</functionname>(seed, val.second);
return seed;</programlisting></entry>
</row>
<row>
<entry><code>std::tuple&lt;T...&gt;</code></entry>
<entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, get&lt;0&gt;(val));
<functionname>hash_combine</functionname>(seed, get&lt;1&gt;(val));
// ....
return seed;</programlisting></entry>
</row>
<row>
<entry>
<code>std::complex&lt;T&gt;</code>
</entry>
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry>
<code>std::type_index</code>
</entry>
<entry><code>val.hash_code()</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>
</returns>
</overloaded-function>
</free-function-group>
</namespace>
</header>
</library-reference>

View File

@@ -1,27 +0,0 @@
#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]));
}

View File

@@ -1,19 +1,20 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:acknowledgements Acknowledgements]
This library is based on the design by Peter Dimov. During the initial
development
Joaquín M López Muñoz made many useful suggestions and contributed fixes.
This library is based on the design by Peter Dimov's original design.
During the initial development Joaquín M López Muñoz made many useful
suggestions, contributed fixes.
The formal review was managed by Thorsten Ottosen, and the library reviewed by:
David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris,
Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter,
Rob Stewart and Pavel Vozenilek. Since then, further constructive criticism has
been made by Daniel Krügler, Alexander Nasonov and 沈慧峰.
Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter, Rob
Stewart and Pavel Vozenilek. Since then, there have been further contributions
from Daniel Krügler, Alexander Nasonov, 沈慧峰 and John Maddock.
The implementation of the hash function for pointers is based on suggestions
made by Alberto Barbati and Dave Harris. Dave Harris also suggested an

View File

@@ -1,12 +1,9 @@
[/ Copyright 2005-2008 Daniel James.
[/ Copyright 2005-2006 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) ]
[quickbook 1.7]
[import samples/tutorial.cpp]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
[def __multi-index-short__ [@../../libs/multi_index/doc/index.html
Boost.MultiIndex]]
[section:tutorial Tutorial]
@@ -30,7 +27,7 @@ associative containers and you wish to use
To use [classref boost::hash] directly, create an instance and call it as a function:
#include <``[headerref boost/container_hash/hash.hpp]``>
#include <``[headerref boost/functional/hash.hpp]``>
int main()
{
@@ -42,7 +39,15 @@ To use [classref boost::hash] directly, create an instance and call it as a func
For an example of generic use, here is a function to generate a vector
containing the hashes of the elements of a container:
[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::insert_iterator(hashes),
``[classref boost::hash]``<typename Container::value_type>());
return hashes;
}
[endsect]
@@ -105,16 +110,16 @@ And you can now use [classref boost::hash] with book:
assert(books.find(dandelion) == books.end());
The full example can be found in:
[@boost:/libs/container_hash/examples/books.hpp /libs/container_hash/examples/books.hpp]
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp]
and
[@boost:/libs/container_hash/examples/books.cpp /libs/container_hash/examples/books.cpp].
[@../../libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
[tip
When writing a hash function, first look at how the equality function works.
Objects that are equal must generate the same hash value.
When objects are not equal they should generate different hash values.
In this object equality was based just on the id so the hash function
only hashes the id. If it was based on the object's name and author
only hash the id. If it was based on the objects name and author
then the hash function should take them into account
(how to do this is discussed in the next section).
]
@@ -165,7 +170,7 @@ of point, it can be repeatedly called for any number of elements. It calls
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
Full code for this example is at
[@boost:/libs/container_hash/examples/point.cpp /libs/container_hash/examples/point.cpp].
[@../../libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
[note
When using [funcref boost::hash_combine] the order of the
@@ -193,15 +198,5 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
std::vector<std::string> some_strings;
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
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]

View File

@@ -6,4 +6,3 @@
run books.cpp ;
run point.cpp ;
run portable.cpp ;
run template.cpp ;

View File

@@ -1,10 +1,10 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./books.hpp"
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
#include <cassert>
// If std::unordered_set was available:
@@ -20,7 +20,6 @@ int main()
boost::hash<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife);
(void)knife_hash_value; // suppress unused variable warning
// If std::unordered_set was available:
//

View File

@@ -1,7 +1,7 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This example illustrates how to use boost::hash with a custom hash function.
// The implementation is contained in books.cpp

View File

@@ -1,14 +1,9 @@
// Copyright 2005 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2005. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
#include <cassert>
// This example illustrates how to use boost::hash_combine to generate a hash

View File

@@ -1,14 +1,9 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
#include <cassert>
// This example illustrates how to customise boost::hash portably, so that

View File

@@ -1,18 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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());
}

View File

@@ -1,36 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// 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;
}
};

View File

@@ -1,336 +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_FLOAT_FUNCTIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
// sufficiently good floating point support to not require any
// workarounds.
//
// When set to 0, the library tries to automatically
// use the best available implementation. This normally works well, but
// breaks when ambiguities are created by odd namespacing of the functions.
//
// Note that if this is set to 0, the library should still take full
// advantage of the platform's floating point support.
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__LIBCOMO__)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// Rogue Wave library:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(_LIBCPP_VERSION)
// libc++
# define BOOST_HASH_CONFORMANT_FLOATS 1
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
// GNU libstdc++ 3
# if defined(__GNUC__) && __GNUC__ >= 4
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(__STL_CONFIG_H)
// generic SGI STL
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__MSL_CPP__)
// MSL standard lib:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__IBMCPP__)
// VACPP std lib (probably conformant for much earlier version).
# if __IBMCPP__ >= 1210
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(MSIPL_COMPILE_H)
// Modena C++ standard library
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library (this has to appear after any possible replacement libraries):
# if _CPPLIB_VER >= 405
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#else
# define BOOST_HASH_CONFORMANT_FLOATS 0
#endif
#if BOOST_HASH_CONFORMANT_FLOATS
// The standard library is known to be compliant, so don't use the
// configuration mechanism.
namespace boost {
namespace hash_detail {
template <typename Float>
struct call_ldexp {
typedef Float float_type;
inline Float operator()(Float x, int y) const {
return std::ldexp(x, y);
}
};
template <typename Float>
struct call_frexp {
typedef Float float_type;
inline Float operator()(Float x, int* y) const {
return std::frexp(x, y);
}
};
template <typename Float>
struct select_hash_type
{
typedef Float type;
};
}
}
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// The following tries to automatically detect which are available.
namespace boost {
namespace hash_detail {
// Returned by dummy versions of the float functions.
struct not_found {
// Implicitly convertible to float and long double in order to avoid
// a compile error when the dummy float functions are used.
inline operator float() const { return 0; }
inline operator long double() const { return 0; }
};
// A type for detecting the return type of functions.
template <typename T> struct is;
template <> struct is<float> { char x[10]; };
template <> struct is<double> { char x[20]; };
template <> struct is<long double> { char x[30]; };
template <> struct is<boost::hash_detail::not_found> { char x[40]; };
// Used to convert the return type of a function to a type for sizeof.
template <typename T> is<T> float_type(T);
// call_ldexp
//
// This will get specialized for float and long double
template <typename Float> struct call_ldexp
{
typedef double float_type;
inline double operator()(double a, int b) const
{
using namespace std;
return ldexp(a, b);
}
};
// call_frexp
//
// This will get specialized for float and long double
template <typename Float> struct call_frexp
{
typedef double float_type;
inline double operator()(double a, int* b) const
{
using namespace std;
return frexp(a, b);
}
};
}
}
// A namespace for dummy functions to detect when the actual function we want
// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
//
// AFAICT these have to be outside of the boost namespace, as if they're in
// the boost namespace they'll always be preferable to any other function
// (since the arguments are built in types, ADL can't be used).
namespace boost_hash_detect_float_functions {
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
}
// Macros for generating specializations of call_ldexp and call_frexp.
//
// check_cpp and check_c99 check if the C++ or C99 functions are available.
//
// Then the call_* functions select an appropriate implementation.
//
// I used c99_func in a few places just to get a unique name.
//
// Important: when using 'using namespace' at namespace level, include as
// little as possible in that namespace, as Visual C++ has an odd bug which
// can cause the namespace to be imported at the global level. This seems to
// happen mainly when there's a template in the same namesapce.
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
namespace boost_hash_detect_float_functions { \
template <class Float> \
boost::hash_detail::not_found c99_func(Float, type2); \
} \
\
namespace boost { \
namespace hash_detail { \
namespace c99_func##_detect { \
using namespace std; \
using namespace boost_hash_detect_float_functions; \
\
struct check { \
static type1 x; \
static type2 y; \
BOOST_STATIC_CONSTANT(bool, cpp = \
sizeof(float_type(cpp_func(x,y))) \
== sizeof(is<type1>)); \
BOOST_STATIC_CONSTANT(bool, c99 = \
sizeof(float_type(c99_func(x,y))) \
== sizeof(is<type1>)); \
}; \
} \
\
template <bool x> \
struct call_c99_##c99_func : \
boost::hash_detail::call_##cpp_func<double> {}; \
\
template <> \
struct call_c99_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return c99_func(a, b); \
} \
}; \
\
template <bool x> \
struct call_cpp_##c99_func : \
call_c99_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::c99 \
> {}; \
\
template <> \
struct call_cpp_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return cpp_func(a, b); \
} \
}; \
\
template <> \
struct call_##cpp_func<type1> : \
call_cpp_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::cpp \
> {}; \
} \
}
#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
namespace boost { \
namespace hash_detail { \
\
template <> \
struct call_##cpp_func<type1> { \
typedef type1 float_type; \
inline type1 operator()(type1 x, type2 y) const { \
return c99_func(x, y); \
} \
}; \
} \
}
#if defined(ldexpf)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
#endif
#if defined(ldexpl)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
#endif
#if defined(frexpf)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
#endif
#if defined(frexpl)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
#endif
#undef BOOST_HASH_CALL_FLOAT_MACRO
#undef BOOST_HASH_CALL_FLOAT_FUNC
namespace boost
{
namespace hash_detail
{
template <typename Float1, typename Float2>
struct select_hash_type_impl {
typedef double type;
};
template <>
struct select_hash_type_impl<float, float> {
typedef float type;
};
template <>
struct select_hash_type_impl<long double, long double> {
typedef long double type;
};
// select_hash_type
//
// If there is support for a particular floating point type, use that
// otherwise use double (there's always support for double).
template <typename Float>
struct select_hash_type : select_hash_type_impl<
BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
> {};
}
}
#endif // BOOST_HASH_CONFORMANT_FLOATS
#endif

View File

@@ -1,271 +0,0 @@
// 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

View File

@@ -1,62 +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)
//
// On some platforms std::limits gives incorrect values for long double.
// This tries to work around them.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/limits.hpp>
// On OpenBSD, numeric_limits is not reliable for long doubles, but
// the macros defined in <float.h> are and support long double when STLport
// doesn't.
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
#include <float.h>
#endif
namespace boost
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
template <>
struct limits<long double>
: std::numeric_limits<long double>
{
static long double epsilon() {
return LDBL_EPSILON;
}
static long double (max)() {
return LDBL_MAX;
}
static long double (min)() {
return LDBL_MIN;
}
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
#if defined(_STLP_NO_LONG_DOUBLE)
BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
#endif
};
#endif // __OpenBSD__
}
}
#endif

View File

@@ -1,361 +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)
// 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
#include <memory>
#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

View File

@@ -1,767 +0,0 @@
// 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>
#include <climits>
#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<std::size_t Bits> struct hash_combine_impl
{
template <typename SizeT>
inline static SizeT fn(SizeT seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
template<> struct hash_combine_impl<32>
{
inline static boost::uint32_t fn(boost::uint32_t h1, boost::uint32_t k1)
{
const boost::uint32_t c1 = 0xcc9e2d51;
const boost::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;
return h1;
}
};
template<> struct hash_combine_impl<64>
{
inline static boost::uint64_t fn(boost::uint64_t h, boost::uint64_t k)
{
const boost::uint64_t m = (boost::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995;
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;
return h;
}
};
}
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;
seed = boost::hash_detail::hash_combine_impl<sizeof(std::size_t) * CHAR_BIT>::fn(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(BOOST_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

View File

@@ -1,36 +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)
// 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(BOOST_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

View File

@@ -0,0 +1,95 @@
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_DETAIL_CONTAINER_FWD_HPP)
#define BOOST_DETAIL_CONTAINER_FWD_HPP
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
#else
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
#if (defined(__GLIBCXX__) && defined(_GLIBCXX_DEBUG)) \
|| BOOST_WORKAROUND(__BORLANDC__, > 0x551) \
|| BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x842)) \
|| (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#else
#include <cstddef>
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) && \
defined(__STL_CONFIG_H)
#define BOOST_CONTAINER_FWD_BAD_BITSET
#if !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
#define BOOST_CONTAINER_FWD_BAD_DEQUE
#endif
#endif
#if defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
#include <deque>
#endif
#if defined(BOOST_CONTAINER_FWD_BAD_BITSET)
#include <bitset>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4099) // struct/class mismatch in fwd declarations
#endif
namespace std
{
template <class T> class allocator;
template <class charT, class traits, class Allocator> class basic_string;
template <class charT> struct BOOST_HASH_CHAR_TRAITS;
template <class T> class complex;
}
// gcc 3.4 and greater
namespace std
{
#if !defined(BOOST_CONTAINER_FWD_BAD_DEQUE)
template <class T, class Allocator> class deque;
#endif
template <class T, class Allocator> class list;
template <class T, class Allocator> class vector;
template <class Key, class T, class Compare, class Allocator> class map;
template <class Key, class T, class Compare, class Allocator>
class multimap;
template <class Key, class Compare, class Allocator> class set;
template <class Key, class Compare, class Allocator> class multiset;
#if !defined(BOOST_CONTAINER_FWD_BAD_BITSET)
template <size_t N> class bitset;
#endif
template <class T1, class T2> struct pair;
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif
#endif

View File

@@ -0,0 +1,154 @@
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP)
#define BOOST_FUNCTIONAL_DETAIL_FLOAT_FUNCTIONS_HPP
#include <cmath>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// Some of this is based on guess work. If I don't know any better I assume that
// the standard C++ overloaded functions are available. If they're not then this
// means that the argument is cast to a double and back, which is inefficient
// and will give pretty bad results for long doubles - so if you know better
// let me know.
// STLport:
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# if (defined(__GNUC__) && __GNUC__ < 3 && (defined(linux) || defined(__linux) || defined(__linux__))) || defined(__DMC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# elif defined(BOOST_MSVC) && BOOST_MSVC < 1300
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
// Roguewave:
//
// On borland 5.51, with roguewave 2.1.1 the standard C++ overloads aren't
// defined, but for the same version of roguewave on sunpro they are.
#elif defined(_RWSTD_VER)
# if defined(__BORLANDC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# define BOOST_HASH_C99_NO_FLOAT_FUNCS
# elif defined(__DECCXX)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
// libstdc++ (gcc 3.0 onwards, I think)
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
// SGI:
#elif defined(__STL_CONFIG_H)
# if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# endif
// Dinkumware.
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Overloaded float functions were probably introduced in an earlier version
// than this.
# if defined(_CPPLIB_VER) && (_CPPLIB_VER >= 402)
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
# else
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
# endif
// Digital Mars
#elif defined(__DMC__)
# define BOOST_HASH_USE_C99_FLOAT_FUNCS
// Use overloaded float functions by default.
#else
# define BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#endif
namespace boost
{
namespace hash_detail
{
inline float call_ldexp(float v, int exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
return ldexp(v, exp);
#else
return ldexpf(v, exp);
#endif
}
inline double call_ldexp(double v, int exp)
{
using namespace std;
return ldexp(v, exp);
}
inline long double call_ldexp(long double v, int exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
return ldexp(v, exp);
#else
return ldexpl(v, exp);
#endif
}
inline float call_frexp(float v, int* exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS) || \
defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
return frexp(v, exp);
#else
return frexpf(v, exp);
#endif
}
inline double call_frexp(double v, int* exp)
{
using namespace std;
return frexp(v, exp);
}
inline long double call_frexp(long double v, int* exp)
{
using namespace std;
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
return frexp(v, exp);
#else
return frexpl(v, exp);
#endif
}
}
}
#if defined(BOOST_HASH_USE_C99_FLOAT_FUNCS)
#undef BOOST_HASH_USE_C99_FLOAT_FUNCS
#endif
#if defined(BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS)
#undef BOOST_HASH_USE_OVERLOAD_FLOAT_FUNCS
#endif
#if defined(BOOST_HASH_C99_NO_FLOAT_FUNCS)
#undef BOOST_HASH_C99_NO_FLOAT_FUNCS
#endif
#endif

View File

@@ -0,0 +1,123 @@
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER)
#define BOOST_FUNCTIONAL_DETAIL_HASH_FLOAT_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/functional/detail/float_functions.hpp>
#include <boost/limits.hpp>
#include <boost/assert.hpp>
#include <errno.h>
// Don't use fpclassify or _fpclass for stlport.
#if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
# if defined(__GLIBCPP__) || defined(__GLIBCXX__)
// GNU libstdc++ 3
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY
# endif
# elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library, on Visual C++
# if defined(BOOST_MSVC)
# define BOOST_HASH_USE_FPCLASS
# endif
# endif
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
template <class T>
inline std::size_t float_hash_impl(T v)
{
int exp = 0;
errno = 0;
v = boost::hash_detail::call_frexp(v, &exp);
if(errno) return 0;
std::size_t seed = 0;
std::size_t const length
= (std::numeric_limits<T>::digits +
std::numeric_limits<int>::digits - 1)
/ std::numeric_limits<int>::digits;
for(std::size_t i = 0; i < length; ++i)
{
v = boost::hash_detail::call_ldexp(v, std::numeric_limits<int>::digits);
int const part = static_cast<int>(v);
v -= part;
hash_float_combine(seed, part);
}
hash_float_combine(seed, exp);
return seed;
}
template <class T>
inline std::size_t float_hash_value(T v)
{
#if defined(BOOST_HASH_USE_FPCLASSIFY)
using namespace std;
switch (fpclassify(v)) {
case FP_ZERO:
return 0;
case FP_INFINITE:
return (std::size_t)(v > 0 ? -1 : -2);
case FP_NAN:
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v);
default:
BOOST_ASSERT(0);
return 0;
}
#elif defined(BOOST_HASH_USE_FPCLASS)
switch(_fpclass(v)) {
case _FPCLASS_NZ:
case _FPCLASS_PZ:
return 0;
case _FPCLASS_PINF:
return (std::size_t)(-1);
case _FPCLASS_NINF:
return (std::size_t)(-2);
case _FPCLASS_SNAN:
case _FPCLASS_QNAN:
return (std::size_t)(-3);
case _FPCLASS_NN:
case _FPCLASS_ND:
return float_hash_impl(v);
case _FPCLASS_PD:
case _FPCLASS_PN:
return float_hash_impl(v);
default:
BOOST_ASSERT(0);
return 0;
}
#else
return float_hash_impl(v);
#endif
}
}
}
#endif

View File

@@ -1,6 +1,10 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/container_hash/hash.hpp>
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#include <boost/functional/hash/hash.hpp>

View File

@@ -1,6 +0,0 @@
// 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)
#include <boost/container_hash/extensions.hpp>

View File

@@ -1,6 +1,592 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/functional/hash_fwd.hpp>
#include <functional>
#include <boost/functional/detail/hash_float.hpp>
#include <boost/functional/detail/container_fwd.hpp>
#include <string>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#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
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
// Borland complains about an ambiguous function overload
// when compiling boost::hash<bool>.
std::size_t hash_value(bool);
#endif
std::size_t hash_value(int);
std::size_t hash_value(unsigned int);
std::size_t hash_value(long);
std::size_t hash_value(unsigned long);
#if defined(BOOST_MSVC) && defined(_WIN64)
// On 64-bit windows std::size_t is a typedef for unsigned long long, which
// isn't due to be supported until Boost 1.35. So add support here.
// (Technically, Boost.Hash isn't actually documented as supporting
// std::size_t. But it would be pretty silly not to).
std::size_t hash_value(std::size_t);
#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 (&array)[N]);
template< class T, unsigned N >
std::size_t hash_value(T (&array)[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&);
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);
// Implementation
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
inline std::size_t hash_value(bool v)
{
return static_cast<std::size_t>(v);
}
#endif
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(_M_X64) && defined(_WIN64)
inline std::size_t hash_value(long long v)
{
return v;
}
inline std::size_t hash_value(unsigned long long v)
{
return 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 (&array)[N])
{
return hash_range(array, array + N);
}
template< class T, unsigned N >
inline std::size_t hash_value(T (&array)[N])
{
return hash_range(array, array + 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);
}
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());
}
//
// boost::hash
//
#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
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
#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 \
{ \
return boost::hash_value(v); \
} \
};
#else
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
{
return boost::hash_value(val);
}
};
};
}
template <class T> struct hash
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
////////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
namespace boost
{
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
{
template <bool IsArray>
struct call_hash_impl
{
template <class T>
struct inner
{
static std::size_t call(T const& v)
{
using namespace boost;
return hash_value(v);
}
};
};
template <>
struct call_hash_impl<true>
{
template <class Array>
struct inner
{
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
static std::size_t call(Array const& v)
#else
static std::size_t call(Array& v)
#endif
{
const int size = sizeof(v) / sizeof(*v);
return boost::hash_range(v, v + size);
}
};
};
template <class T>
struct call_hash
: public call_hash_impl<boost::is_array<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: std::unary_function<T, std::size_t>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
#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.
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
// There's probably a more elegant way to Visual C++ 6.5 to work
// but I don't know what it is.
template <bool IsConst>
struct hash_impl_msvc
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T const>::call(val);
}
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <>
struct hash_impl_msvc<true>
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <class T>
struct hash_impl_msvc2
: public hash_impl_msvc<boost::is_const<T>::value>
::BOOST_NESTED_TEMPLATE inner<T> {};
template <>
struct hash_impl<false>
{
template <class T>
struct inner : public hash_impl_msvc2<T> {};
};
#endif // Visual C++ 6.5
}
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
#endif
#include <boost/container_hash/hash.hpp>

View File

@@ -1,6 +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/container_hash/hash_fwd.hpp>

View File

@@ -1,6 +1,40 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/container_hash/hash_fwd.hpp>
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <cstddef>
#include <boost/detail/workaround.hpp>
namespace boost
{
template <class T> struct hash;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T> void hash_combine(std::size_t& seed, T& v);
#else
template <class T> void hash_combine(std::size_t& seed, T const& v);
#endif
template <class It> std::size_t hash_range(It, It);
template <class It> void hash_range(std::size_t&, It, It);
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T> inline std::size_t hash_range(T*, T*);
template <class T> inline void hash_range(std::size_t&, T*, T*);
#endif
}
#endif

View File

@@ -1,6 +1,6 @@
<!--
Copyright 2005-2007 Daniel James.
Copyright 2005-2006 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)
-->

View File

@@ -1,96 +0,0 @@
<?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&lt;T[N]&gt;, 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>

View File

@@ -1,21 +0,0 @@
[
{
"key": "container_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"
],
"cxxstd": "03"
}
]

View File

@@ -1,34 +1,23 @@
# 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)
# Copyright Daniel James 2005-2006. Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
import testing ;
project hash-tests
: requirements
<warnings>pedantic
<toolset>intel:<warnings>on
<toolset>gcc:<cxxflags>"-Wstrict-aliasing -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>darwin:<cxxflags>"-Wstrict-aliasing -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>clang:<cxxflags>"-Wstrict-aliasing -Wsign-promo -Wunused-parameter -Wsign-conversion -Wconversion -Wfloat-equal -Wshadow"
<toolset>msvc:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
<toolset>gcc:<define>_GLIBCXX_DEBUG
;
test-suite container_hash/hash
test-suite functional/hash
:
[ run hash_info.cpp : : : <test-info>always_show_run_output ]
[ compile check_float_funcs.cpp ]
[ run hash_fwd_test_1.cpp ]
[ run hash_fwd_test_2.cpp ]
[ run hash_number_test.cpp ]
[ run hash_enum_test.cpp ]
[ run hash_pointer_test.cpp ]
[ run hash_function_pointer_test.cpp ]
[ run hash_float_test.cpp ]
[ run hash_long_double_test.cpp ]
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_string_test.cpp ]
[ run hash_range_test.cpp ]
[ run hash_custom_test.cpp ]
@@ -41,48 +30,12 @@ test-suite container_hash/hash
[ run hash_deque_test.cpp ]
[ run hash_set_test.cpp ]
[ run hash_map_test.cpp ]
[ run hash_complex_test.cpp ]
[ run hash_optional_test.cpp ]
[ run hash_variant_test.cpp ]
[ run hash_type_index_test.cpp ]
[ run hash_system_error_test.cpp ]
[ run hash_std_array_test.cpp ]
[ run hash_std_tuple_test.cpp ]
[ run hash_std_smart_ptr_test.cpp ]
[ run link_test.cpp link_test_2.cpp ]
[ run link_ext_test.cpp link_no_ext_test.cpp ]
[ run extensions_hpp_test.cpp ]
[ run container_fwd_test.cpp ]
[ compile-fail hash_no_ext_fail_test.cpp ]
[ compile-fail namespace_fail_test.cpp ]
[ run implicit_test.cpp ]
[ run hash_no_ext_macro_1.cpp ]
[ run hash_no_ext_macro_2.cpp ]
;
test-suite container_hash/hash_no_ext
:
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
;
# Tests to see if the floating point hash is using the binary hash.
# Not run normally because on some platforms these should fail.
test-suite 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 ;
run hash_reference_values.cpp ;

View File

@@ -1,63 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if defined(__GNUC__)
// in type_traits/is_complete.hpp:47
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#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
}

View File

@@ -1,20 +1,16 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
template <class T>
void compile_time_tests(T*)
{
BOOST_STATIC_ASSERT((boost::is_same<T,
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::argument_type
>::value));
BOOST_STATIC_ASSERT((boost::is_same<std::size_t,
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::result_type
>::value));
}
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
};

View File

@@ -1,25 +1,14 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if defined(BOOST_HASH_TEST_STD)
# define BOOST_HASH_TEST_STD_INCLUDES
# define BOOST_HASH_TEST_NAMESPACE std
#if defined(TEST_STD)
# define TEST_STD_INCLUDES
# define HASH_NAMESPACE std::tr1
#else
# define BOOST_HASH_TEST_NAMESPACE boost
# define HASH_NAMESPACE boost
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_TEST_EXTENSIONS
# define TEST_EXTENSIONS
# endif
#endif
#if defined(_WIN32_WCE)
// The standard windows mobile headers trigger this warning so I disable it
// before doing anything else.
#pragma warning(disable:4201) // nonstandard extension used :
// nameless struct/union
#endif
#define HASH_TEST_CAT(x, y) HASH_TEST_CAT2(x, y)
#define HASH_TEST_CAT2(x, y) x##y

109
test/container_fwd_test.cpp Normal file
View File

@@ -0,0 +1,109 @@
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/detail/container_fwd.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
{
}
#else
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
{
}
#endif
template <class T, class Allocator>
static void test(std::deque<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::list<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::vector<T, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::map<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::multimap<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::set<Key, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::multiset<Key, Compare, Allocator> const&)
{
}
template <std::size_t N>
static void test(std::bitset<N> const&)
{
}
template <class T>
static void test(std::complex<T> const&)
{
}
template <class X, class Y>
static void test(std::pair<X, Y> const&)
{
}
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#include <utility>
int main()
{
std::deque<int> x1;
std::list<std::string> x2;
std::vector<float> x3;
std::vector<bool> x4;
std::map<int, int> x5;
std::multimap<float, int*> x6;
std::set<std::string> x7;
std::multiset<std::vector<int> > x8;
std::bitset<10> x9;
std::string x10;
std::complex<double> x11;
std::pair<std::list<int>, char***> x12;
test(x1);
test(x2);
test(x3);
test(x4);
test(x5);
test(x6);
test(x7);
test(x8);
test(x9);
test(x10);
test(x11);
test(x12);
return 0;
}

View File

@@ -1,19 +0,0 @@
// Copyright 2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Check that boost/container_hash/extensions.hpp works okay.
//
// It probably should be in boost/container_hash/detail, but since it isn't it
// should work.
#include "./config.hpp"
#include <boost/container_hash/extensions.hpp>
int main() {
int x[2] = { 2, 3 };
boost::hash<int[2]> hf;
hf(x);
}

View File

@@ -1,21 +1,21 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
void array_int_test()
{
@@ -27,47 +27,47 @@ void array_int_test()
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
HASH_NAMESPACE::hash<int[25]> hasher1;
const int length2 = 1;
int array2[1] = {3};
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
HASH_NAMESPACE::hash<int[1]> hasher2;
const int length3 = 2;
int array3[2] = {2, 3};
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1)
== BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
BOOST_TEST(hasher2(array2)
== BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
BOOST_TEST(hasher3(array3)
== BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
HASH_NAMESPACE::hash<int[3][2]> hasher;
std::size_t seed1 = 0;
for(int i = 0; i < 3; ++i)
{
std::size_t seed2 = 0;
for(int j = 0; j < 2; ++j)
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
HASH_NAMESPACE::hash_combine(seed1, seed2);
}
BOOST_TEST(hasher(array) == seed1);
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
}
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif

View File

@@ -1,110 +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 "./config.hpp"
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
#endif
#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(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <complex>
#include <sstream>
#include <boost/limits.hpp>
template <class T>
void generic_complex_tests(std::complex<T> v)
{
BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
T real = v.real();
T imag = v.imag();
BOOST_TEST(real_hasher(real) == complex_hasher(std::complex<T>(real)));
if(imag != 0 && real_hasher(real) == complex_hasher(v)) {
std::ostringstream os;
os<<"real_hasher("<<real<<") == complex_hasher("
<<v.real()<<" + "<<v.imag()<<"i) == "
<<real_hasher(real)<<" (This might not be a bug).";
BOOST_ERROR(os.str().c_str());
}
}
template <class Float>
void complex_float_tests(Float*)
{
typedef std::complex<Float> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
}
template <class Integer>
void complex_integral_tests(Integer*)
{
typedef std::complex<Integer> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(15342,124));
generic_complex_tests(complex(25,54356));
generic_complex_tests(complex(5325,2346));
generic_complex_tests(complex(Integer(-243897),Integer(-49923874)));
generic_complex_tests(complex(Integer(-543),Integer(763)));
}
int main()
{
// I've comments out the short and unsigned short tests
// as they cause warnings and don't really test
// anything that the other tests already deal with.
complex_float_tests((float*) 0);
complex_float_tests((double*) 0);
complex_float_tests((long double*) 0);
//complex_integral_tests((short*) 0);
complex_integral_tests((int*) 0);
complex_integral_tests((long*) 0);
//complex_integral_tests((unsigned short*) 0);
complex_integral_tests((unsigned int*) 0);
complex_integral_tests((unsigned long*) 0);
return boost::report_errors();
}
#endif // BOOST_HASH_TEST_EXTENSIONS

View File

@@ -1,9 +1,8 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
@@ -15,7 +14,7 @@ namespace test
std::size_t hash() const
{
return static_cast<std::size_t>(value_ * 10);
return value_ * 10;
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -41,17 +40,17 @@ namespace boost
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -59,13 +58,13 @@ namespace boost
void custom_tests()
{
BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
HASH_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace BOOST_HASH_TEST_NAMESPACE;
using namespace HASH_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -75,25 +74,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
std::size_t seed2 = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -1,21 +1,21 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <deque>
@@ -23,11 +23,11 @@ using std::deque;
#define CONTAINER_TYPE deque
#include "./hash_sequence_test.hpp"
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
deque_tests::deque_hash_integer_tests();
#endif

View File

@@ -1,63 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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();
}

View File

@@ -1,18 +1,228 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "hash_float_test.hpp"
#include "./config.hpp"
int main()
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <cmath>
#include <boost/limits.hpp>
#include <iostream>
template <class T>
void float_tests(char const* name, T* = 0)
{
std::cerr<<"\n"
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n"
<<"\n"
<<"std::numeric_limits<T>::digits = "
<<std::numeric_limits<T>::digits<<"\n"
<<"std::numeric_limits<int>::digits = "
<<std::numeric_limits<int>::digits<<"\n"
<<"std::numeric_limits<std::size_t>::digits = "
<<std::numeric_limits<std::size_t>::digits<<"\n"
<<"\n"
;
HASH_NAMESPACE::hash<T> x1;
T zero = 0;
T minus_zero = (T) -1 * zero;
BOOST_TEST(zero == minus_zero);
BOOST_TEST(x1(zero) == x1(minus_zero));
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
using namespace std;
// Doing anything with infinity causes borland to crash.
#if defined(__BORLANDC__)
std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n";
#else
if(std::numeric_limits<T>::has_infinity) {
T infinity = -log(zero);
T infinity2 = (T) 1. / zero;
T infinity3 = (T) -1. / minus_zero;
T infinity4 = std::numeric_limits<T>::infinity();
T minus_infinity = log(zero);
T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero;
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity));
if(infinity == infinity2)
BOOST_TEST(x1(infinity) == x1(infinity2));
if(infinity == infinity3);
BOOST_TEST(x1(infinity) == x1(infinity3));
if(infinity == infinity4)
BOOST_TEST(x1(infinity) == x1(infinity4));
if(minus_infinity == minus_infinity2)
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
if(minus_infinity == minus_infinity3)
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
BOOST_TEST(infinity != minus_infinity);
if(x1(infinity) == x1(minus_infinity)) {
std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
}
// This should really be 'has_denorm == denorm_present' but some
// compilers don't have 'denorm_present'. See also a later use.
if(std::numeric_limits<T>::has_denorm) {
if(x1(std::numeric_limits<T>::denorm_min()) == x1(infinity)) {
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n";
}
if(x1(std::numeric_limits<T>::denorm_min()) == x1(minus_infinity)) {
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
}
}
if(std::numeric_limits<T>::has_quiet_NaN) {
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(infinity)) {
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n";
}
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(minus_infinity)) {
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n";
}
}
}
#endif
T max = (std::numeric_limits<T>::max)();
T half_max = max / 2;
T quarter_max = max / 4;
T three_quarter_max = max - quarter_max;
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
// The '!=' tests could legitimately fail, but with my hash it indicates a bug.
BOOST_TEST(x1(max) == x1(max));
BOOST_TEST(x1(max) != x1(quarter_max));
BOOST_TEST(x1(max) != x1(half_max));
BOOST_TEST(x1(max) != x1(three_quarter_max));
BOOST_TEST(x1(quarter_max) == x1(quarter_max));
BOOST_TEST(x1(quarter_max) != x1(half_max));
BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
BOOST_TEST(x1(half_max) == x1(half_max));
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
defined(__ICC) || defined(__ECC)) && \
(defined(__GLIBCPP__) || defined(__GLIBCXX__)))
T v1 = asin((T) 1);
T v2 = acos((T) 0);
if(v1 == v2)
BOOST_TEST(x1(v1) == x1(v2));
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
#endif
BOOST_TEST(x1(std::numeric_limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::epsilon()));
BOOST_TEST(std::numeric_limits<T>::epsilon() != (T) 0);
if(x1(std::numeric_limits<T>::epsilon()) == x1((T) 0))
std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
BOOST_TEST(-std::numeric_limits<T>::epsilon() != (T) 0);
if(x1(-std::numeric_limits<T>::epsilon()) == x1((T) 0))
std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
BOOST_TEST((T) 1 + std::numeric_limits<T>::epsilon() != (T) 1);
if(x1((T) 1 + std::numeric_limits<T>::epsilon()) == x1((T) 1))
std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
BOOST_TEST((T) 1 - std::numeric_limits<T>::epsilon() != (T) 1);
if(x1((T) 1 - std::numeric_limits<T>::epsilon()) == x1((T) 1))
std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
BOOST_TEST((T) -1 + std::numeric_limits<T>::epsilon() != (T) -1);
if(x1((T) -1 + std::numeric_limits<T>::epsilon()) == x1((T) -1))
std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
BOOST_TEST((T) -1 - std::numeric_limits<T>::epsilon() != (T) -1);
if(x1((T) -1 - std::numeric_limits<T>::epsilon()) == x1((T) -1))
std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
// As before.
if(std::numeric_limits<T>::has_denorm) {
if(x1(std::numeric_limits<T>::denorm_min()) == x1(zero)) {
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
}
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of std::numeric_limits::denorm_min() for long
// doubles which causes this test to fail.
if(x1(std::numeric_limits<T>::denorm_min()) !=
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::denorm_min()))
{
std::cerr<<"x1(std::numeric_limits<T>::denorm_min()) = "
<< x1(std::numeric_limits<T>::denorm_min())
<< "\nhash_value(std::numeric_limits<T>::denorm_min()) = "
<< HASH_NAMESPACE::hash_value(
std::numeric_limits<T>::denorm_min())
<< "\nx1(0) = "<<x1(0)<<"\n";
}
#endif
}
// NaN also causes borland to crash.
#if !defined(__BORLANDC__)
if(std::numeric_limits<T>::has_quiet_NaN) {
if(x1(std::numeric_limits<T>::quiet_NaN()) == x1(1.0)) {
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
}
BOOST_TEST(x1(std::numeric_limits<T>::quiet_NaN()) ==
HASH_NAMESPACE::hash_value(std::numeric_limits<T>::quiet_NaN()));
}
#endif
}
void hash_float_tests()
{
std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
float_tests("float", (float*) 0);
}
void hash_double_tests()
{
float_tests("double", (double*) 0);
}
void hash_long_double_tests()
{
float_tests("long double", (long double*) 0);
}
int main()
{
hash_float_tests();
hash_double_tests();
hash_long_double_tests();
return boost::report_errors();
}

View File

@@ -1,309 +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 "./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 <cmath>
#include <boost/container_hash/detail/limits.hpp>
#include <boost/container_hash/detail/float_functions.hpp>
#include <boost/config/workaround.hpp>
#include <iostream>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4723) // conditional expression is constant
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if ( defined(__GNUC__) || defined(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
char const* float_type(float*) { return "float"; }
char const* float_type(double*) { return "double"; }
char const* float_type(long double*) { return "long double"; }
template <class T>
void float_tests(char const* name, T* = 0)
{
std::cerr
<< "\n"
<< "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
<< name
<< ">\n"
<< "\n"
<< "boost::hash_detail::limits<T>::digits = "
<< boost::hash_detail::limits<T>::digits<< "\n"
<< "boost::hash_detail::limits<int>::digits = "
<< boost::hash_detail::limits<int>::digits<< "\n"
<< "boost::hash_detail::limits<std::size_t>::digits = "
<< boost::hash_detail::limits<std::size_t>::digits
<< "\n"
<< "\n"
<< "boost::hash_detail::call_ldexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_ldexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::call_frexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_frexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::select_hash_type<T>::type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::select_hash_type<T>::type*>(0))
<< "\n"
<< "\n"
;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
T zero = 0;
T minus_zero = (T) -1 * zero;
BOOST_TEST(zero == minus_zero);
BOOST_TEST(x1(zero) == x1(minus_zero));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
#endif
BOOST_TEST(x1(zero) != x1(0.5));
BOOST_TEST(x1(minus_zero) != x1(0.5));
BOOST_TEST(x1(0.5) != x1(-0.5));
BOOST_TEST(x1(1) != x1(-1));
using namespace std;
// Doing anything with infinity causes borland to crash.
#if defined(BOOST_BORLANDC)
std::cerr
<< "Not running infinity checks on Borland, as it causes it to crash."
"\n";
#else
if(boost::hash_detail::limits<T>::has_infinity) {
T infinity = -log(zero);
T infinity2 = (T) 1. / zero;
T infinity3 = (T) -1. / minus_zero;
T infinity4 = boost::hash_detail::limits<T>::infinity();
T minus_infinity = log(zero);
T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero;
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
#endif
if(infinity == infinity2)
BOOST_TEST(x1(infinity) == x1(infinity2));
if(infinity == infinity3)
BOOST_TEST(x1(infinity) == x1(infinity3));
if(infinity == infinity4)
BOOST_TEST(x1(infinity) == x1(infinity4));
if(minus_infinity == minus_infinity2)
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity2));
if(minus_infinity == minus_infinity3)
BOOST_TEST(x1(minus_infinity) == x1(minus_infinity3));
BOOST_TEST(infinity != minus_infinity);
if(x1(infinity) == x1(minus_infinity)) {
std::cerr<<"x1(infinity) == x1(-infinity) == "<<x1(infinity)<<"\n";
}
// This should really be 'has_denorm == denorm_present' but some
// compilers don't have 'denorm_present'. See also a later use.
if(boost::hash_detail::limits<T>::has_denorm) {
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
{
std::cerr
<< "x1(denorm_min) == x1(infinity) == "
<< x1(infinity)
<< "\n";
}
if(x1(boost::hash_detail::limits<T>::denorm_min()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(denorm_min) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
}
}
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
{
std::cerr
<< "x1(quiet_NaN) == x1(infinity) == "
<< x1(infinity)
<< "\n";
}
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(quiet_NaN) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
}
}
}
#endif
T max = (boost::hash_detail::limits<T>::max)();
T half_max = max / 2;
T quarter_max = max / 4;
T three_quarter_max = max - quarter_max;
// Check the limits::max is in range.
BOOST_TEST(max != half_max);
BOOST_TEST(max != quarter_max);
BOOST_TEST(max != three_quarter_max);
BOOST_TEST(half_max != quarter_max);
BOOST_TEST(half_max != three_quarter_max);
BOOST_TEST(quarter_max != three_quarter_max);
BOOST_TEST(max != -max);
BOOST_TEST(half_max != -half_max);
BOOST_TEST(quarter_max != -quarter_max);
BOOST_TEST(three_quarter_max != -three_quarter_max);
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
#endif
// The '!=' tests could legitimately fail, but with my hash it indicates a
// bug.
BOOST_TEST(x1(max) == x1(max));
BOOST_TEST(x1(max) != x1(quarter_max));
BOOST_TEST(x1(max) != x1(half_max));
BOOST_TEST(x1(max) != x1(three_quarter_max));
BOOST_TEST(x1(quarter_max) == x1(quarter_max));
BOOST_TEST(x1(quarter_max) != x1(half_max));
BOOST_TEST(x1(quarter_max) != x1(three_quarter_max));
BOOST_TEST(x1(half_max) == x1(half_max));
BOOST_TEST(x1(half_max) != x1(three_quarter_max));
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
BOOST_TEST(x1(max) != x1(-max));
BOOST_TEST(x1(half_max) != x1(-half_max));
BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
defined(__ICC) || defined(__ECC)) && \
(defined(__GLIBCPP__) || defined(__GLIBCXX__)))
T v1 = asin((T) 1);
T v2 = acos((T) 0);
if(v1 == v2)
BOOST_TEST(x1(v1) == x1(v2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
#endif
#endif
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::epsilon()));
#endif
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
if(x1(boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
std::cerr<<"x1(epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
BOOST_TEST(-boost::hash_detail::limits<T>::epsilon() != (T) 0);
if(x1(-boost::hash_detail::limits<T>::epsilon()) == x1((T) 0))
std::cerr<<"x1(-epsilon) == x1(0) == "<<x1((T) 0)<<"\n";
BOOST_TEST((T) 1 + boost::hash_detail::limits<T>::epsilon() != (T) 1);
if(x1((T) 1 + boost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
std::cerr<<"x1(1 + epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
BOOST_TEST((T) 1 - boost::hash_detail::limits<T>::epsilon() != (T) 1);
if(x1((T) 1 - boost::hash_detail::limits<T>::epsilon()) == x1((T) 1))
std::cerr<<"x1(1 - epsilon) == x1(1) == "<<x1((T) 1)<<"\n";
BOOST_TEST((T) -1 + boost::hash_detail::limits<T>::epsilon() != (T) -1);
if(x1((T) -1 + boost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
std::cerr<<"x1(-1 + epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
BOOST_TEST((T) -1 - boost::hash_detail::limits<T>::epsilon() != (T) -1);
if(x1((T) -1 - boost::hash_detail::limits<T>::epsilon()) == x1((T) -1))
std::cerr<<"x1(-1 - epsilon) == x1(-1) == "<<x1((T) -1)<<"\n";
// As before.
if(boost::hash_detail::limits<T>::has_denorm) {
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
}
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of boost::hash_detail::limits::denorm_min() for long
// doubles which causes this test to fail.
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()))
{
std::cerr
<< "x1(boost::hash_detail::limits<T>::denorm_min()) = "
<< x1(boost::hash_detail::limits<T>::denorm_min())
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
" = "
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "
<< x1(0)
<< "\n";
}
#endif
}
// NaN also causes borland to crash.
#if !defined(BOOST_BORLANDC) && defined(BOOST_HASH_TEST_EXTENSIONS)
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
}
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
}
#endif
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

View File

@@ -1,9 +1,7 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#include <cstddef>
@@ -17,7 +15,7 @@ namespace test
std::size_t hash() const
{
return static_cast<std::size_t>(value_ * 10);
return value_ * 10;
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -44,17 +42,17 @@ namespace boost
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -62,13 +60,13 @@ namespace boost
void custom_tests()
{
BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom<int> x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace BOOST_HASH_TEST_NAMESPACE;
using namespace HASH_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -78,25 +76,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
std::size_t seed2 = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -1,17 +1,22 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void void_func1() { static int x = 1; ++x; }
@@ -24,8 +29,8 @@ void function_pointer_tests()
compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0);
BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
HASH_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_TEST(&void_func1 != &void_func2);
BOOST_TEST(&int_func1 != &int_func2);
@@ -38,11 +43,11 @@ void function_pointer_tests()
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
#if defined(TEST_EXTENSIONS)
BOOST_TEST(hasher_void(&void_func1)
== BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
== HASH_NAMESPACE::hash_value(&void_func1));
BOOST_TEST(hasher_int(&int_func1)
== BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
== HASH_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal:
BOOST_TEST(hasher_void(0) == 0);

View File

@@ -1,12 +1,12 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/container_hash/hash_fwd.hpp>
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#include <boost/functional/hash_fwd.hpp>
#include <boost/config.hpp>
#include <cstddef>
@@ -25,7 +25,7 @@ namespace test {
template <class T>
std::size_t hash_value(test_type1<T> const& x)
{
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
HASH_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
#endif
@@ -42,8 +42,8 @@ namespace test {
std::size_t hash_value(test_type2<T> const& x)
{
std::size_t seed = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
#endif
@@ -60,9 +60,8 @@ namespace test {
template <class T>
std::size_t hash_value(test_type3<T> const& x)
{
std::size_t seed =
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
#endif
@@ -76,7 +75,7 @@ namespace boost
template <class T>
std::size_t hash_value(test::test_type1<T> const& x)
{
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
HASH_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
@@ -84,17 +83,16 @@ namespace boost
std::size_t hash_value(test::test_type2<T> const& x)
{
std::size_t seed = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
template <class T>
std::size_t hash_value(test::test_type3<T> const& x)
{
std::size_t seed =
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());
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
}

View File

@@ -1,19 +1,17 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This checks that template code implemented using hash_fwd will work.
#include "./config.hpp"
#include "./hash_fwd_test.hpp"
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
#include <string>
void fwd_test1()
@@ -21,10 +19,10 @@ void fwd_test1()
test::test_type1<int> x(5);
test::test_type1<std::string> y("Test");
BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
HASH_NAMESPACE::hash<int> hasher_int;
HASH_NAMESPACE::hash<std::string> hasher_string;
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
@@ -36,15 +34,15 @@ void fwd_test2()
test::test_type2<std::string> y("Test1", "Test2");
std::size_t seed1 = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
HASH_NAMESPACE::hash_combine(seed1, 5);
HASH_NAMESPACE::hash_combine(seed1, 10);
std::size_t seed2 = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -68,16 +66,14 @@ void fwd_test3()
test::test_type3<int> x(values1.begin(), values1.end());
test::test_type3<std::string> y(values2.begin(), values2.end());
std::size_t seed1 =
BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 =
BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -87,10 +83,11 @@ void fwd_test3()
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
fwd_test1();
fwd_test2();
fwd_test3();
#endif
return boost::report_errors();
}

View File

@@ -1,21 +1,14 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This test just makes sure a header which uses hash_fwd can compile without
// the main hash headers.
#include "./config.hpp"
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
int main() {}
#else
#include "./hash_fwd_test.hpp"
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
template <class T> void unused(T const&) {}
@@ -37,11 +30,10 @@ void fwd_test()
unused(y1); unused(y2); unused(y3);
}
int main()
{
fwd_test();
return boost::report_errors();
}
#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)

View File

@@ -1,13 +1,11 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
// in the global namespace.
#include "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
@@ -17,7 +15,7 @@ struct custom
std::size_t hash() const
{
return static_cast<std::size_t>(value_ * 10);
return value_ * 10;
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -42,17 +40,17 @@ namespace boost
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -60,13 +58,13 @@ namespace boost
void custom_tests()
{
BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
HASH_NAMESPACE::hash<custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace BOOST_HASH_TEST_NAMESPACE;
using namespace HASH_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -76,26 +74,26 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
HASH_NAMESPACE::hash_combine(seed, custom(5));
HASH_NAMESPACE::hash_combine(seed, custom(25));
HASH_NAMESPACE::hash_combine(seed, custom(35));
std::size_t seed2 = 0;
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -1,102 +0,0 @@
// 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
}

View File

@@ -1,21 +1,21 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <list>
@@ -23,11 +23,11 @@ using std::list;
#define CONTAINER_TYPE list
#include "./hash_sequence_test.hpp"
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
list_tests::list_hash_integer_tests();
#endif

View File

@@ -1,17 +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 "hash_float_test.hpp"
int main()
{
std::cerr<<"Compiler: "<<BOOST_COMPILER<<"\n";
std::cerr<<"Platform: "<<BOOST_PLATFORM<<"\n";
std::cerr<<"Library: "<<BOOST_STDLIB<<"\n\n";
float_tests("long double", (long double*) 0);
return boost::report_errors();
}

View File

@@ -1,23 +1,23 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <map>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
using std::map;
#define CONTAINER_TYPE map
@@ -27,11 +27,11 @@ using std::multimap;
#define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp"
#endif // BOOST_HASH_TEST_EXTENSIONS
#endif // TEST_EXTENSTIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
map_tests::map_hash_integer_tests();
multimap_tests::multimap_hash_integer_tests();
#endif

View File

@@ -1,51 +1,45 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'int' to 'float'
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
#include <boost/preprocessor/cat.hpp>
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
{
const int number_of_containers = 10;
T containers[number_of_containers];
typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
typedef BOOST_DEDUCED_TYPENAME T::key_type key;
typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
typedef typename T::value_type pair;
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j)
containers[i].insert(pair(key(0), value(0)));
containers[i].insert(pair(0, 0));
}
containers[6].insert(pair(key(1),value(0)));
containers[7].insert(pair(key(1),value(0)));
containers[7].insert(pair(key(1),value(0)));
containers[8].insert(pair(key(-1),value(1)));
containers[9].insert(pair(key(-1),value(3)));
containers[9].insert(pair(key(-1),value(3)));
containers[6].insert(pair(1,0));
containers[7].insert(pair(1,0));
containers[7].insert(pair(1,0));
containers[8].insert(pair(-1,1));
containers[9].insert(pair(-1,3));
containers[9].insert(pair(-1,3));
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
HASH_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== BOOST_HASH_TEST_NAMESPACE::hash_range(
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -57,7 +51,7 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
integer_tests((CONTAINER_TYPE<int, float>*) 0);
@@ -66,9 +60,5 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#undef CONTAINER_TYPE
#endif

View File

@@ -1,28 +1,19 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#define HASH_NAMESPACE boost
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
// (or at least one of them).
#if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
#endif
#define BOOST_HASH_NO_EXTENSIONS
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
#endif
template <class T> void ignore(T const&) {}
#include <boost/functional/hash.hpp>
#include <boost/functional/hash.hpp>
int main()
{
BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
HASH_NAMESPACE::hash< int[10] > hasher;
return 0;
}

View File

@@ -1,37 +1,25 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# if defined(BOOST_HASH_NO_EXTENSIONS)
# undef BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/container_hash/hash.hpp>
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# define BOOST_HASH_NO_EXTENSIONS
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#define HASH_NAMESPACE boost
#include <boost/functional/hash.hpp>
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <deque>
#include <cassert>
int main()
{
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::deque<int> x;
x.push_back(1);
x.push_back(2);
BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
HASH_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
return boost::report_errors();
}

View File

@@ -1,37 +1,25 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/container_hash/hash.hpp>
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# undef BOOST_HASH_NO_EXTENSIONS
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#define HASH_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#undef BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <map>
int main()
{
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::map<int, int> x;
x.insert(std::map<int, int>::value_type(53, -42));
x.insert(std::map<int, int>::value_type(14, -75));
BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
return boost::report_errors();
}

View File

@@ -1,68 +1,37 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
#endif
#include <iostream>
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/container_hash/detail/limits.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4309) // truncation of constant value
#pragma warning(disable:4310) // cast truncates constant value
#endif
#if ( defined(__GNUC__) || defined(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T>
void numeric_extra_tests(typename
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
typedef boost::hash_detail::limits<T> limits;
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
template <class T>
void numeric_extra_tests(typename
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
}
template <class T>
void numeric_test(T*)
{
typedef std::numeric_limits<T> limits;
compile_time_tests((T*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
T v1 = (T) -5;
T v1 = -5;
BOOST_TEST(x1(v1) == x2(v1));
BOOST_TEST(x1(T(-5)) == x2(T(-5)));
BOOST_TEST(x1(T(0)) == x2(T(0)));
@@ -71,25 +40,31 @@ void numeric_test(T*)
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
numeric_extra_tests<T>();
if (limits::is_integer)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
#endif
}
template <class T>
void limits_test(T*)
{
typedef boost::hash_detail::limits<T> limits;
typedef std::numeric_limits<T> limits;
if(limits::is_specialized)
{
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
T min_value = (limits::min)();
T max_value = (limits::max)();
@@ -97,15 +72,15 @@ void limits_test(T*)
BOOST_TEST(x1(min_value) == x2((limits::min)()));
BOOST_TEST(x1(max_value) == x2((limits::max)()));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
if (limits::is_integer)
{
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
== std::size_t(min_value));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
== std::size_t(max_value));
}
#endif
@@ -115,10 +90,10 @@ void limits_test(T*)
template <class T>
void poor_quality_tests(T*)
{
typedef boost::hash_detail::limits<T> limits;
typedef std::numeric_limits<T> limits;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
// A hash function can legally fail these tests, but it'll not be a good
// sign.
@@ -126,49 +101,25 @@ void poor_quality_tests(T*)
BOOST_TEST(x1(T(1)) != x2(T(-1)));
if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2)));
// 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));
}
if((limits::max)() != (limits::max)() - 1)
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1));
}
void bool_test()
{
BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
BOOST_TEST(x1(true) == x2(true));
BOOST_TEST(x1(false) == x2(false));
BOOST_TEST(x1(true) != x2(false));
BOOST_TEST(x1(false) != x2(true));
}
#define NUMERIC_TEST(type, name) \
std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
numeric_test((type*) 0); \
limits_test((type*) 0); \
poor_quality_tests((type*) 0);
#define NUMERIC_TEST_NO_LIMITS(type, name) \
std::cerr<<"Testing: " BOOST_STRINGIZE(name) "\n"; \
numeric_test((type*) 0); \
poor_quality_tests((type*) 0);
int main()
{
NUMERIC_TEST(bool, bool)
NUMERIC_TEST(char, char)
NUMERIC_TEST(signed char, schar)
NUMERIC_TEST(unsigned char, uchar)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
NUMERIC_TEST(wchar_t, wchar)
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
NUMERIC_TEST(char16_t, char16)
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
NUMERIC_TEST(char32_t, char32)
#endif
NUMERIC_TEST(short, short)
NUMERIC_TEST(unsigned short, ushort)
@@ -177,27 +128,11 @@ int main()
NUMERIC_TEST(long, hash_long)
NUMERIC_TEST(unsigned long, ulong)
#if !defined(BOOST_NO_LONG_LONG)
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
#endif
#if defined(BOOST_HAS_INT128)
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
#endif
NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double)
NUMERIC_TEST(std::size_t, size_t)
NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
bool_test();
NUMERIC_TEST(long double, ldouble)
return boost::report_errors();
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

View File

@@ -1,70 +0,0 @@
// 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();
}

View File

@@ -1,18 +1,22 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void pointer_tests()
@@ -20,8 +24,8 @@ void pointer_tests()
compile_time_tests((int**) 0);
compile_time_tests((void**) 0);
BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
HASH_NAMESPACE::hash<int*> x1;
HASH_NAMESPACE::hash<int*> x2;
int int1;
int int2;
@@ -29,9 +33,9 @@ void pointer_tests()
BOOST_TEST(x1(0) == x2(0));
BOOST_TEST(x1(&int1) == x2(&int1));
BOOST_TEST(x1(&int2) == x2(&int2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal:
BOOST_TEST(x1(0) == 0);

View File

@@ -1,24 +1,25 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector>
void hash_range_tests()
@@ -40,41 +41,41 @@ void hash_range_tests()
std::vector<int> x;
std::size_t x_seed = 0;
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10);
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
HASH_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
x.push_back(20);
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
HASH_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
std::size_t seed =
BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed ==
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
}
#endif
int main()
{
hash_range_tests();
@@ -82,4 +83,3 @@ int main()
return boost::report_errors();
}
#endif // TEST_EXTESNIONS

View File

@@ -1,495 +0,0 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/config/pragma_message.hpp>
#if defined(__GNUC__) && !defined(__clang__) && __cplusplus < 201100L
BOOST_PRAGMA_MESSAGE("Skipping test under GCC in C++98 mode")
int main() {}
#else
#if defined(__clang__)
# pragma clang diagnostic ignored "-Wlong-long"
#endif
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <string>
#include <vector>
#include <list>
#include <utility>
#include <complex>
#include <limits>
#include <climits>
#include <cfloat>
#include <cstddef>
// This test checks whether hash values have changed
template<class T> std::size_t hv( T const& t )
{
return boost::hash<T>()( t );
}
int main()
{
// char
BOOST_TEST_EQ( hv('\x00'), 0 );
BOOST_TEST_EQ( hv('A'), 'A' );
BOOST_TEST_EQ( hv('\x7F'), 0x7F );
// signed char
BOOST_TEST_EQ( hv((signed char)0), 0 );
BOOST_TEST_EQ( hv((signed char)+1), +1 );
BOOST_TEST_EQ( hv((signed char)-1), (std::size_t)-1 );
BOOST_TEST_EQ( hv((signed char)+127), 127 );
BOOST_TEST_EQ( hv((signed char)-128), (std::size_t)-128 );
// unsigned char
BOOST_TEST_EQ( hv((unsigned char)0), 0 );
BOOST_TEST_EQ( hv((unsigned char)1), 1 );
BOOST_TEST_EQ( hv((unsigned char)255), 255 );
// short
BOOST_TEST_EQ( hv((short)0), 0 );
BOOST_TEST_EQ( hv((short)+1), 1 );
BOOST_TEST_EQ( hv((short)-1), (std::size_t)-1 );
BOOST_TEST_EQ( hv((short)+32767), 32767 );
BOOST_TEST_EQ( hv((short)-32768), (std::size_t)-32768 );
// unsigned short
BOOST_TEST_EQ( hv((unsigned short)0), 0 );
BOOST_TEST_EQ( hv((unsigned short)1), 1 );
BOOST_TEST_EQ( hv((unsigned short)65535), 65535 );
// int
BOOST_TEST_EQ( hv(0), 0 );
BOOST_TEST_EQ( hv(+1), 1 );
BOOST_TEST_EQ( hv(-1), (std::size_t)-1 );
BOOST_TEST_EQ( hv(+32767), 32767 );
BOOST_TEST_EQ( hv(-32768), (std::size_t)-32768 );
// unsigned int
BOOST_TEST_EQ( hv((unsigned)0), 0 );
BOOST_TEST_EQ( hv((unsigned)1), 1 );
BOOST_TEST_EQ( hv((unsigned)65535), 65535 );
BOOST_TEST_EQ( hv((unsigned)-1), (std::size_t)(unsigned)-1 );
// long
BOOST_TEST_EQ( hv(0L), 0 );
BOOST_TEST_EQ( hv(+1L), 1 );
BOOST_TEST_EQ( hv(-1L), (std::size_t)-1 );
BOOST_TEST_EQ( hv(+32767L), 32767 );
BOOST_TEST_EQ( hv(-32768L), (std::size_t)-32768 );
// unsigned long
BOOST_TEST_EQ( hv(0UL), 0 );
BOOST_TEST_EQ( hv(1UL), 1 );
BOOST_TEST_EQ( hv(65535UL), 65535 );
BOOST_TEST_EQ( hv((unsigned long)-1), (std::size_t)(unsigned long)-1 );
// long long
BOOST_TEST_EQ( hv(0LL), 0 );
BOOST_TEST_EQ( hv(+1LL), 1 );
BOOST_TEST_EQ( hv(-1LL), (std::size_t)-1 );
BOOST_TEST_EQ( hv(+32767LL), 32767 );
BOOST_TEST_EQ( hv(-32768LL), (std::size_t)-32768 );
// unsigned long long
BOOST_TEST_EQ( hv(0ULL), 0 );
BOOST_TEST_EQ( hv(1ULL), 1 );
BOOST_TEST_EQ( hv(65535ULL), 65535 );
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv((unsigned long long)-1), 3221225537U );
#else
BOOST_TEST_EQ( hv((unsigned long long)-1), (std::size_t)-1 );
#endif
#if defined(BOOST_HAS_INT128)
typedef boost::int128_type int128;
BOOST_TEST_EQ( hv((int128)0), 0 );
BOOST_TEST_EQ( hv((int128)1), 1 );
BOOST_TEST_EQ( hv((int128)-1), (std::size_t)-1 );
BOOST_TEST_EQ( hv((int128)+32767), 32767 );
BOOST_TEST_EQ( hv((int128)-32768), (std::size_t)-32768 );
typedef boost::uint128_type uint128;
BOOST_TEST_EQ( hv((uint128)0), 0 );
BOOST_TEST_EQ( hv((uint128)1), 1 );
BOOST_TEST_EQ( hv((uint128)65535), 65535 );
#if defined(BOOST_GCC) && BOOST_GCC < 100000
// This looks like some sort of miscompilation.
// Under CI, both GHA and Appveyor GCCs produce this value.
// But the exact same test on godbolt.org produces the correct
// value, below.
// BOOST_TEST_EQ( hv((uint128)-1), 18446744073709551615ULL );
#else
BOOST_TEST_EQ( hv((uint128)-1), 13835058055282163777ULL );
#endif
#endif
// float
BOOST_TEST_EQ( hv(0.0f), 0 );
BOOST_TEST_EQ( hv(-0.0f), 0 );
BOOST_TEST_EQ( hv(1.0f), 1065353216U );
BOOST_TEST_EQ( hv(-1.0f), 3212836864U );
BOOST_TEST_EQ( hv(3.14f), 1078523331U );
BOOST_TEST_EQ( hv(-3.14f), 3226006979U );
BOOST_TEST_EQ( hv(1e-38f), 7136238U );
BOOST_TEST_EQ( hv(-1e-38f), 2154619886U );
BOOST_TEST_EQ( hv(1e+38f), 2123789977U );
BOOST_TEST_EQ( hv(-1e+38f), 4271273625U );
#if !defined(__GLIBCXX__)
BOOST_TEST_EQ( hv(std::numeric_limits<float>::infinity()), 2139095040U );
BOOST_TEST_EQ( hv(-std::numeric_limits<float>::infinity()), 4286578688U );
#elif SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::numeric_limits<float>::infinity()), 4294967295U );
BOOST_TEST_EQ( hv(-std::numeric_limits<float>::infinity()), 4294967294U );
#else
BOOST_TEST_EQ( hv(std::numeric_limits<float>::infinity()), 18446744073709551615ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<float>::infinity()), 18446744073709551614ULL );
#endif
// double
BOOST_TEST_EQ( hv(0.0), 0 );
BOOST_TEST_EQ( hv(-0.0), 0 );
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(1.0), 1072693248U );
BOOST_TEST_EQ( hv(-1.0), 3220176896U );
BOOST_TEST_EQ( hv(3.14), 2660156064U );
BOOST_TEST_EQ( hv(-3.14), 512672416U );
BOOST_TEST_EQ( hv(1e-308), 1553872728U );
BOOST_TEST_EQ( hv(-1e-308), 3701356376U );
BOOST_TEST_EQ( hv(1e+308), 2577739707U );
BOOST_TEST_EQ( hv(-1e+308), 430256059U );
#if !defined(__GLIBCXX__)
BOOST_TEST_EQ( hv(std::numeric_limits<double>::infinity()), 2146435072U );
BOOST_TEST_EQ( hv(-std::numeric_limits<double>::infinity()), 4293918720U );
#else
BOOST_TEST_EQ( hv(std::numeric_limits<double>::infinity()), 4294967295U );
BOOST_TEST_EQ( hv(-std::numeric_limits<double>::infinity()), 4294967294U );
#endif
#else
BOOST_TEST_EQ( hv(1.0), 4607182418800017408ULL );
BOOST_TEST_EQ( hv(-1.0), 13830554455654793216ULL );
BOOST_TEST_EQ( hv(3.14), 4614253070214989087ULL );
BOOST_TEST_EQ( hv(-3.14), 13837625107069764895ULL );
BOOST_TEST_EQ( hv(1e-308), 2024022533073106ULL );
BOOST_TEST_EQ( hv(-1e-308), 9225396059387848914ULL );
BOOST_TEST_EQ( hv(1e+308), 9214871658872686752ULL );
BOOST_TEST_EQ( hv(-1e+308), 18438243695727462560ULL );
#if !defined(__GLIBCXX__)
BOOST_TEST_EQ( hv(std::numeric_limits<double>::infinity()), 9218868437227405312ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<double>::infinity()), 18442240474082181120ULL );
#else
BOOST_TEST_EQ( hv(std::numeric_limits<double>::infinity()), 18446744073709551615ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<double>::infinity()), 18446744073709551614ULL );
#endif
#endif
// long double
BOOST_TEST_EQ( hv(0.0L), 0 );
BOOST_TEST_EQ( hv(-0.0L), 0 );
#if defined(_WIN32) && !defined(__GNUC__) // Under MS ABI, long double == double
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(1.0L), 1072693248U );
BOOST_TEST_EQ( hv(-1.0L), 3220176896U );
BOOST_TEST_EQ( hv(3.14L), 2660156064U );
BOOST_TEST_EQ( hv(-3.14L), 512672416U );
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 2146435072U );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 4293918720U );
#else
BOOST_TEST_EQ( hv(1.0L), 4607182418800017408ULL );
BOOST_TEST_EQ( hv(-1.0L), 13830554455654793216ULL );
BOOST_TEST_EQ( hv(3.14L), 4614253070214989087ULL );
BOOST_TEST_EQ( hv(-3.14L), 13837625107069764895ULL );
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 9218868437227405312ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 18442240474082181120ULL );
#endif
#else
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(1.0L), 2684370943U );
BOOST_TEST_EQ( hv(-1.0L), 2684403711U );
BOOST_TEST_EQ( hv(3.14L), 83002659U );
BOOST_TEST_EQ( hv(-3.14L), 82969891U );
#if !defined(__GLIBCXX__)
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 0xA0007FFFu );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 0xA000FFFFu );
#else
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 4294967295U );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 4294967294U );
#endif
#else
BOOST_TEST_EQ( hv(1.0L), 11529215046068486143ULL );
BOOST_TEST_EQ( hv(-1.0L), 11529215046068518911ULL );
BOOST_TEST_EQ( hv(3.14L), 12059468778148142067ULL );
BOOST_TEST_EQ( hv(-3.14L), 12059468778147191795ULL );
#if !defined(__GLIBCXX__)
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 11529215046068502527ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 11529215046068535295ULL );
#else
BOOST_TEST_EQ( hv(std::numeric_limits<long double>::infinity()), 18446744073709551615ULL );
BOOST_TEST_EQ( hv(-std::numeric_limits<long double>::infinity()), 18446744073709551614ULL );
#endif
#endif
#endif
// C array
{
int a1[] = { 0 };
int a2[] = { 0, 0 };
int a3[] = { 0, 0, 0 };
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(a1), 3864292196U );
BOOST_TEST_EQ( hv(a2), 2842917718U );
BOOST_TEST_EQ( hv(a3), 325752138U );
#else
BOOST_TEST_EQ( hv(a1), 3864292196ULL );
BOOST_TEST_EQ( hv(a2), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(a3), 17867750819888810972ULL );
#endif
}
// string
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::string()), 0 );
BOOST_TEST_EQ( hv(std::string("abc")), 1849538372U );
BOOST_TEST_EQ( hv(std::string("\0", 1)), 3864292196U );
BOOST_TEST_EQ( hv(std::string("\0\0", 2)), 2842917718U );
BOOST_TEST_EQ( hv(std::string("\0\0\0", 3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::string()), 0 );
BOOST_TEST_EQ( hv(std::string("abc")), 6420922261882292859ULL );
BOOST_TEST_EQ( hv(std::string("\0", 1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::string("\0\0", 2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::string("\0\0\0", 3)), 17867750819888810972ULL );
#endif
// pointer
BOOST_TEST_EQ( hv((void*)0), 0 );
BOOST_TEST_EQ( hv((void*)0x200014A0), 603985716U );
// complex<int>
BOOST_TEST_EQ( hv(std::complex<int>(0, 0)), 0U );
BOOST_TEST_EQ( hv(std::complex<int>(+1, 0)), 1U );
BOOST_TEST_EQ( hv(std::complex<int>(0, +1)), 65U );
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::complex<int>(-1, 0)), 4294967295U );
BOOST_TEST_EQ( hv(std::complex<int>(0, -1)), 3221225536U );
#else
BOOST_TEST_EQ( hv(std::complex<int>(-1, 0)), 18446744073709551615ULL );
BOOST_TEST_EQ( hv(std::complex<int>(0, -1)), 13835058055282163776ULL );
#endif
// complex<float>
BOOST_TEST_EQ( hv(std::complex<float>(0.0f, 0.0f)), 0U );
BOOST_TEST_EQ( hv(std::complex<float>(+1.0f, 0.0f)), 1065353216U );
BOOST_TEST_EQ( hv(std::complex<float>(-1.0f, 0.0f)), 3212836864U );
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::complex<float>(0.0f, +1.0f)), 3495952384U );
BOOST_TEST_EQ( hv(std::complex<float>(0.0f, -1.0f)), 2959081472U );
#else
BOOST_TEST_EQ( hv(std::complex<float>(0.0f, +1.0f)), 67920461824ULL );
BOOST_TEST_EQ( hv(std::complex<float>(0.0f, -1.0f)), 209117511680ULL );
#endif
// complex<double>
BOOST_TEST_EQ( hv(std::complex<double>(0.0, 0.0)), 0U );
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::complex<double>(+1.0, 0.0)), 1072693248U );
BOOST_TEST_EQ( hv(std::complex<double>(-1.0, 0.0)), 3220176896U );
BOOST_TEST_EQ( hv(std::complex<double>(0.0, +1.0)), 873201664U );
BOOST_TEST_EQ( hv(std::complex<double>(0.0, -1.0)), 2483814400U );
#else
BOOST_TEST_EQ( hv(std::complex<double>(+1.0, 0.0)), 4607182418800017408ULL );
BOOST_TEST_EQ( hv(std::complex<double>(-1.0, 0.0)), 13830554455654793216ULL );
BOOST_TEST_EQ( hv(std::complex<double>(0.0, +1.0)), 3750372589692780544ULL );
BOOST_TEST_EQ( hv(std::complex<double>(0.0, -1.0)), 10667901617333862400ULL );
#endif
// pair
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::make_pair(0, 0)), 2842917718U );
BOOST_TEST_EQ( hv(std::make_pair(1, 2)), 2507434894U );
BOOST_TEST_EQ( hv(std::make_pair(-1, -2)), 1874100199 );
#else
BOOST_TEST_EQ( hv(std::make_pair(0, 0)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::make_pair(1, 2)), 3370697991563800380ULL );
BOOST_TEST_EQ( hv(std::make_pair(-1, -2)), 4139767141999124554ULL );
#endif
// vector<char>
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::vector<char>(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<char>(1)), 3864292196U );
BOOST_TEST_EQ( hv(std::vector<char>(2)), 2842917718U );
BOOST_TEST_EQ( hv(std::vector<char>(3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::vector<char>(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<char>(1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::vector<char>(2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::vector<char>(3)), 17867750819888810972ULL );
#endif
// vector<int>
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::vector<int>(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<int>(1)), 3864292196U );
BOOST_TEST_EQ( hv(std::vector<int>(2)), 2842917718U );
BOOST_TEST_EQ( hv(std::vector<int>(3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::vector<int>(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<int>(1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::vector<int>(2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::vector<int>(3)), 17867750819888810972ULL );
#endif
// vector<vector<int>>
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(1)), 3864292196U );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(2)), 2842917718U );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(0)), 0 );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::vector<std::vector<int> >(3)), 17867750819888810972ULL );
#endif
// list<char>
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::list<char>(0)), 0 );
BOOST_TEST_EQ( hv(std::list<char>(1)), 3864292196U );
BOOST_TEST_EQ( hv(std::list<char>(2)), 2842917718U );
BOOST_TEST_EQ( hv(std::list<char>(3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::list<char>(0)), 0 );
BOOST_TEST_EQ( hv(std::list<char>(1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::list<char>(2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::list<char>(3)), 17867750819888810972ULL );
#endif
// list<int>
#if SIZE_MAX == 4294967295U
BOOST_TEST_EQ( hv(std::list<int>(0)), 0 );
BOOST_TEST_EQ( hv(std::list<int>(1)), 3864292196U );
BOOST_TEST_EQ( hv(std::list<int>(2)), 2842917718U );
BOOST_TEST_EQ( hv(std::list<int>(3)), 325752138U );
#else
BOOST_TEST_EQ( hv(std::list<int>(0)), 0 );
BOOST_TEST_EQ( hv(std::list<int>(1)), 3864292196ULL );
BOOST_TEST_EQ( hv(std::list<int>(2)), 14642545639667855512ULL );
BOOST_TEST_EQ( hv(std::list<int>(3)), 17867750819888810972ULL );
#endif
return boost::report_errors();
}
#endif

View File

@@ -1,24 +1,19 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
#include <boost/preprocessor/cat.hpp>
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
{
typedef typename T::value_type value_type;
const int number_of_containers = 11;
T containers[number_of_containers];
@@ -27,27 +22,27 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
containers[i].push_back(0);
}
containers[5].push_back(value_type(1));
containers[6].push_back(value_type(1));
containers[6].push_back(value_type(1));
containers[7].push_back(value_type(-1));
containers[8].push_back(value_type(-1));
containers[8].push_back(value_type(-1));
containers[9].push_back(value_type(1));
containers[9].push_back(value_type(-1));
containers[10].push_back(value_type(-1));
containers[10].push_back(value_type(1));
containers[5].push_back(1);
containers[6].push_back(1);
containers[6].push_back(1);
containers[7].push_back(-1);
containers[8].push_back(-1);
containers[8].push_back(-1);
containers[9].push_back(1);
containers[9].push_back(-1);
containers[10].push_back(-1);
containers[10].push_back(1);
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
HASH_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== BOOST_HASH_TEST_NAMESPACE::hash_range(
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -59,7 +54,7 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0);
@@ -68,9 +63,5 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#undef CONTAINER_TYPE
#endif

View File

@@ -1,21 +1,21 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <set>
@@ -31,7 +31,7 @@ using std::multiset;
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
set_tests::set_hash_integer_tests();
multiset_tests::multiset_hash_integer_tests();
#endif

View File

@@ -1,25 +1,20 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
#include <boost/preprocessor/cat.hpp>
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
{
typedef typename T::value_type value_type;
const int number_of_containers = 12;
const int number_of_containers = 11;
T containers[number_of_containers];
for(int i = 0; i < 5; ++i) {
@@ -27,30 +22,25 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
containers[i].insert(0);
}
containers[6].insert(value_type(1));
containers[7].insert(value_type(1));
containers[7].insert(value_type(1));
containers[8].insert(value_type(-1));
containers[9].insert(value_type(-1));
containers[9].insert(value_type(-1));
containers[10].insert(value_type(-1));
containers[10].insert(value_type(1));
containers[11].insert(value_type(1));
containers[11].insert(value_type(2));
containers[11].insert(value_type(3));
containers[11].insert(value_type(4));
containers[11].insert(value_type(5));
containers[6].insert(1);
containers[7].insert(1);
containers[7].insert(1);
containers[8].insert(-1);
containers[9].insert(-1);
containers[9].insert(-1);
containers[10].insert(-1);
containers[10].insert(1);
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
HASH_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== BOOST_HASH_TEST_NAMESPACE::hash_range(
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -62,7 +52,7 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0);
@@ -71,9 +61,5 @@ namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#undef CONTAINER_TYPE
#endif

View File

@@ -1,103 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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();
}

View File

@@ -1,80 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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();
}

View File

@@ -1,77 +0,0 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#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();
}

View File

@@ -1,184 +1,78 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <string>
#include "./compile_time.hpp"
void string_tests()
{
compile_time_tests((std::string*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
HASH_NAMESPACE::hash<std::string> x1;
HASH_NAMESPACE::hash<std::string> x2;
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
BOOST_TEST(x1("") == x2(std::string()));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
#if defined(TEST_EXTENSIONS)
std::string value1;
std::string value2("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()));
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
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)
#if !defined(BOOST_NO_STD_WSTRING)
void wstring_tests()
{
compile_time_tests((std::wstring*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
HASH_NAMESPACE::hash<std::wstring> x1;
HASH_NAMESPACE::hash<std::wstring> x2;
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
BOOST_TEST(x1(L"") == x2(std::wstring()));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
#if defined(TEST_EXTENSIONS)
std::wstring value1;
std::wstring value2(L"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()));
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#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()
{
string_tests();
string0_tests();
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
#if !defined(BOOST_NO_STD_WSTRING)
wstring_tests();
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
u16string_tests();
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
u32string_tests();
#endif
generic_string_tests((std::string*) 0);
#if BOOST_HASH_HAS_STRING_VIEW
generic_string_tests((std::string_view*) 0);
#endif
return boost::report_errors();
}

View File

@@ -1,55 +0,0 @@
// 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();
}

View File

@@ -1,53 +0,0 @@
// 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();
}

View File

@@ -1,24 +1,24 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// On some compilers hash_value isn't available for arrays, so I test it
// separately from the main array tests.
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
void array_int_test()
{
@@ -29,32 +29,32 @@ void array_int_test()
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
HASH_NAMESPACE::hash<int[25]> hasher1;
int array2[1] = {3};
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
HASH_NAMESPACE::hash<int[1]> hasher2;
int array3[2] = {2, 3};
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
HASH_NAMESPACE::hash<int[3][2]> hasher;
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
}
#endif
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif

View File

@@ -1,100 +0,0 @@
// 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();
}

View File

@@ -1,21 +1,21 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/container_hash/hash.hpp>
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_test.hpp>
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
#include <vector>
@@ -23,46 +23,13 @@ using std::vector;
#define CONTAINER_TYPE vector
#include "./hash_sequence_test.hpp"
#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));
}
}
#endif // TEST_EXTENSIONS
int main()
{
#ifdef BOOST_HASH_TEST_EXTENSIONS
#ifdef TEST_EXTENSIONS
vector_tests::vector_hash_integer_tests();
#endif
vector_bool_tests::vector_bool_test();
return boost::report_errors();
}

View File

@@ -1,21 +0,0 @@
// 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);
}

View File

@@ -1,33 +1,22 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#define BOOST_HASH_TEST_NAMESPACE boost
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#define HASH_NAMESPACE boost
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
int f(std::size_t hash1, int* x1) {
// Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
// Check that HASH_NAMESPACE::hash<int*> works in both files.
HASH_NAMESPACE::hash<int*> ptr_hasher;
BOOST_TEST(hash1 == ptr_hasher(x1));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Check that std::vector<std::size_t> is avaiable in this file.
std::vector<std::size_t> x;
x.push_back(static_cast<std::size_t>(*x1));
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
#else
return 0;
#endif
x.push_back(*x1);
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
}

View File

@@ -1,19 +1,17 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#define BOOST_HASH_TEST_NAMESPACE boost
#define HASH_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
extern int f(std::size_t, int*);
int main() {
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
HASH_NAMESPACE::hash<int*> ptr_hasher;
int x = 55;
BOOST_TEST(!f(ptr_hasher(&x), &x));
return boost::report_errors();

View File

@@ -1,11 +1,9 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
extern int f();
int main() { return f(); }

View File

@@ -1,10 +1,8 @@
// 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)
// Copyright Daniel James 2005-2006. Use, modification, and distribution are
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/container_hash/hash.hpp>
#include <boost/functional/hash.hpp>
int f() { return 0; }

View File

@@ -1,16 +0,0 @@
// Copyright 2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Check that I haven't inadvertantly pulled namespace std into the global
// namespace.
#include "./config.hpp"
#include <list>
#include <boost/container_hash/hash.hpp>
typedef list<int> foo;
int main() {}