Compare commits

...

142 Commits

Author SHA1 Message Date
Daniel James
cf6176c276 Remove hash from repo 2017-12-22 20:10:37 +00:00
Daniel James
376000169c Manually write out tuple overloads
A tad more usable this way.
2017-12-19 17:48:48 +00:00
Daniel James
bc09240437 Update paths for headers moved to different modules
Makes it easier to see dependencies.
2017-12-19 17:48:18 +00:00
Daniel James
8098c5b302 1.66.0 release notes 2017-11-10 15:16:39 +00:00
Daniel James
d803b3bdc0 Remove schema stuff, as it doesn't work 2017-10-02 23:31:54 +01:00
Daniel James
170558e4fa Initial explicit-failures-markup.xml 2017-10-02 13:42:23 +01:00
Daniel James
4a4cb9f7a4 Use is_zero workaround on clang
The same warning appears on clang for windows, but the workaround wasn't
used because the gcc macro wasn't defined.
2017-09-19 12:42:01 +01:00
Daniel James
8bdfb0cf90 Use 1.65.1 in travis 2017-09-08 21:40:16 +01:00
Daniel James
3ee110f82c Download branch snapshot from cron jobs 2017-08-24 22:03:19 +01:00
Daniel James
f7ad177dae Use boost 1.65 in travis
Also copied some other things that I've found to work well.
2017-08-24 10:24:52 +01:00
Daniel James
9c82e48bc9 Support for char16_t, char32_t, u16string, u32string 2017-05-31 22:19:54 +01:00
Daniel James
1b3bed82aa Initial support for char32_t 2017-05-31 10:17:34 +01:00
Daniel James
6dd58674aa Add ticket link to changelog entry 2017-02-03 08:41:31 +00:00
Daniel James
babb4f8f73 Hash changelog entry 2017-01-01 16:04:24 +00:00
Daniel James
4b99dbdb64 Link to ticket in changelog 2016-12-05 23:00:20 +00:00
Daniel James
a489b08e27 Add changelog entry for 1.63.0 2016-12-05 22:42:44 +00:00
Daniel James
ab9f98455a Fix cast issue in poor_quality_tests
The comparison in the if statement and the test didn't match, which I
think is why this test was sometimes failling. But should still try to
write something that will work for floats.
2016-11-18 15:14:04 +00:00
Daniel James
7159a86166 Only support std::wstring when wchar_t is available
This hopefuly fixes #8552.

https://svn.boost.org/trac/boost/ticket/8552
2016-11-18 15:13:46 +00:00
Daniel James
d0ee8e13bd Support for removed function objects in C++17
std::unary_function and std::binary_function are removed in C++17, and
Visual C++ is the first compiler to do this (when the appropriate macro
is defined). I'm not sure what the long term solution should be, but
hopefully this will work for now.
2016-11-01 16:31:21 +00:00
Daniel James
e2d7225f57 Document warning fixes in 1.63.0 2016-10-14 09:24:13 +01:00
Daniel James
36545f62cf Try to avoid more warnings 2016-10-11 10:07:11 +01:00
Daniel James
618fc6d074 Remove -Wsign-conversion, old gcc doesn't support it. 2016-10-05 13:46:24 +01:00
Daniel James
c2764e22a7 Another signed conversion warning 2016-10-05 09:49:27 +01:00
Daniel James
5a811f25aa Add -Wsign-conversion to flags 2016-10-05 09:42:18 +01:00
Daniel James
b790429529 Warnings as errors on travis. 2016-09-30 09:25:44 +01:00
Daniel James
1e6cefbfeb More clang warnings 2016-09-30 09:25:44 +01:00
Daniel James
b0ddb244be Fix signed conversion warnings. 2016-09-30 09:25:44 +01:00
Daniel James
3dfdb19bfd Merge branch 'master' into develop 2016-08-14 19:50:45 +01:00
Daniel James
f184dd019f Merge branch 'develop'
Just changes to build setup.
2016-07-30 12:03:02 +01:00
Daniel James
0361d416b7 Always specify standard version. 2016-07-03 08:47:14 +01:00
Daniel James
7838c3678f Merge branch 'develop' (early part) 2016-06-26 20:32:22 +01:00
Daniel James
5856bff480 Move all hash tests into a single directory. 2016-06-26 20:28:17 +01:00
Marshall Clow
468516ed71 Fix a typo in a comment; fixes https://svn.boost.org/trac/boost/ticket/12270 2016-06-14 17:24:30 -07:00
Daniel James
c8d8c7edd4 Fix some warnings in test/example code. 2016-05-30 15:20:52 +01:00
Daniel
e76c3dc1a2 Travis 2016-05-26 22:36:58 +01:00
Daniel
8171dbb465 Fix the binary 32 and 64 bit hash functions. 2016-02-28 09:14:37 +00:00
Daniel
99d4923496 Add test for strings of null character.
They're working, but wanted to make that explicitly clear.
2016-02-28 09:11:19 +00:00
Daniel James
29865a5bca Merge pull request #4 from BillyDonahue/changes
doc: BOOST_HASH_SPECIALIZE_REF passes by const ref
2015-09-15 13:50:41 +01:00
Billy Donahue
8b05fd5fdf doc: BOOST_HASH_SPECIALIZE_REF passes by const ref 2015-09-12 17:12:02 -04:00
Daniel James
ada1369a14 Merge remote-tracking branch 'origin/develop' 2015-01-24 14:37:21 +00:00
Daniel James
4977373964 Fix version number in release notes. 2015-01-10 13:10:15 +00:00
Daniel James
8b19e7eaa0 Release note for hash change. 2015-01-10 13:04:32 +00:00
Daniel James
75ae18ef54 Merge branch 'pr/3' into develop 2015-01-05 19:36:31 +00:00
Andy Webber
754d5f535e Fixed strict aliasing violation.
Changed C-style cast and dereference to std::memcpy.  Exactly mirrors other code already in the file.
2015-01-05 19:35:34 +00:00
Daniel James
ebc607d44e Merge branch 'develop' 2014-07-28 23:32:57 +01:00
Daniel James
549196ca7d Update documentation for hash_combine.
Also added some disclaimers for anyone who didn't notice the note in the
introduction.
2014-07-28 23:30:47 +01:00
Daniel James
f2761964bd The correct release notes.
The ones I checked in were for unordered.
2014-07-27 18:00:14 +01:00
Daniel James
41487a2e8c Merge branch 'develop' 2014-07-27 12:20:49 +01:00
Daniel James
ca52df8a05 Release notes. 2014-07-27 12:20:43 +01:00
Daniel James
b39e6e96f0 Merge remote-tracking branch 'origin/develop' 2014-07-27 12:01:12 +01:00
Daniel James
8266a55b26 Update metadata to use array for 'std'. 2014-05-31 15:16:56 +01:00
Daniel James
711b2b6d69 Merge branch 'develop'
Library metadata, plus improved hash_combine.
2014-03-16 22:55:12 +00:00
Daniel James
d888097468 Regenerate libraries.json 2014-02-27 22:46:55 +00:00
Daniel James
23f1db7729 Update maintainers from /libs/maintainers.txt 2014-02-27 22:29:01 +00:00
Daniel James
35ef2502d5 Typo 2014-02-24 22:21:35 +00:00
Daniel James
aa3ab0790a Add maintainers to metadata. 2014-02-24 22:21:03 +00:00
Daniel James
6c3e20ac18 Json meta data. 2014-02-24 21:40:10 +00:00
Daniel James
97cc6fbbc1 Add metadata 2014-02-23 14:29:48 +00:00
Daniel James
309d17f387 Another try at an improved hash function.
This is based on the mix function from MurmurHash. It's not the full
algorithm as it's always seeded with 0, and doesn't do a final mix. This
should be okay as Boost.Hash doesn't claim to avalanche the bits.
2014-02-23 10:17:08 +00:00
Daniel James
928767f2bd Merge remote-tracking branch 'origin/develop' 2014-02-12 23:55:44 +00:00
Daniel James
bb2a91bf47 Improved(?) hash function.
Given the existing interface, it's quite tricky to use most popular hash
functions without a change, so I'm using a modified version of FNV1a.
The current function always starts with a seed of 0 (and will in user
functions), so I'm adding the offset each time instead. I'm not sure if
that will work as well.
2014-01-28 23:33:25 +00:00
Daniel James
496bf24900 Merge remote-tracking branch 'origin/develop'
Just updating 'pragma once' to use the correct config macro.
2014-01-23 22:01:07 +00:00
Stephen Kelly
09f197abf6 Functional: Remove obsolete MSVC version checks.
[SVN r86051]
2013-12-10 23:41:55 +00:00
Daniel James
582671543b Use BOOST_HAS_PRAGMA_ONCE.
Remembering to first include config, so that it'll actually be defined.

[SVN r86726]
2013-12-10 23:41:13 +00:00
Stephen Kelly
6157ad5267 Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2013-12-10 23:40:59 +00:00
Daniel James
844d9758bd Merge branch 'develop' 2013-12-10 23:40:30 +00:00
Daniel James
7dbc8b593f Revert changes to develop branch.
Simplest way to merge to master.
2013-12-10 23:18:52 +00:00
Daniel James
3c22fce14c Merge unordered and hash from trunk.
- Only use Visual C++ pragma with appropriate compilers.
- Working link for Thomas Wang's hash function.
- Updated unordered rationale.
- Fix `unnecessary_copy_tests` for Visual C++ 12.
- Some extra insert tests.


[SVN r86728]
2013-11-16 20:36:27 +00:00
Daniel James
b066a9c509 Use BOOST_HAS_PRAGMA_ONCE.
Remembering to first include config, so that it'll actually be defined.

[SVN r86726]
2013-11-16 20:13:24 +00:00
Daniel James
74603822f4 Only use Visual C++ pragma for appropriate versions.
[SVN r86671]
2013-11-12 22:09:42 +00:00
Daniel James
998f714f8f Link to archived copy of Thomas Wang's integer hash function.
His site's no longer on the web, so use web.archive.org instead.

[SVN r86607]
2013-11-10 23:25:54 +00:00
Stephen Kelly
614feab582 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifndef...#else...#endif blocks.

[SVN r86245]
2013-10-11 23:17:48 +00:00
Stephen Kelly
999c2d5963 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
Process #ifdef...#endif blocks.

[SVN r86243]
2013-10-11 23:13:10 +00:00
Daniel James
c3e54942e8 Merge release notes + float hash fix. Ref #8822.
[SVN r86210]
2013-10-08 21:26:30 +00:00
Daniel James
10c83e95d9 Change log.
[SVN r86173]
2013-10-06 08:03:12 +00:00
Daniel James
734eb87d2a Simplify SFINAE for largest float overload. Refs #8822.
I accidentally missed it out. Also fix the return values.

[SVN r86172]
2013-10-06 08:02:35 +00:00
Stephen Kelly
af17fa46fb Functional: Remove obsolete GCC version checks.
[SVN r86112]
2013-10-01 08:46:45 +00:00
Stephen Kelly
e26c102522 Functional: Remove obsolete MSVC version checks.
[SVN r86051]
2013-09-30 11:22:29 +00:00
Stephen Kelly
378007cf94 Remove obsolete MSVC check from pragma guard
git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq

is now clean.

[SVN r85952]
2013-09-26 13:02:51 +00:00
Daniel James
61df9052e1 Merge Hash. Fixes #8568, Refs #8822.#8822.#8822.
[SVN r85389]
2013-08-18 09:48:53 +00:00
Daniel James
dea8d12a04 Fix Visual C++ warning in hash. Refs #8568.
I changed this a little from the patch on #8568. I moved the pragmas to the
start and end of the file because I don't like to little the body of the code
with them (this does mean I've disabled a potentially useful warning, but the
code is pretty stable nowadays).

I also removed the version checks, as the warning should be present in later
versions.


[SVN r85248]
2013-08-08 22:01:18 +00:00
Daniel James
1870aa9534 Simpler test for appropriate floats for binary hashing. Refs #8822.
No idea if this will actually fix it.

[SVN r85246]
2013-08-08 20:30:04 +00:00
Daniel James
b1ca4cf0d4 Merge some change log entries to release.
[SVN r84497]
2013-05-25 15:53:49 +00:00
Daniel James
0d6cee7e64 Change log entries for 1.54.0
[SVN r84496]
2013-05-25 15:45:51 +00:00
Daniel James
9dad407f06 Hash: Merge documentation fixes. Fixes #7957.
[SVN r82827]
2013-02-12 00:19:56 +00:00
Daniel James
7d148af8d2 Hash: Fix typo, refs #7957.
[SVN r82674]
2013-01-31 21:57:26 +00:00
Daniel James
4aec4be0ed Hash: Merge UB fix to release.
[SVN r82256]
2012-12-29 11:11:43 +00:00
Daniel James
bb8ebafca1 Hash: Changelog for undefined behaviour fix.
[SVN r82255]
2012-12-29 11:09:35 +00:00
Thomas Heller
7e162c4f03 Fixing UB by using memcpy instead of old style cast
[SVN r82218]
2012-12-27 10:49:19 +00:00
Daniel James
061e0d9d6d Hash: Fix changelog for 1.53.0.
[SVN r82140]
2012-12-21 09:50:01 +00:00
Daniel James
cc091d5d98 Merge hash test fixes.
[SVN r82125]
2012-12-20 20:38:09 +00:00
Daniel James
e5f3356742 Hash: Stop using -strict-ansi for Intel.
It doesn't seem to be compatible with C++11.

[SVN r82060]
2012-12-17 23:38:35 +00:00
Daniel James
9721f9c764 Hash: Safer macro names in tests.
[SVN r82059]
2012-12-17 23:37:56 +00:00
Daniel James
713b688159 Hash: Merge from trunk.
- Avoid floating point workarounds on recent standard libraries.
- Support int128.
- Remove container_fwd_0x.hpp.


[SVN r81920]
2012-12-13 22:34:18 +00:00
Daniel James
8a8ab9ec70 Hash: Fix int128 with BOOST_HASH_NO_EXTENSIONS.
I don't think int128 should count as an extension.

BOOST_HASH_NO_EXTENSIONS is actually a bit of a pain, and I don't think it's
that useful. Maybe I should deprecate it.

[SVN r81870]
2012-12-12 09:44:32 +00:00
Daniel James
13a86a7a26 Hash: Fix int128 support.
[SVN r81854]
2012-12-11 15:48:19 +00:00
Daniel James
0e0906b0a4 Hash: Support boost::int128_type.
[SVN r81816]
2012-12-10 10:40:44 +00:00
Daniel James
67ad8c2151 Hash: Detab.
[SVN r81787]
2012-12-08 09:19:24 +00:00
Daniel James
be4292842d Hash: Stop using warnings as errors for Visual C++.
I'd like to get full test results for Visual C++ with STLport.

[SVN r81712]
2012-12-04 22:23:20 +00:00
Daniel James
473b1da8de Hash: Avoid some intel warnings in tests.
It doesn't have the GCC warning pragma, and doesn't like compiling the integer
tests with floats (used to compile them, but never use them).

[SVN r81679]
2012-12-02 21:12:38 +00:00
Daniel James
8afae2e762 Hash: Remove container_fwd_0x.hpp
[SVN r81678]
2012-12-02 21:12:24 +00:00
Daniel James
03380087a9 Hash: Don't use workarounds with recent compilers. #7221, #7470
[SVN r81677]
2012-12-02 21:11:45 +00:00
Marshall Clow
9dcc33ab1b Removed missed usage of deprecated macros in Boost.Functional
[SVN r81578]
2012-11-26 21:45:20 +00:00
Daniel James
d8adc5aa24 Remove deprecated container_fwd header.
[SVN r81356]
2012-11-15 13:25:08 +00:00
Daniel James
7f7ecfc717 Hash: Extra test to check different platform's floating point functions.
[SVN r81210]
2012-11-05 18:33:54 +00:00
Daniel James
dfd48ef498 Hash: Revert r81122. Refs #7470.
I'll get back to this later, it probably requires compiler specific changes.


[SVN r81124]
2012-10-31 19:05:25 +00:00
Marshall Clow
a2756e75e8 Narrower 'using'; Refs #7470
[SVN r81122]
2012-10-31 17:14:43 +00:00
Daniel James
9c37cd46b1 Unordered/Hash: Merge change log.
[SVN r80778]
2012-09-30 11:58:06 +00:00
Daniel James
acf1f3bc48 Hash: Update change log
[SVN r80777]
2012-09-30 11:56:13 +00:00
Daniel James
b856e6308d Hash: Merge new floating point hasher.
Uses a binary hash for more platforms.


[SVN r80293]
2012-08-28 21:50:57 +00:00
Daniel James
b4b4a559e0 Hash: merge enum support + cleanup some tests.
[SVN r80292]
2012-08-28 21:48:16 +00:00
Daniel James
853a713cf2 Remove deprecated header boost/functional/detail/container_fwd.hpp
[SVN r80288]
2012-08-28 17:43:05 +00:00
Daniel James
043571dabf Merge #error for deperectaed boost/functional/detail/container_fwd.hpp
[SVN r80286]
2012-08-28 17:38:30 +00:00
Daniel James
7b2f73c225 Hash: Avoid type punning warning.
[SVN r80217]
2012-08-25 20:54:10 +00:00
Daniel James
eec47991f9 Hash: A single unified algorithm for hashing floats.
Attempts to automatically use a binary hash for floats where it's known to
work, and then use the generic hash algorithm as a fallback.

[SVN r80177]
2012-08-24 22:52:42 +00:00
Daniel James
f1de575546 Hash: Clean up some unit tests.
- Remove some unnecessary headers.
- Try to fix warning in enum tests.
- Compile tests + hash namespace in enum tests.


[SVN r80154]
2012-08-23 12:18:18 +00:00
Daniel James
05f16beaf0 Hash: Quick attempt at supporting enums.
Thanks to Filip Konvička.


[SVN r80139]
2012-08-22 11:40:27 +00:00
Daniel James
34a6eebf7e Hash: Merge C++11 forward declaration fix.
[SVN r80054]
2012-08-15 23:04:49 +00:00
Daniel James
9119b2646b Hash: Remove C++11 forward declarations.
It seems that on Visual C++ Dinkumware declares shared_ptr in std, but for
Intel C++ it imports it from std::tr1. I was thinking of doing a macro check
for this, but since we're close to release, just change it to always include
the headers and never forward declare the C++11 classes, which is much safer.

I might restore the forward declarations in the future, although I'm tempted
not to. I'm not sure the improvement in compile time is worth the hassle.


[SVN r80038]
2012-08-14 20:06:07 +00:00
Daniel James
12f49f7c53 Merge some link fixes.
[SVN r79869]
2012-08-05 08:36:49 +00:00
Daniel James
0757aea7cb Hash: Fix links to examples.
[SVN r79749]
2012-07-25 23:42:41 +00:00
Daniel James
92fe67f714 Compile error for deprecated header boost/functional/detail/container_fwd.hpp.
[SVN r79652]
2012-07-22 07:15:34 +00:00
Daniel James
73b507c728 Hash: Merge support for smart pointers.
[SVN r79548]
2012-07-16 00:18:30 +00:00
Daniel James
330040aea9 Hash: Merge update c++11 header macros.
[SVN r79544]
2012-07-15 23:28:30 +00:00
Daniel James
5ebe3ad87d Hash: Fix smart pointer macro check.
[SVN r79527]
2012-07-15 07:43:40 +00:00
Daniel James
411ac66581 Hash: std::shared_ptr, std::unique_ptr support.
[SVN r79516]
2012-07-14 22:32:29 +00:00
Daniel James
75bcfdeb36 Hash: Merge using SFINAE to avoid implicit casts.
[SVN r79394]
2012-07-09 20:53:36 +00:00
Marshall Clow
af3a31090c Switch from deprecated macros to new shiny ones; no functionality change
[SVN r79392]
2012-07-09 20:12:04 +00:00
Daniel James
806abd0ddf Hash: Only use typeid when available.
[SVN r78755]
2012-05-29 19:41:19 +00:00
Daniel James
8ef04ed807 Hash: Extra changelog note.
[SVN r78696]
2012-05-27 20:55:14 +00:00
Daniel James
6be66ba092 Hash: Remove stary semicolon from deprecation pragma.
[SVN r78635]
2012-05-26 15:02:26 +00:00
Daniel James
0d4c55854b Add warning to deprecated header boost/functional/detail/container_fwd.hpp.
Should have done this years ago, removing this header should make
modularization a tad bit cleaner.


[SVN r78533]
2012-05-21 21:58:18 +00:00
Daniel James
8bc410f571 Hash: Use SFINAE to avoid implicit casts to numbers.
[SVN r78391]
2012-05-08 22:24:46 +00:00
Daniel James
68f0d9bc6b Hash: Add some notes about forwarding header. Refs #6849.
[SVN r78366]
2012-05-07 10:58:55 +00:00
Daniel James
5611f4238e Unordered: Avoid -Wshadow warnings. Refs #6190.
[SVN r78364]
2012-05-07 10:57:35 +00:00
Daniel James
963d06acb8 Unordered/Hash: Release notes.
[SVN r78318]
2012-05-03 21:35:51 +00:00
Daniel James
f3229da836 Hash: fix tests for older C++0x libraries.
[SVN r78165]
2012-04-23 20:51:21 +00:00
Daniel James
441cea413d Hash: Some formatting.
[SVN r78164]
2012-04-23 20:49:30 +00:00
Daniel James
4f3265079d Hash: Missing comma.
[SVN r78145]
2012-04-22 19:49:41 +00:00
Daniel James
98953a28c7 Hash: Support std::array and std::tuple. Refs #6806.
[SVN r78144]
2012-04-22 19:46:28 +00:00
Daniel James
c3d01123fa Hash: Note about previous change.
[SVN r78143]
2012-04-22 19:45:58 +00:00
Daniel James
f98a942e2e Unordered/hash: Avoid a gcc warning. Refs #6771
[SVN r77832]
2012-04-08 15:29:15 +00:00
75 changed files with 76 additions and 5999 deletions

72
.travis.yml Normal file
View File

@@ -0,0 +1,72 @@
# 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++
addons:
apt:
packages:
- libboost-tools-dev
matrix:
include:
- compiler: gcc
env: |
USER_CONFIG="using gcc : : g++-4.8 -Werror --std=c++03 ;"
- compiler: gcc
env: |
USER_CONFIG="using gcc : : g++-4.8 -Werror --std=c++11 ;"
- compiler: clang
env: |
USER_CONFIG="using clang : : clang++ -Werror --std=c++03 ;"
- compiler: clang
env: |
USER_CONFIG="using clang : : clang++ -Werror --std=c++11 ;"
- compiler: clang
env: |
USER_CONFIG="using clang : : clang++ -Werror --std=c++11 -D_HAS_AUTO_PTR_ETC=0 ;"
before_script:
- export BOOST_VERSION=1.65.1
- export BOOST_FILENAME=boost_1_65_1
- 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 ${BOOST_ROOT}/boost/functional.hpp
- find ${BOOST_ROOT}/boost/functional -type f | grep -v hash | xargs -r rm
script:
- cd ${TRAVIS_BUILD_DIR}/test
- bjam -q ${BJAM_TOOLSET} include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include

View File

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

View File

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

View File

@@ -1,29 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:disable Disabling The Extensions]
While [classref boost::hash]'s extensions are generally useful, you might want
to turn them of in order to check that your code will work with other
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
When this macro is defined, only the specialisations detailed
in TR1 will be declared. But, if you later undefine the macro and include
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
- activating the extensions.
It is strongly recommended that you never undefine the macro - and only define
it so that it applies to the complete translation unit, either by defining it
at the beginning of the main source file or, preferably, by using a compiler
switch or preference. And you really should never define it in header files.
If you are writing a library which has code in the header which requires the
extensions, then the best action is to tell users not to define the macro.
Their code won't ['require] the macro.
Translation units that are compiled with the macro defined will link with units
that were compiled without it. This feature has been designed to avoid ODR
violations.
[endsect]

View File

@@ -1,29 +0,0 @@
[library Boost.Functional/Hash
[quickbook 1.5]
[authors [James, Daniel]]
[copyright 2005 2006 2007 2008 Daniel James]
[purpose A TR1 hash function object that can be extended to hash user
defined types]
[category higher-order]
[id hash]
[dirname functional/hash]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[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,52 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:intro Introduction]
[def __tr1-full__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Draft Technical Report on C++ Library Extensions]]
[def __tr1__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
TR1]]
[def __unordered__ [link unordered Boost.Unordered]]
[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
[def __multi-index__ [@boost:/libs/multi_index/doc/index.html
Boost Multi-Index Containers Library]]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
[classref boost::hash] is an implementation of the __hash-function__ object
specified by the __tr1-full__ (TR1). It is the default hash function for
__unordered__, __intrusive__'s unordered associative containers, and
__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
As it is compliant with __tr1__, it will work with:
* integers
* floats
* pointers
* strings
It also implements the extension proposed by Peter Dimov in issue 6.18 of the
__issues__ (page 63), this adds support for:
* arrays
* `std::pair`
* the standard containers.
* extending [classref boost::hash] for custom types.
[note
This hash function is designed to be used in containers based on
the STL and is not suitable as a general purpose hash function.
For more details see the [link hash.rationale rationale].
]
[endsect]

View File

@@ -1,27 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[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]
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]
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]
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]
Contains the hash function that [funcref boost::hash_combine] is based on.
[endsect]

View File

@@ -1,93 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:portability Portability]
[def __boost_hash__ [classref boost::hash]]
__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.
On a strictly standards compliant compiler, an overload defined in the
boost namespace won't be found when __boost_hash__ is instantiated,
so for these compilers the overload should only be declared in the same
namespace as the class.
Let's say we have a simple custom type:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
friend std::size_t hash_value(custom_type x)
{
__boost_hash__<int> hasher;
return hasher(x.value);
}
};
}
On a compliant compiler, when `hash_value` is called for this type,
it will look at the namespace inside the type and find `hash_value`
but on a compiler which doesn't support ADL `hash_value` won't be found.
To make things worse, some compilers which do support ADL won't find
a friend class defined inside the class.
So first move the member function out of the class:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash(custom_type x)
{
__boost_hash__<T> hasher;
return hasher(value);
}
};
template <class T>
inline std::size_t hash_value(custom_type<T> x)
{
return x.hash();
}
}
Unfortunately, I couldn't declare hash_value as a friend, as some compilers
don't support template friends, so instead I declared a member function to
calculate the hash, and called it from hash_value.
For compilers which don't support ADL, hash_value needs to be defined in the
boost namespace:
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[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://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 that 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,883 +0,0 @@
<!--
Copyright Daniel James 2005-2009
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<library-reference>
<section id="hash.reference.specification">
<para>For the full specification, see section 6.3 of the
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</ulink>
and issue 6.18 of the
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
</para>
</section>
<header name="boost/functional/hash.hpp">
<para>
Defines <code><classname>boost::hash</classname></code>,
and helper functions.
</para>
<namespace name="boost">
<!--
boost::hash
-->
<struct name="hash">
<template>
<template-type-parameter name="T"/>
</template>
<inherit access="public">
<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>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>T const&amp;</paramtype>
</parameter>
<returns><para>
<programlisting><functionname>hash_value</functionname>(val)</programlisting>
</para></returns>
<notes>
<para>
The call to <code><functionname>hash_value</functionname></code>
is unqualified, so that custom overloads can be
found via argument dependent lookup.
</para>
<para>
This is not defined when the macro <code>BOOST_HASH_NO_EXTENSIONS</code>
is defined. The specializations are still defined, so only the specializations
required by TR1 are defined.
</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws><para>
Only throws if
<code><functionname>hash_value</functionname>(T)</code> throws.
</para></throws>
</method>
</struct>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>bool</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>bool</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>char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char</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>signed char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>signed char</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 char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned char</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>wchar_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>wchar_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>short</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>short</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 short</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned short</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>int</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>int</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 int</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned int</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>long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>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</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned 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>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>
<template-arg>float</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>float</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>double</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>double</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>long double</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>long double</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::string</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::string 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::wstring</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::wstring 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"/>
</template>
<specialization>
<template-arg>T*</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>T*</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::type_index</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::type_index</paramtype>
</parameter>
<returns>
<para><code>val.hash_code()</code></para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
<notes>
<para>
Only available if it's in your standard library and Boost.Config
is aware of it.
</para>
</notes>
</struct-specialization>
<free-function-group name="Support functions (Boost extension).">
<!--
boost::hash_combine
-->
<function name="hash_combine">
<template>
<template-type-parameter name="T"/>
</template>
<type>void</type>
<parameter name="seed"><paramtype>size_t &amp;</paramtype></parameter>
<parameter name="v"><paramtype>T const&amp;</paramtype></parameter>
<purpose><simpara>
Called repeatedly to incrementally create a hash value from
several variables.
</simpara></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/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws>
Only throws if <functionname>hash_value</functionname>(T) throws.
Strong exception safety, as long as <functionname>hash_value</functionname>(T)
also has strong exception safety.
</throws>
</function>
<!--
boost::hash_range
-->
<overloaded-function name="hash_range">
<signature>
<template>
<template-type-parameter name="It"/>
</template>
<type>std::size_t</type>
<parameter name="first"><paramtype>It</paramtype></parameter>
<parameter name="last"><paramtype>It</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="It"/>
</template>
<type>void</type>
<parameter name="seed"><paramtype>std::size_t&amp;</paramtype></parameter>
<parameter name="first"><paramtype>It</paramtype></parameter>
<parameter name="last"><paramtype>It</paramtype></parameter>
</signature>
<purpose><simpara>
Calculate the combined hash value of the elements of an iterator
range.
</simpara></purpose>
<effects>
<para>For the two argument overload:
<programlisting>
size_t seed = 0;
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
return seed;
</programlisting>
</para>
<para>For the three arguments overload:</para>
<programlisting>
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
</programlisting>
</effects>
<notes>
<para>
<code>hash_range</code> is sensitive to the order of the elements
so it wouldn't be appropriate to use this with an unordered
container.
</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
</notes>
<throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
throws. <code>hash_range(std::size_t&amp;, It, It)</code> has basic exception safety as long as
<code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
has basic exception safety.
</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>
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>short</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned short</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>int</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned int</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<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>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>double</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long double</paramtype></parameter>
</signature>
<signature>
<template><template-type-parameter name="T"/></template>
<type>std::size_t</type>
<parameter name="val"><paramtype>T* const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter><paramtype>T (&amp;val)[N]</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter><paramtype>const T (&amp;val)[N]</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Ch"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::basic_string&lt;Ch, std::char_traits&lt;Ch&gt;, A&gt; const&amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="A"/>
<template-type-parameter name="B"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::pair&lt;A, B&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::vector&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::list&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::deque&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::set&lt;K, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::multiset&lt;K, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="T"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::map&lt;K, T, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="T"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::multimap&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>
or <functionname>boost::hash_combine</functionname> which
call <code>hash_value</code> without namespace qualification so that overloads
for custom types are found via ADL.
</para></description>
<notes>
<para>This is an extension to TR1</para>
</notes>
<throws>
Only throws if a user supplied version of
<code><functionname>hash_value</functionname></code>
throws for an element of a container, or
one of the types stored in a pair.
</throws>
<returns>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Types</entry>
<entry>Returns</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>bool</code>,
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>,
<code>short</code>, <code>unsigned short</code>,
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
</entry>
<entry><code>val</code></entry>
</row>
<row>
<entry><code>long long</code>, <code>unsigned long long</code></entry>
<entry><code>val</code> when <code>abs(val) &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>
</row>
<row>
<entry><code>T*</code></entry>
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry>
<code>T&#160;val[N]</code>,
<code>const&#160;T&#160;val[N]</code>
</entry>
<entry><code>hash_range(val, val+N)</code></entry>
</row>
<row>
<entry>
<code>std:basic_string&lt;Ch,&#160;std::char_traits&lt;Ch&gt;,&#160;A&gt;</code>,
<code>std::vector&lt;T,&#160;A&gt;</code>,
<code>std::list&lt;T,&#160;A&gt;</code>,
<code>std::deque&lt;T,&#160;A&gt;</code>,
<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>
</entry>
<entry><code>hash_range(val.begin(), val.end())</code></entry>
</row>
<row>
<entry><code>std::pair&lt;A, B&gt;</code></entry>
<entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, val.first);
<functionname>hash_combine</functionname>(seed, val.second);
return seed;</programlisting></entry>
</row>
<row>
<entry><code>std::tuple&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,28 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[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.
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 沈慧峰.
The implementation of the hash function for pointers is based on suggestions
made by Alberto Barbati and Dave Harris. Dave Harris also suggested an
important improvement to [funcref boost::hash_combine] that was taken up.
Some useful improvements to the floating point hash algorithm were suggested
by Daniel Krügler.
The original implementation came from Jeremy B. Maitin-Shepard's hash table
library, although this is a complete rewrite.
[endsect]

View File

@@ -1,212 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[section:tutorial Tutorial]
When using a hash index with __multi-index-short__, you don't need to do
anything to use [classref boost::hash] as it uses it by default.
To find out how to use a user-defined type, read the
[link hash.custom section on extending boost::hash for a custom data type].
If your standard library supplies its own implementation of the unordered
associative containers and you wish to use
[classref boost::hash], just use an extra template parameter:
std::unordered_multiset<int, ``[classref boost::hash]``<int> >
set_of_ints;
std::unordered_set<std::pair<int, int>, ``[classref boost::hash]``<std::pair<int, int> >
set_of_pairs;
std::unordered_map<int, std::string, ``[classref boost::hash]``<int> > map_int_to_string;
To use [classref boost::hash] directly, create an instance and call it as a function:
#include <``[headerref boost/functional/hash.hpp]``>
int main()
{
``[classref boost::hash]``<std::string> string_hash;
std::size_t h = string_hash("Hash me");
}
For an example of generic use, here is a function to generate a vector
containing the hashes of the elements of a container:
template <class Container>
std::vector<std::size_t> get_hashes(Container const& x)
{
std::vector<std::size_t> hashes;
std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
``[classref boost::hash]``<typename Container::value_type>());
return hashes;
}
[endsect]
[section:custom Extending boost::hash for a custom data type]
[classref boost::hash] is implemented by calling the function
[funcref boost::hash_value hash_value].
The namespace isn't specified so that it can detect overloads via argument
dependant lookup. So if there is a free function `hash_value` in the same
namespace as a custom type, it will get called.
If you have a structure `library::book`, where each `book` is uniquely
defined by it's member `id`:
namespace library
{
struct book
{
int id;
std::string author;
std::string title;
// ....
};
bool operator==(book const& a, book const& b)
{
return a.id == b.id;
}
}
Then all you would need to do is write the function `library::hash_value`:
namespace library
{
std::size_t hash_value(book const& b)
{
``[classref boost::hash]``<int> hasher;
return hasher(b.id);
}
}
And you can now use [classref boost::hash] with book:
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
library::book dandelion(1354, "Paul J. Shanley",
"Hash & Dandelion Greens");
``[classref boost::hash]``<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife);
// If std::unordered_set is available:
std::unordered_set<library::book, ``[classref boost::hash]``<library::book> > books;
books.insert(knife);
books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
books.insert(library::book(1953, "Snyder, Bernadette M.",
"Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
assert(books.find(knife) != books.end());
assert(books.find(dandelion) == books.end());
The full example can be found in:
[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
and
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
[tip
When writing a hash function, first look at how the equality function works.
Objects that are equal must generate the same hash value.
When objects are not equal they should generate different hash values.
In this object equality was based just on the id so the hash function
only hashes the id. If it was based on the object's name and author
then the hash function should take them into account
(how to do this is discussed in the next section).
]
[endsect]
[section:combine Combining hash values]
Say you have a point class, representing a two dimensional location:
class point
{
int x;
int y;
public:
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
};
and you wish to use it as the key for an `unordered_map`. You need to
customise the hash for this structure. To do this we need to combine
the hash values for `x` and `y`. The function
[funcref boost::hash_combine] is supplied for this purpose:
class point
{
...
friend std::size_t hash_value(point const& p)
{
std::size_t seed = 0;
``[funcref boost::hash_combine]``(seed, p.x);
``[funcref boost::hash_combine]``(seed, p.y);
return seed;
}
...
};
Calls to hash_combine incrementally build the hash from the different members
of point, it can be repeatedly called for any number of elements. It calls
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
Full code for this example is at
[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
[note
When using [funcref boost::hash_combine] the order of the
calls matters.
'''
<programlisting>
std::size_t seed = 0;
boost::hash_combine(seed, 1);
boost::hash_combine(seed, 2);
</programlisting>
results in a different seed to:
<programlisting>
std::size_t seed = 0;
boost::hash_combine(seed, 2);
boost::hash_combine(seed, 1);
</programlisting>
'''
If you are calculating a hash value for data where the order of the data
doesn't matter in comparisons (e.g. a set) you will have to ensure that the
data is always supplied in the same order.
]
To calculate the hash of an iterator range you can use [funcref boost::hash_range]:
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/functional/hash_fwd.hpp>`
header which forward declares [classref boost::hash],
[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
include the main header before instantiating [classref boost::hash]. When using
a container that uses [classref boost::hash] it should do that for you, so your
type will work fine with the boost hash containers. There's an example of this
in [@boost:/libs/unordered/examples/template.hpp template.hpp] and
[@boost:/libs/unordered/examples/template.cpp template.cpp].
[endsect]

View File

@@ -1,9 +0,0 @@
# 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)
run books.cpp ;
run point.cpp ;
run portable.cpp ;
run template.cpp ;

View File

@@ -1,51 +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 "./books.hpp"
#include <boost/functional/hash.hpp>
#include <cassert>
// If std::unordered_set was available:
//#include <unordered_set>
// This example illustrates how to use boost::hash with a custom hash function.
// For full details, see the tutorial.
int main()
{
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
library::book dandelion(1354, "Paul J. Shanley", "Hash & Dandelion Greens");
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:
//
//std::unordered_set<library::book, boost::hash<library::book> > books;
//books.insert(knife);
//books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
//books.insert(library::book(1953, "Snyder, Bernadette M.",
// "Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
//assert(books.find(knife) != books.end());
//assert(books.find(dandelion) == books.end());
return 0;
}
namespace library
{
bool operator==(book const& a, book const& b)
{
return a.id == b.id;
}
std::size_t hash_value(book const& b)
{
boost::hash<int> hasher;
return hasher(b.id);
}
}

View File

@@ -1,26 +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)
// This example illustrates how to use boost::hash with a custom hash function.
// The implementation is contained in books.cpp
#include <cstddef>
#include <string>
namespace library
{
struct book
{
int id;
std::string author;
std::string title;
book(int i, std::string const& a, std::string const& t)
: id(i), author(a), title(t) {}
};
bool operator==(book const&, book const&);
std::size_t hash_value(book const&);
}

View File

@@ -1,54 +0,0 @@
// Copyright 2005 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp>
#include <cassert>
// This example illustrates how to use boost::hash_combine to generate a hash
// value from the different members of a class. For full details see the hash
// tutorial.
class point
{
int x;
int y;
public:
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
friend std::size_t hash_value(point const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
};
int main()
{
boost::hash<point> point_hasher;
point p1(0, 0);
point p2(1, 2);
point p3(4, 1);
point p4 = p1;
assert(point_hasher(p1) == point_hasher(p4));
// These tests could legally fail, but if they did it'd be a pretty bad
// hash function.
assert(point_hasher(p1) != point_hasher(p2));
assert(point_hasher(p1) != point_hasher(p3));
return 0;
}

View File

@@ -1,54 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp>
#include <cassert>
// This example illustrates how to customise boost::hash portably, so that
// it'll work on both compilers that don't implement argument dependent lookup
// and compilers that implement strict two-phase template instantiation.
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash() const
{
boost::hash<T> hasher;
return hasher(value);
}
};
}
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
int main()
{
foo::custom_type<int> x(1), y(2), z(1);
boost::hash<foo::custom_type<int> > hasher;
assert(hasher(x) == hasher(x));
assert(hasher(x) != hasher(y));
assert(hasher(x) == hasher(z));
return 0;
}

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/functional/hash_fwd.hpp>
template <typename A, typename B>
class my_pair
{
A value1;
B value2;
public:
my_pair(A const& v1, B const& v2)
: value1(v1), value2(v2)
{}
bool operator==(my_pair const& other) const
{
return value1 == other.value1 &&
value2 == other.value2;
}
friend std::size_t hash_value(my_pair const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.value1);
boost::hash_combine(seed, p.value2);
return seed;
}
};

View File

@@ -1,27 +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)
// Forwarding header for container_fwd.hpp's new location.
// This header is deprecated, I'll change the warning to an error in a future
// release, and then later remove the header completely.
#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(__EDG__)
#elif defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
#pragma message("Warning: boost/functional/detail/container_fwd.hpp is deprecated, use boost/detail/container_fwd.hpp instead.")
#elif defined(__GNUC__) || defined(__HP_aCC) || \
defined(__SUNPRO_CC) || defined(__IBMCPP__)
#warning "boost/functional/detail/container_fwd.hpp is deprecated, use boost/detail/container_fwd.hpp instead."
#endif
#include <boost/detail/container_fwd.hpp>
#endif

View File

@@ -1,7 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash.hpp>

View File

@@ -1,41 +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(BOOST_DETAIL_CONTAINER_FWD_0X_HPP)
#define BOOST_DETAIL_CONTAINER_FWD_0X_HPP
#include <boost/detail/container_fwd.hpp>
// std::array
#if !defined(BOOST_NO_0X_HDR_ARRAY)
// Don't forward declare std::array for Dinkumware, as it seems to be
// just 'using std::tr1::array'.
# if (defined(BOOST_DETAIL_NO_CONTAINER_FWD) && \
!defined(BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD)) || \
(defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
# include <array>
# else
namespace std {
template <class, std::size_t> class array;
}
# endif
#endif
// std::tuple
#if !defined(BOOST_NO_0X_HDR_TUPLE)
# if (defined(BOOST_DETAIL_NO_CONTAINER_FWD) && \
!defined(BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD)) || \
defined(BOOST_NO_VARIADIC_TEMPLATES)
# include <tuple>
# else
namespace std {
template <typename...> class tuple;
}
# endif
#endif
#endif

View File

@@ -1,246 +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>
#include <boost/config/no_tr1/cmath.hpp>
#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.
//
// 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

View File

@@ -1,115 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
// Include hash implementation for the current platform.
// Cygwn
#if defined(__CYGWIN__)
# if defined(__i386__) || defined(_M_IX86)
# include <boost/functional/hash/detail/hash_float_x86.hpp>
# else
# include <boost/functional/hash/detail/hash_float_generic.hpp>
# endif
#else
# include <boost/functional/hash/detail/hash_float_generic.hpp>
#endif
// Can we use fpclassify?
// STLport
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#define BOOST_HASH_USE_FPCLASSIFY 0
// GNU libstdc++ 3
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY 1
# else
# define BOOST_HASH_USE_FPCLASSIFY 0
# endif
// Everything else
#else
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
namespace boost
{
namespace hash_detail
{
template <class T>
inline std::size_t float_hash_value(T v)
{
using namespace std;
switch (fpclassify(v)) {
case FP_ZERO:
return 0;
case FP_INFINITE:
return (std::size_t)(v > 0 ? -1 : -2);
case FP_NAN:
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v);
default:
BOOST_ASSERT(0);
return 0;
}
}
}
}
#else // !BOOST_HASH_USE_FPCLASSIFY
namespace boost
{
namespace hash_detail
{
template <class T>
inline bool is_zero(T v)
{
#if !defined(__GNUC__)
return v == 0;
#else
// GCC's '-Wfloat-equal' will complain about comparing
// v to 0, but because it disables warnings for system
// headers it won't complain if you use std::equal_to to
// compare with 0. Resulting in this silliness:
return std::equal_to<T>()(v, 0);
#endif
}
template <class T>
inline std::size_t float_hash_value(T v)
{
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v);
}
}
}
#endif // BOOST_HASH_USE_FPCLASSIFY
#undef BOOST_HASH_USE_FPCLASSIFY
#endif

View File

@@ -1,91 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A general purpose hash function for non-zero floating point values.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
template <class T>
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
v = ldexp(v, limits<std::size_t>::digits);
std::size_t seed = static_cast<std::size_t>(v);
v -= static_cast<T>(seed);
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value
+ limits<std::size_t>::digits - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= static_cast<T>(part);
hash_float_combine(seed, part);
}
hash_float_combine(seed, exp);
return seed;
}
template <class T>
inline std::size_t float_hash_impl(T v)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif

View File

@@ -1,56 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A non-portable hash function form non-zero floats on x86.
//
// Even if you're on an x86 platform, this might not work if their floating
// point isn't set up as this expects. So this should only be used if it's
// absolutely certain that it will work.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER
#include <boost/cstdint.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
inline std::size_t float_hash_impl(float v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr;
return seed;
}
inline std::size_t float_hash_impl(double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr);
return seed;
}
inline std::size_t float_hash_impl(long double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr++);
hash_float_combine(seed, *(boost::uint16_t*)ptr);
return seed;
}
}
}
#endif

View File

@@ -1,61 +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
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# 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,355 +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/functional/hash/hash.hpp>
#include <boost/functional/hash/detail/container_fwd_0x.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#include <boost/type_traits/is_const.hpp>
#endif
namespace boost
{
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const&);
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const&);
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v);
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
template <class T>
std::size_t hash_value(std::complex<T> const&);
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
boost::hash_combine(seed, v.first);
boost::hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T>
std::size_t hash_value(std::complex<T> const& v)
{
boost::hash<T> hasher;
std::size_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
}
#if !defined(BOOST_NO_0X_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_0X_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_VARIADIC_TEMPLATES)
template <typename... T>
inline std::size_t hash_value(std::tuple<T...> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
#else
inline std::size_t hash_value(std::tuple<> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
# define BOOST_HASH_TUPLE_F(z, n, _) \
template< \
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
> \
inline std::size_t hash_value(std::tuple< \
BOOST_PP_ENUM_PARAMS_Z(z, n, A) \
> const& v) \
{ \
return boost::hash_detail::hash_tuple(v); \
}
BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
# undef BOOST_HASH_TUPLE_F
#endif
#endif
//
// call_hash_impl
//
// On compilers without function template ordering, this deals with arrays.
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
{
template <bool IsArray>
struct call_hash_impl
{
template <class T>
struct inner
{
static std::size_t call(T const& v)
{
using namespace boost;
return hash_value(v);
}
};
};
template <>
struct call_hash_impl<true>
{
template <class Array>
struct inner
{
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
static std::size_t call(Array const& v)
#else
static std::size_t call(Array& v)
#endif
{
const int size = sizeof(v) / sizeof(*v);
return boost::hash_range(v, v + size);
}
};
};
template <class T>
struct call_hash
: public call_hash_impl<boost::is_array<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//
// boost::hash
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: std::unary_function<T, std::size_t>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T, unsigned int n> struct hash<T[n]>
: std::unary_function<T[n], std::size_t>
{
std::size_t operator()(const T* val) const
{
return boost::hash_range(val, val+n);
}
};
#endif
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// On compilers without partial specialization, boost::hash<T>
// has already been declared to deal with pointers, so just
// need to supply the non-pointer version of hash_impl.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct hash_impl<false>
{
template <class T>
struct inner
: std::unary_function<T, std::size_t>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
};
#else // Visual C++ 6.5
// Visual C++ 6.5 has problems with nested member functions and
// applying const to const types in templates. So we get this:
template <bool IsConst>
struct hash_impl_msvc
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T const>::call(val);
}
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <>
struct hash_impl_msvc<true>
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <class T>
struct hash_impl_msvc2
: public hash_impl_msvc<boost::is_const<T>::value>
::BOOST_NESTED_TEMPLATE inner<T> {};
template <>
struct hash_impl<false>
{
template <class T>
struct inner : public hash_impl_msvc2<T> {};
};
#endif // Visual C++ 6.5
}
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
#endif

View File

@@ -1,536 +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_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/functional/hash/hash_fwd.hpp>
#include <functional>
#include <boost/functional/hash/detail/hash_float.hpp>
#include <string>
#include <boost/limits.hpp>
#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
#include <boost/static_assert.hpp>
#endif
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
#include <typeindex>
#endif
#if BOOST_WORKAROUND(__GNUC__, < 3) \
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
#else
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
namespace boost
{
#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
// If you get a static assertion here, it's because hash_value
// isn't declared for your type.
template <typename T>
std::size_t hash_value(T const&) {
BOOST_STATIC_ASSERT((T*) 0 && false);
return 0;
}
#endif
std::size_t hash_value(bool);
std::size_t hash_value(char);
std::size_t hash_value(unsigned char);
std::size_t hash_value(signed char);
std::size_t hash_value(short);
std::size_t hash_value(unsigned short);
std::size_t hash_value(int);
std::size_t hash_value(unsigned int);
std::size_t hash_value(long);
std::size_t hash_value(unsigned long);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
std::size_t hash_value(wchar_t);
#endif
#if !defined(BOOST_NO_LONG_LONG)
std::size_t hash_value(boost::long_long_type);
std::size_t hash_value(boost::ulong_long_type);
#endif
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
template <class T> std::size_t hash_value(T*);
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
std::size_t hash_value(const T (&x)[N]);
template< class T, unsigned N >
std::size_t hash_value(T (&x)[N]);
#endif
std::size_t hash_value(float v);
std::size_t hash_value(double v);
std::size_t hash_value(long double v);
template <class Ch, class A>
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
std::size_t hash_value(std::type_index);
#endif
// Implementation
namespace hash_detail
{
template <class T>
inline std::size_t hash_value_signed(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
T positive = val < 0 ? -1 - val : val;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <class T>
inline std::size_t hash_value_unsigned(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
}
inline std::size_t hash_value(bool v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(signed char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(long v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned long v)
{
return static_cast<std::size_t>(v);
}
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline std::size_t hash_value(wchar_t v)
{
return static_cast<std::size_t>(v);
}
#endif
#if !defined(BOOST_NO_LONG_LONG)
inline std::size_t hash_value(boost::long_long_type v)
{
return hash_detail::hash_value_signed(v);
}
inline std::size_t hash_value(boost::ulong_long_type v)
{
return hash_detail::hash_value_unsigned(v);
}
#endif
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const& v)
#else
template <class T> std::size_t hash_value(T* v)
#endif
{
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
// for some reason ptrdiff_t on OpenVMS compiler with
// 64 bit is not 64 bit !!!
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<long long int>(v));
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
#endif
return x + (x >> 3);
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T>
inline void hash_combine(std::size_t& seed, T& v)
#else
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
#endif
{
boost::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class It>
inline std::size_t hash_range(It first, It last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
return seed;
}
template <class It>
inline void hash_range(std::size_t& seed, It first, It last)
{
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T>
inline std::size_t hash_range(T* first, T* last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
template <class T>
inline void hash_range(std::size_t& seed, T* first, T* last)
{
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
inline std::size_t hash_value(const T (&x)[N])
{
return hash_range(x, x + N);
}
template< class T, unsigned N >
inline std::size_t hash_value(T (&x)[N])
{
return hash_range(x, x + N);
}
#endif
template <class Ch, class A>
inline std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
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);
}
#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
inline std::size_t hash_value(std::type_index v)
{
return v.hash_code();
}
#endif
//
// boost::hash
//
// Define the specializations required by the standard. The general purpose
// boost::hash is defined later in extensions.hpp if
// BOOST_HASH_NO_EXTENSIONS is not defined.
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by copy.
//
// These are undefined later.
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#else
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(const type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#endif
BOOST_HASH_SPECIALIZE(bool)
BOOST_HASH_SPECIALIZE(char)
BOOST_HASH_SPECIALIZE(signed char)
BOOST_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE(wchar_t)
#endif
BOOST_HASH_SPECIALIZE(short)
BOOST_HASH_SPECIALIZE(unsigned short)
BOOST_HASH_SPECIALIZE(int)
BOOST_HASH_SPECIALIZE(unsigned int)
BOOST_HASH_SPECIALIZE(long)
BOOST_HASH_SPECIALIZE(unsigned long)
BOOST_HASH_SPECIALIZE(float)
BOOST_HASH_SPECIALIZE(double)
BOOST_HASH_SPECIALIZE(long double)
BOOST_HASH_SPECIALIZE_REF(std::string)
#if !defined(BOOST_NO_STD_WSTRING)
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
BOOST_HASH_SPECIALIZE(std::type_index)
#endif
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
// Specializing boost::hash for pointers.
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct hash<T*>
: public std::unary_function<T*, std::size_t>
{
std::size_t operator()(T* v) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
return boost::hash_value(v);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
#endif
}
};
#else
// For compilers without partial specialization, we define a
// boost::hash for all remaining types. But hash_impl is only defined
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
// is defined there will still be a compile error for types not supported
// in the standard.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<true>
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T val) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
return boost::hash_value(val);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(val));
return x + (x >> 3);
#endif
}
};
};
}
template <class T> struct hash
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#undef BOOST_HASH_CHAR_TRAITS
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
// Include this outside of the include guards in case the file is included
// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
// undefined.
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#include <boost/functional/hash/extensions.hpp>
#endif

View File

@@ -1,40 +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
#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,7 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash_fwd.hpp>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<explicit-failures-markup>
</explicit-failures-markup>

1
meta/libraries.json Normal file
View File

@@ -0,0 +1 @@
[]

View File

@@ -1,81 +0,0 @@
# Copyright 2005-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)
import testing ;
project hash-tests
: requirements
<warnings>all
<toolset>intel:<warnings>on
<toolset>intel:<cxxflags>-strict-ansi
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>msvc:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
;
test-suite functional/hash
:
[ run hash_fwd_test_1.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_fwd_test_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_range_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_custom_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_global_namespace_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_friend_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_built_in_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_value_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_vector_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_list_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_deque_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_set_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_map_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_complex_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_type_index_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_std_array_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_std_tuple_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run link_ext_test.cpp link_no_ext_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run extensions_hpp_test.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ compile-fail hash_no_ext_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ compile-fail namespace_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ compile-fail implicit_fail_test.cpp : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_no_ext_macro_1.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ run hash_no_ext_macro_2.cpp : : : <define>BOOST_HASH_NO_IMPLICIT_CASTS ]
[ compile deprecated_container_fwd.cpp ]
;
test-suite functional/hash_implicit_casts
:
[ run hash_number_test.cpp : : : : implicit_number ]
[ run hash_pointer_test.cpp : : : : implicit_pointer ]
[ run hash_function_pointer_test.cpp : : : : implicit_function_pointer ]
[ run hash_float_test.cpp : : : : implicit_float ]
[ run hash_string_test.cpp : : : : implicit_string ]
[ run hash_range_test.cpp : : : : implicit_range ]
[ run hash_custom_test.cpp : : : : implicit_custom ]
[ run hash_built_in_array_test.cpp : : : : implicit_built_in_array ]
[ run link_test.cpp link_test_2.cpp : : : : implicit_link ]
[ run implicit_fail_test.cpp : : : : implicit_test ]
;
test-suite functional/hash_no_ext
:
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
;
build-project ../examples ;

View File

@@ -1,16 +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/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
template <class T>
void compile_time_tests(T*)
{
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
}

View File

@@ -1,21 +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(TEST_STD)
# define TEST_STD_INCLUDES
# define HASH_NAMESPACE std
#else
# define HASH_NAMESPACE boost
# if !defined(BOOST_HASH_NO_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

View File

@@ -1,14 +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 <boost/functional/detail/container_fwd.hpp>
typedef std::vector<int, std::allocator<int> > int_vector;
#include <vector>
int main() {
int_vector x;
}

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/functional/hash/extensions.hpp works okay.
//
// It probably should be in boost/functional/hash/detail, but since it isn't it
// should work.
#include "./config.hpp"
#include <boost/functional/hash/extensions.hpp>
int main() {
int x[2] = { 2, 3 };
boost::hash<int[2]> hf;
hf(x);
}

View File

@@ -1,75 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
void array_int_test()
{
const int length1 = 25;
int array1[25] = {
26, -43, 32, 65, 45,
12, 67, 32, 12, 23,
0, 0, 0, 0, 0,
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
HASH_NAMESPACE::hash<int[25]> hasher1;
const int length2 = 1;
int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2;
const int length3 = 2;
int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1)
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
BOOST_TEST(hasher2(array2)
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
BOOST_TEST(hasher3(array3)
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher;
std::size_t seed1 = 0;
for(int i = 0; i < 3; ++i)
{
std::size_t seed2 = 0;
for(int j = 0; j < 2; ++j)
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
HASH_NAMESPACE::hash_combine(seed1, seed2);
}
BOOST_TEST(hasher(array) == seed1);
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
}
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif
return boost::report_errors();
}

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(TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable:4244) // conversion from 'unsigned long' to
// 'unsigned short', possible loss of data
#pragma warning(disable:4245) // conversion from 'int' to
// 'const unsigned short',
// signed/unsigned mismatch
#pragma warning(disable:4305) // truncation from 'double' to
// 'const std::complex<float>::_Ty'
#pragma warning(disable:4309) // truncation of constant value
#pragma warning(disable:4512) // assignment operator could not be generated
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__)
#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)
{
HASH_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
HASH_NAMESPACE::hash<T> real_hasher;
T real = v.real();
T imag = v.imag();
BOOST_TEST(real_hasher(real) == complex_hasher(std::complex<T>(real)));
if(imag != 0 && real_hasher(real) == complex_hasher(v)) {
std::ostringstream os;
os<<"real_hasher("<<real<<") == complex_hasher("
<<v.real()<<" + "<<v.imag()<<"i) == "
<<real_hasher(real)<<" (This might not be a bug).";
BOOST_ERROR(os.str().c_str());
}
}
template <class Float>
void complex_float_tests(Float*)
{
typedef std::complex<Float> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
}
template <class Integer>
void complex_integral_tests(Integer*)
{
typedef std::complex<Integer> complex;
generic_complex_tests(complex(0,0));
generic_complex_tests(complex(15342,124));
generic_complex_tests(complex(25,54356));
generic_complex_tests(complex(5325,2346));
generic_complex_tests(complex(-243897,-49923874));
generic_complex_tests(complex(-543,763));
}
int main()
{
// I've comments out the short and unsigned short tests
// as they cause warnings and don't really test
// anything that the other tests already deal with.
complex_float_tests((float*) 0);
complex_float_tests((double*) 0);
complex_float_tests((long double*) 0);
//complex_integral_tests((short*) 0);
complex_integral_tests((int*) 0);
complex_integral_tests((long*) 0);
//complex_integral_tests((unsigned short*) 0);
complex_integral_tests((unsigned int*) 0);
complex_integral_tests((unsigned long*) 0);
return boost::report_errors();
}
#endif // TEST_EXTENSIONS

View File

@@ -1,100 +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"
#include <boost/config.hpp>
#include <cstddef>
namespace test
{
struct custom
{
int value_;
std::size_t hash() const
{
return value_ * 10;
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
friend std::size_t hash_value(custom const& x )
{
return x.hash();
}
#endif
custom(int x) : value_(x) {}
};
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace boost
{
std::size_t hash_value(test::custom x)
{
return x.hash();
}
}
#endif
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <vector>
#include <string>
#include <cctype>
void custom_tests()
{
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 HASH_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
std::vector<test::custom> custom_vector;
custom_vector.push_back(5);
custom_vector.push_back(25);
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();
}

View File

@@ -1,35 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <deque>
using std::deque;
#define CONTAINER_TYPE deque
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
deque_tests::deque_hash_integer_tests();
#endif
return boost::report_errors();
}

View File

@@ -1,18 +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("float", (float*) 0);
float_tests("double", (double*) 0);
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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <cmath>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/detail/workaround.hpp>
#include <iostream>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4723) // conditional expression is constant
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__)
#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(HASH_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"
;
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));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
#endif
BOOST_TEST(x1(zero) != x1(0.5));
BOOST_TEST(x1(minus_zero) != x1(0.5));
BOOST_TEST(x1(0.5) != x1(-0.5));
BOOST_TEST(x1(1) != x1(-1));
using namespace std;
// Doing anything with infinity causes borland to crash.
#if defined(__BORLANDC__)
std::cerr
<< "Not running infinity checks on Borland, as it causes it to crash."
"\n";
#else
if(boost::hash_detail::limits<T>::has_infinity) {
T infinity = -log(zero);
T infinity2 = (T) 1. / zero;
T infinity3 = (T) -1. / minus_zero;
T infinity4 = boost::hash_detail::limits<T>::infinity();
T minus_infinity = log(zero);
T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero;
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== HASH_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(TEST_EXTENSIONS)
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));
#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(TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
#endif
#endif
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
HASH_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(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()) !=
HASH_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())"
" = "
<< HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "
<< x1(0)
<< "\n";
}
#endif
}
// NaN also causes borland to crash.
#if !defined(__BORLANDC__) && defined(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()) ==
HASH_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
}
#endif
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

View File

@@ -1,103 +0,0 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/config.hpp>
#include <cstddef>
namespace test
{
template <class T>
struct custom
{
int value_;
std::size_t hash() const
{
return value_ * 10;
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
friend std::size_t hash_value(custom const& x)
{
return x.hash();
}
#endif
custom(int x) : value_(x) {}
};
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace boost
{
template <class T>
std::size_t hash_value(test::custom<T> x)
{
return x.hash();
}
}
#endif
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <vector>
#include <string>
#include <cctype>
void custom_tests()
{
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 HASH_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
std::vector<test::custom<int> > custom_vector;
custom_vector.push_back(5);
custom_vector.push_back(25);
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();
}

View File

@@ -1,61 +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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.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; }
void void_func2() { static int x = 2; --x; }
int int_func1(int) { return 0; }
int int_func2(int) { return 1; }
void function_pointer_tests()
{
compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0);
HASH_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_TEST(&void_func1 != &void_func2);
BOOST_TEST(&int_func1 != &int_func2);
BOOST_TEST(hasher_void(0) == hasher_void(0));
BOOST_TEST(hasher_void(&void_func1) == hasher_void(&void_func1));
BOOST_TEST(hasher_void(&void_func1) != hasher_void(&void_func2));
BOOST_TEST(hasher_void(&void_func1) != hasher_void(0));
BOOST_TEST(hasher_int(0) == hasher_int(0));
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(hasher_void(&void_func1)
== HASH_NAMESPACE::hash_value(&void_func1));
BOOST_TEST(hasher_int(&int_func1)
== HASH_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal:
BOOST_TEST(hasher_void(0) == 0);
#endif
}
int main()
{
function_pointer_tests();
return boost::report_errors();
}

View File

@@ -1,104 +0,0 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#include <boost/functional/hash_fwd.hpp>
#include <boost/config.hpp>
#include <cstddef>
#include <vector>
namespace test {
template <class T>
struct test_type1
{
T value;
test_type1(T const& x) : value(x) {}
};
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
template <class T>
std::size_t hash_value(test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
#endif
template <class T>
struct test_type2
{
T value1, value2;
test_type2(T const& x, T const& y) : value1(x), value2(y) {}
};
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
template <class T>
std::size_t hash_value(test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
#endif
template <class T>
struct test_type3
{
std::vector<T> values;
test_type3(typename std::vector<T>::iterator x,
typename std::vector<T>::iterator y) : values(x, y) {}
};
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
template <class T>
std::size_t hash_value(test_type3<T> const& x)
{
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
#endif
}
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace boost
{
template <class T>
std::size_t hash_value(test::test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
template <class T>
std::size_t hash_value(test::test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
template <class T>
std::size_t hash_value(test::test_type3<T> const& x)
{
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
}
#endif
#endif

View File

@@ -1,96 +0,0 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This checks that template code implemented using hash_fwd will work.
#include "./config.hpp"
#include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#include <boost/functional/hash.hpp>
#include <string>
void fwd_test1()
{
test::test_type1<int> x(5);
test::test_type1<std::string> y("Test");
HASH_NAMESPACE::hash<int> hasher_int;
HASH_NAMESPACE::hash<std::string> hasher_string;
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
}
void fwd_test2()
{
test::test_type2<int> x(5, 10);
test::test_type2<std::string> y("Test1", "Test2");
std::size_t seed1 = 0;
HASH_NAMESPACE::hash_combine(seed1, 5);
HASH_NAMESPACE::hash_combine(seed1, 10);
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
}
void fwd_test3()
{
std::vector<int> values1;
values1.push_back(10);
values1.push_back(15);
values1.push_back(20);
values1.push_back(3);
std::vector<std::string> values2;
values2.push_back("Chico");
values2.push_back("Groucho");
values2.push_back("Harpo");
values2.push_back("Gummo");
values2.push_back("Zeppo");
test::test_type3<int> x(values1.begin(), values1.end());
test::test_type3<std::string> y(values2.begin(), values2.end());
std::size_t seed1 =
HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 =
HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
}
#endif
int main()
{
#ifdef TEST_EXTENSIONS
fwd_test1();
fwd_test2();
fwd_test3();
#endif
return boost::report_errors();
}

View File

@@ -1,47 +0,0 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This test just makes sure a header which uses hash_fwd can compile without
// the main hash headers.
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
int main() {}
#else
#include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp>
template <class T> void unused(T const&) {}
void fwd_test()
{
test::test_type1<int> x1(3);
test::test_type1<std::string> y1("Black");
test::test_type2<int> x2(25, 16);
test::test_type2<std::string> y2("White", "Green");
std::vector<int> empty;
std::vector<std::string> empty2;
test::test_type3<int> x3(empty.begin(), empty.end());
test::test_type3<std::string> y3(empty2.begin(), empty2.end());
// Prevent gcc warnings:
unused(x1); unused(x2); unused(x3);
unused(y1); unused(y2); unused(y3);
}
int main()
{
fwd_test();
return boost::report_errors();
}
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)

View File

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

View File

@@ -1,35 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <list>
using std::list;
#define CONTAINER_TYPE list
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
list_tests::list_hash_integer_tests();
#endif
return boost::report_errors();
}

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,40 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#include <map>
#ifdef TEST_EXTENSIONS
using std::map;
#define CONTAINER_TYPE map
#include "./hash_map_test.hpp"
using std::multimap;
#define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp"
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
map_tests::map_hash_integer_tests();
multimap_tests::multimap_hash_integer_tests();
#endif
return boost::report_errors();
}

View File

@@ -1,76 +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(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'int' to 'float'
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
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;
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j)
containers[i].insert(pair(key(0), value(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)));
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]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_TEST(
(containers[i2] == containers[j2]) ==
(hasher(containers[i2]) == hasher(containers[j2]))
);
}
}
}
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
integer_tests((CONTAINER_TYPE<int, float>*) 0);
integer_tests((CONTAINER_TYPE<unsigned long, unsigned long>*) 0);
integer_tests((CONTAINER_TYPE<double, short>*) 0);
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#undef CONTAINER_TYPE
#endif

View File

@@ -1,28 +0,0 @@
// 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"
// 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
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
template <class T> void ignore(T const&) {}
int main()
{
HASH_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
return 0;
}

View File

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

View File

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

View File

@@ -1,178 +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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <iostream>
#include <boost/detail/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/functional/hash/detail/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__)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T>
void numeric_test(T*)
{
typedef boost::hash_detail::limits<T> limits;
compile_time_tests((T*) 0);
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
T v1 = (T) -5;
BOOST_TEST(x1(v1) == x2(v1));
BOOST_TEST(x1(T(-5)) == x2(T(-5)));
BOOST_TEST(x1(T(0)) == x2(T(0)));
BOOST_TEST(x1(T(10)) == x2(T(10)));
BOOST_TEST(x1(T(25)) == x2(T(25)));
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
if (limits::is_integer)
{
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
#endif
}
template <class T>
void limits_test(T*)
{
typedef boost::hash_detail::limits<T> limits;
if(limits::is_specialized)
{
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
T min_value = (limits::min)();
T max_value = (limits::max)();
BOOST_TEST(x1(min_value) == x2((limits::min)()));
BOOST_TEST(x1(max_value) == x2((limits::max)()));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
if (limits::is_integer)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
== std::size_t(min_value));
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
== std::size_t(max_value));
}
#endif
}
}
template <class T>
void poor_quality_tests(T*)
{
typedef boost::hash_detail::limits<T> limits;
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.
if(T(1) != T(-1))
BOOST_TEST(x1(T(1)) != x2(T(-1)));
if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2)));
if((limits::max)() != (limits::max)() - 1)
BOOST_TEST(x1(static_cast<T>((limits::max)()))
!= x2(static_cast<T>((limits::max)() - 1)));
}
void bool_test()
{
HASH_NAMESPACE::hash<bool> x1;
HASH_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(char, char)
NUMERIC_TEST(signed char, schar)
NUMERIC_TEST(unsigned char, uchar)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
NUMERIC_TEST(wchar_t, wchar)
#endif
NUMERIC_TEST(short, short)
NUMERIC_TEST(unsigned short, ushort)
NUMERIC_TEST(int, int)
NUMERIC_TEST(unsigned int, uint)
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
NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double)
NUMERIC_TEST(std::size_t, size_t)
NUMERIC_TEST(std::ptrdiff_t, ptrdiff_t)
bool_test();
return boost::report_errors();
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif

View File

@@ -1,49 +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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void pointer_tests()
{
compile_time_tests((int**) 0);
compile_time_tests((void**) 0);
HASH_NAMESPACE::hash<int*> x1;
HASH_NAMESPACE::hash<int*> x2;
int int1;
int int2;
BOOST_TEST(x1(0) == x2(0));
BOOST_TEST(x1(&int1) == x2(&int1));
BOOST_TEST(x1(&int2) == x2(&int2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal:
BOOST_TEST(x1(0) == 0);
#endif
}
int main()
{
pointer_tests();
return boost::report_errors();
}

View File

@@ -1,88 +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(TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector>
void hash_range_tests()
{
std::vector<int> empty, values1, values2, values3, values4, values5;
values1.push_back(0);
values2.push_back(10);
values3.push_back(10);
values3.push_back(20);
values4.push_back(15);
values4.push_back(75);
values5.push_back(10);
values5.push_back(20);
values5.push_back(15);
values5.push_back(75);
values5.push_back(10);
values5.push_back(20);
std::vector<int> x;
std::size_t x_seed = 0;
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10);
HASH_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == HASH_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);
HASH_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == HASH_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 =
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()));
}
int main()
{
hash_range_tests();
return boost::report_errors();
}
#endif // TEST_EXTESNIONS

View File

@@ -1,76 +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(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
{
const int number_of_containers = 11;
T containers[number_of_containers];
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j)
containers[i].push_back(0);
}
containers[5].push_back(1);
containers[6].push_back(1);
containers[6].push_back(1);
containers[7].push_back(-1);
containers[8].push_back(-1);
containers[8].push_back(-1);
containers[9].push_back(1);
containers[9].push_back(-1);
containers[10].push_back(-1);
containers[10].push_back(1);
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]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_TEST(
(containers[i2] == containers[j2]) ==
(hasher(containers[i2]) == hasher(containers[j2]))
);
}
}
}
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0);
integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
integer_tests((CONTAINER_TYPE<double>*) 0);
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#undef CONTAINER_TYPE
#endif

View File

@@ -1,40 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <set>
using std::set;
#define CONTAINER_TYPE set
#include "./hash_set_test.hpp"
using std::multiset;
#define CONTAINER_TYPE multiset
#include "./hash_set_test.hpp"
#endif
int main()
{
#ifdef TEST_EXTENSIONS
set_tests::set_hash_integer_tests();
multiset_tests::multiset_hash_integer_tests();
#endif
return boost::report_errors();
}

View File

@@ -1,79 +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(CONTAINER_TYPE)
#error "CONTAINER_TYPE not defined"
#else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
{
const int number_of_containers = 12;
T containers[number_of_containers];
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j)
containers[i].insert(0);
}
containers[6].insert(1);
containers[7].insert(1);
containers[7].insert(1);
containers[8].insert(-1);
containers[9].insert(-1);
containers[9].insert(-1);
containers[10].insert(-1);
containers[10].insert(1);
containers[11].insert(1);
containers[11].insert(2);
containers[11].insert(3);
containers[11].insert(4);
containers[11].insert(5);
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]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
BOOST_TEST(
(containers[i2] == containers[j2]) ==
(hasher(containers[i2]) == hasher(containers[j2]))
);
}
}
}
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests())
{
integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0);
integer_tests((CONTAINER_TYPE<unsigned long>*) 0);
integer_tests((CONTAINER_TYPE<double>*) 0);
}
}
#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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(BOOST_NO_0X_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,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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(BOOST_NO_0X_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,77 +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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <string>
#include "./compile_time.hpp"
void string_tests()
{
compile_time_tests((std::string*) 0);
HASH_NAMESPACE::hash<std::string> x1;
HASH_NAMESPACE::hash<std::string> x2;
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
BOOST_TEST(x1("") == x2(std::string()));
#if defined(TEST_EXTENSIONS)
std::string value1;
std::string value2("Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
#if !defined(BOOST_NO_STD_WSTRING)
void wstring_tests()
{
compile_time_tests((std::wstring*) 0);
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(TEST_EXTENSIONS)
std::wstring value1;
std::wstring value2(L"Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
#endif
int main()
{
string_tests();
#if !defined(BOOST_NO_STD_WSTRING)
wstring_tests();
#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 TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if !defined(BOOST_NO_0X_HDR_TYPEINDEX)
#include <typeindex>
void test_type_index() {
HASH_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(HASH_NAMESPACE::hash_value(int_index) == int_index.hash_code());
BOOST_TEST(HASH_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
BOOST_TEST(HASH_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_0X_HDR_TYPEINDEX)
test_type_index();
#else
std::cout<<"<type_index> not available."<<std::endl;
#endif
return boost::report_errors();
}

View File

@@ -1,64 +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 compilers hash_value isn't available for arrays, so I test it
// separately from the main array tests.
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
void array_int_test()
{
const int array1[25] = {
26, -43, 32, 65, 45,
12, 67, 32, 12, 23,
0, 0, 0, 0, 0,
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
HASH_NAMESPACE::hash<int[25]> hasher1;
int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2;
int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher;
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
}
#endif
int main()
{
#ifdef TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif
return boost::report_errors();
}

View File

@@ -1,35 +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 TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#include <vector>
using std::vector;
#define CONTAINER_TYPE vector
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
vector_tests::vector_hash_integer_tests();
#endif
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/functional/hash.hpp>
namespace test
{
struct base {};
std::size_t hash_value(base const&) { return 0; }
struct converts { operator base() const { return base(); } };
}
int main() {
boost::hash<test::converts> hash;
test::converts x;
hash(x);
}

View File

@@ -1,33 +0,0 @@
// 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"
#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 HASH_NAMESPACE::hash<int*> works in both files.
HASH_NAMESPACE::hash<int*> ptr_hasher;
BOOST_TEST(hash1 == ptr_hasher(x1));
#if defined(TEST_EXTENSIONS)
// Check that std::vector<std::size_t> is avaiable in this file.
std::vector<std::size_t> x;
x.push_back(*x1);
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
#else
return 0;
#endif
}

View File

@@ -1,20 +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"
#define HASH_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
extern int f(std::size_t, int*);
int main() {
HASH_NAMESPACE::hash<int*> ptr_hasher;
int x = 55;
BOOST_TEST(!f(ptr_hasher(&x), &x));
return boost::report_errors();
}

View File

@@ -1,11 +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"
#include <boost/functional/hash.hpp>
extern int f();
int main() { return f(); }

View File

@@ -1,10 +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"
#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/functional/hash.hpp>
typedef list<int> foo;
int main() {}