Compare commits

...

148 Commits

Author SHA1 Message Date
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
dfe0ad3a60 Hash: Merge test fix.
[SVN r78854]
2012-06-07 19:50:10 +00:00
Daniel James
806abd0ddf Hash: Only use typeid when available.
[SVN r78755]
2012-05-29 19:41:19 +00:00
Daniel James
c409903f5e Hash: Merge deprecated header warning + some documentation.
[SVN r78697]
2012-05-27 21:13:49 +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
Lorenzo Caminiti
033ef4b507 Merged ScopeExit (improved), LocalFunction (new), Functional/OverloadedFunction (new), and Utility/IdentityType (new) from trunk into release branch.
[SVN r78564]
2012-05-24 01:35:04 +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
18b143cad1 Unordered: Merge unordered from trunk.
- Activate `std::allocator_traits` for gcc 4.7 and Visual C++ 11.
- Implement variadic construct in `boost::unordered::detail::allocator_traits`
  when variadics, rvalue references and SFINAE expression are available.
- Use variadic construct from `allocator_traits`, or when not available move
  the logic for constructing `value_type` to a lower level, so the container
  code is a bit simpler.
- Avoid `-Wshadow` warnings. Fixes #6190.
- Implement `reserve`. Fixes #6857.


[SVN r78432]
2012-05-12 08:14:05 +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
346e62f53f Unordered/Hash: Merge from trunk.
[SVN r78319]
2012-05-03 22:05:21 +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
Daniel James
9a38ebf8c3 Hash: Merge documentation fix.
[SVN r76955]
2012-02-09 09:26:00 +00:00
Daniel James
a6f8c51afb Hash: Fix 1.6 quickbook in 1.5 document.
[SVN r76703]
2012-01-26 08:17:11 +00:00
Daniel James
903b1e409e Hash: Merge documentation changes.
[SVN r76533]
2012-01-15 20:49:40 +00:00
Daniel James
eb040cb89b Hash: Improve rationale slightly.
[SVN r75542]
2011-11-18 09:03:29 +00:00
Daniel James
d92209d725 Hash: Use quickbook 1.5
[SVN r75541]
2011-11-18 09:02:47 +00:00
Daniel James
58e42260d5 Merge unordered+hash documentation updates.
[SVN r75015]
2011-10-17 20:23:27 +00:00
Daniel James
56293f4313 Hash: A few edits to the new rationale.
[SVN r74963]
2011-10-16 10:32:12 +00:00
Daniel James
335930c652 Hash: Remove info for compilers that are no longer supported.
[SVN r74857]
2011-10-09 18:22:11 +00:00
Daniel James
da096ddf8c Hash: Note about the quality of the hash function.
In response to the thread starting at:

http://lists.boost.org/Archives/boost/2011/10/186476.php

[SVN r74856]
2011-10-09 18:14:50 +00:00
Daniel James
15bc3339e2 Hash: merge updated tests.
- Remove shared_ptr_fail_test, since shared_ptr now has a hash function.
- Run several tests with and without implicit casts.


[SVN r70445]
2011-03-23 00:10:03 +00:00
Daniel James
8c0e9a2b09 Run some tests without BOOST_HASH_NO_IMPLICIT_CASTS.
[SVN r69854]
2011-03-11 18:19:23 +00:00
Daniel James
664522596f Remove shared_ptr fail test since it now supports Boost.Hash
[SVN r69853]
2011-03-11 18:17:48 +00:00
Daniel James
cc0710b8a2 Merge typeindex support for hash. Fixes #4756.
[SVN r68199]
2011-01-17 04:15:00 +00:00
Daniel James
ce885af9b0 Fix copy and paste typo. Refs #4756.
[SVN r68182]
2011-01-16 11:06:00 +00:00
Daniel James
9e641187c6 Oops, make new hash_value overload inline.
[SVN r68147]
2011-01-14 03:36:39 +00:00
Daniel James
7dc95d044d Support typeindex in hash. Refs #4756.
[SVN r68145]
2011-01-14 03:13:39 +00:00
Daniel James
ad614b3d5f Move tests for container_fwd.hpp into detail.
[SVN r67667]
2011-01-04 23:30:22 +00:00
Daniel James
fc7eb28826 Merge hash from trunk.
- Avoid `-Wconversion` warnings.


[SVN r67664]
2011-01-04 23:06:53 +00:00
Daniel James
ed598f865e Fix tabs and files without copyright.
[SVN r67612]
2011-01-03 12:43:34 +00:00
Daniel James
482f038837 Avoid -Wconversion warnings in unordered & hash.
[SVN r67170]
2010-12-11 14:43:00 +00:00
Daniel James
a2e947588d Import boostbook/quickbook in unordered and hash docs.
[SVN r67091]
2010-12-07 20:45:08 +00:00
Daniel James
982b350d71 Remove some 'always_show_run_output' flags.
[SVN r66566]
2010-11-14 11:42:58 +00:00
Daniel James
80b88f24c1 Merge OpenVMS 64 bit patch for hash. Fixes #4477.
[SVN r64869]
2010-08-17 20:00:17 +00:00
Daniel James
577054de93 Fix hashing pointers on 64-bit OpenVMS.
Patch by Artyom. Refs #4477

[SVN r64397]
2010-07-27 19:18:53 +00:00
Daniel James
fc3b3863b4 Only include static_assert when necessary.
[SVN r64009]
2010-07-14 08:28:04 +00:00
Daniel James
906f632706 Actually, make the change to hash opt-in, rather than opt-out. It's a bit late to introduce a breaking change.
[SVN r64007]
2010-07-14 08:17:48 +00:00
Daniel James
bbfb6fd32c Release notes for hash.
[SVN r63810]
2010-07-10 13:47:47 +00:00
Daniel James
38d131c158 Fix inspect issues.
[SVN r63762]
2010-07-08 20:48:30 +00:00
Daniel James
2553a5fbdc Try preventing static casts when calling hash_value.
[SVN r63716]
2010-07-06 23:32:37 +00:00
66 changed files with 1744 additions and 889 deletions

39
.travis.yml Normal file
View File

@@ -0,0 +1,39 @@
# 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-dev
- libboost-tools-dev
matrix:
include:
- compiler: gcc
env: BJAM_TOOLSET=gcc-std03
- compiler: gcc
env: BJAM_TOOLSET=gcc-std11
- compiler: clang
env: BJAM_TOOLSET=clang-std03
- compiler: clang
env: BJAM_TOOLSET=clang-std11
before_script:
- |
echo "using gcc : std03 : g++-4.8 --std=c++03 ;" > ~/user-config.jam
echo "using gcc : std11 : g++-4.8 --std=c++11 ;" >> ~/user-config.jam
echo "using clang : std03 : clang++ --std=c++03 ;" >> ~/user-config.jam
echo "using clang : std11 : clang++ --std=c++11 ;" >> ~/user-config.jam
- cat ~/user-config.jam
- touch Jamroot.jam
script:
- cd ${TRAVIS_BUILD_DIR}/test
- bjam -q ${BJAM_TOOLSET} include=${TRAVIS_BUILD_DIR}/include

View File

@@ -3,6 +3,9 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
using boostbook ;
using quickbook ;
xml hash : hash.qbk ;
boostbook standalone : hash :
<xsl:param>boost.root=../../../..

View File

@@ -3,6 +3,8 @@
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
[section:changes Change Log]
[h2 Boost 1.33.0]
@@ -119,4 +121,62 @@
it's opt-in for now. This, or something like it, will become the
default in a future version.
[h2 Boost 1.46.0]
* Avoid warning due with gcc's `-Wconversion` flag.
[h2 Boost 1.50.0]
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
Avoid gcc's `-Wfloat-equal` warning.
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
Support `std::array` and `std::tuple` when available.
* Add deprecation warning to the long deprecated
`boost/functional/detail/container_fwd.hpp`.
[h2 Boost 1.51.0]
* Support the standard smart pointers.
* `hash_value` now implemented using SFINAE to avoid implicit casts to built
in types when calling it.
* Updated to use the new config macros.
[h2 Boost 1.52.0]
* Restore `enum` support, which was accidentally removed in the last version.
* New floating point hasher - will hash the binary representation on more
platforms, which should be faster.
[h2 Boost 1.53.0]
* Add support for `boost::int128_type` and `boost::uint128_type` where
available - currently only `__int128` and `unsigned __int128` on some
versions of gcc.
* On platforms that are known to have the standard floating point functions,
don't use automatic detection - which can break if there are ambiguous
overloads.
* Fix undefined behaviour when using the binary float hash (Thomas Heller).
[h2 Boost 1.54.0]
* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]:
Fixed a typo.
[h2 Boost 1.55.0]
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9
([ticket 8822]).
* Suppress Visual C++ infinite loop warning ([ticket 8568]).
[h2 Boost 1.56.0]
* Removed some Visual C++ 6 workarounds.
* Ongoing work on improving `hash_combine`. This changes the combine function
which was previously defined in the reference documentation.
[h2 Boost 1.58.0]
* Fixed strict aliasing violation
([@https://github.com/boostorg/functional/pull/3 GitHub #3]).
[endsect]

View File

@@ -1,5 +1,5 @@
[library Boost.Functional/Hash
[quickbook 1.4]
[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
@@ -14,11 +14,16 @@
]
]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[include:hash intro.qbk]
[include:hash 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

@@ -18,9 +18,6 @@
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
@@ -44,5 +41,12 @@ __issues__ (page 63), this adds support for:
* the standard containers.
* extending [classref boost::hash] for custom types.
[note
This hash function is designed to be used in containers based on
the STL and is not suitable as a general purpose hash function.
For more details see the [link hash.rationale rationale].
]
[endsect]

View File

@@ -90,16 +90,4 @@ boost namespace:
Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[h2 Other Issues]
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
When using GCC on Solaris, `boost::hash_value(long double)` treats
`long double`s as `double`s - so the hash function doesn't take into account the
full range of values.
[endsect]

50
doc/rationale.qbk Normal file
View File

@@ -0,0 +1,50 @@
[/ Copyright 2011 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:rationale Rationale]
The rationale can be found in the original design
[footnote issue 6.18 of the __issues__ (page 63)].
[heading Quality of the hash function]
Many hash functions strive to have little correlation between the input
and output values. They attempt to uniformally distribute the output
values for very similar inputs. This hash function makes no such
attempt. In fact, for integers, the result of the hash function is often
just the input value. So similar but different input values will often
result in similar but different output values.
This means that it is not appropriate as a general hash function. For
example, a hash table may discard bits from the hash function resulting
in likely collisions, or might have poor collision resolution when hash
values are clustered together. In such cases this hash function will
preform poorly.
But the standard has no such requirement for the hash function,
it just requires that the hashes of two different values are unlikely
to collide. Containers or algorithms
designed to work with the standard hash function will have to be
implemented to work well when the hash function's output is correlated
to its input. Since they are paying that cost a higher quality hash function
would be wasteful.
For other use cases, if you do need a higher quality hash function,
then neither the standard hash function or `boost::hash` are appropriate.
There are several options
available. One is to use a second hash on the output of this hash
function, such as [@http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm
Thomas Wang's hash function]. This this may not work as
well as a hash algorithm tailored for the input.
For strings there are several fast, high quality hash functions
available (for example [@http://code.google.com/p/smhasher/ MurmurHash3]
and [@http://code.google.com/p/cityhash/ Google's CityHash]),
although they tend to be more machine specific.
These may also be appropriate for hashing a binary representation of
your data - providing that all equal values have an equal
representation, which is not always the case (e.g. for floating point
values).
[endsect]

View File

@@ -55,6 +55,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
is defined. The specializations are still defined, so only the specializations
required by TR1 are defined.
</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws><para>
Only throws if
@@ -406,6 +415,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::type_index</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::type_index</paramtype>
</parameter>
<returns>
<para><code>val.hash_code()</code></para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
<notes>
<para>
Only available if it's in your standard library and Boost.Config
is aware of it.
</para>
</notes>
</struct-specialization>
<free-function-group name="Support functions (Boost extension).">
<!--
@@ -423,11 +455,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Called repeatedly to incrementally create a hash value from
several variables.
</simpara></purpose>
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed &lt;&lt; 6) + (seed &gt;&gt; 2);</programlisting></effects>
<effects>
Updates <code>seed</code> with a new hash value generated by
combining it with the result of
<code><functionname>hash_value</functionname>(v)</code>. Will
always produce the same result for the same combination of
<code>seed</code> and
<code><functionname>hash_value</functionname>(v)</code> during
the single run of a program.
</effects>
<notes>
<para><functionname>hash_value</functionname> is called without
qualification, so that overloads can be found via ADL.</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws>
Only throws if <functionname>hash_value</functionname>(T) throws.
@@ -476,15 +525,14 @@ for(; first != last; ++first)
return seed;
</programlisting>
</para>For the three arguments overload:
</para>
<para>For the three arguments overload:</para>
<programlisting>
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
</programlisting>
<para>
</para>
</effects>
<notes>
<para>
@@ -493,6 +541,15 @@ for(; first != last; ++first)
container.
</para>
<para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/functional/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
@@ -716,6 +773,30 @@ for(; first != last; ++first)
<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>
@@ -726,6 +807,11 @@ for(; first != last; ++first)
<notes>
<para>This is an extension to TR1</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes>
<throws>
@@ -781,7 +867,8 @@ for(; first != last; ++first)
<code>std::set&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::map&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>
<code>std::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>
@@ -790,6 +877,14 @@ for(; first != last; ++first)
<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>
@@ -798,6 +893,12 @@ return seed;</programlisting></entry>
</entry>
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry>
<code>std::type_index</code>
</entry>
<entry><code>val.hash_code()</code></entry>
</row>
</tbody>
</tgroup>
</informaltable>

View File

@@ -198,5 +198,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
std::vector<std::string> some_strings;
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
[endsect]
Note that when writing template classes, you might not want to include the main
hash header as it's quite an expensive include that brings in a lot of other
headers, so instead you can include the `<boost/functional/hash_fwd.hpp>`
header which forward declares [classref boost::hash],
[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
include the main header before instantiating [classref boost::hash]. When using
a container that uses [classref boost::hash] it should do that for you, so your
type will work fine with the boost hash containers. There's an example of this
in [@boost:/libs/functional/hash/examples/template.hpp template.hpp] and
[@boost:/libs/functional/hash/examples/template.cpp template.cpp].
[endsect]

View File

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

View File

@@ -3,6 +3,11 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/functional/hash.hpp>
#include <cassert>

View File

@@ -3,6 +3,11 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/functional/hash.hpp>
#include <cassert>

18
examples/template.cpp Normal file
View File

@@ -0,0 +1,18 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "template.hpp"
#include <cassert>
#include <boost/unordered_set.hpp>
int main()
{
typedef my_pair<int, float> pair;
boost::unordered_set<pair> pair_set;
pair_set.emplace(10, 0.5f);
assert(pair_set.find(pair(10, 0.5f)) != pair_set.end());
assert(pair_set.find(pair(10, 0.6f)) == pair_set.end());
}

36
examples/template.hpp Normal file
View File

@@ -0,0 +1,36 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// This is an example of how to write a hash function for a template
// class.
#include <boost/functional/hash_fwd.hpp>
template <typename A, typename B>
class my_pair
{
A value1;
B value2;
public:
my_pair(A const& v1, B const& v2)
: value1(v1), value2(v2)
{}
bool operator==(my_pair const& other) const
{
return value1 == other.value1 &&
value2 == other.value2;
}
friend std::size_t hash_value(my_pair const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.value1);
boost::hash_combine(seed, p.value2);
return seed;
}
};

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)
// Forwarding header for container_fwd.hpp's new location.
// This header is deprecated, I'll be adding a warning in a future release,
// then converting it to an error and finally removing this header completely.
#if !defined(BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP)
#define BOOST_FUNCTIONAL_DETAIL_CONTAINER_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/detail/container_fwd.hpp>
#endif

View File

@@ -7,12 +7,100 @@
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
// Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
// sufficiently good floating point support to not require any
// workarounds.
//
// When set to 0, the library tries to automatically
// use the best available implementation. This normally works well, but
// breaks when ambiguities are created by odd namespacing of the functions.
//
// Note that if this is set to 0, the library should still take full
// advantage of the platform's floating point support.
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__LIBCOMO__)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// Rogue Wave library:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(_LIBCPP_VERSION)
// libc++
# define BOOST_HASH_CONFORMANT_FLOATS 1
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
// GNU libstdc++ 3
# if defined(__GNUC__) && __GNUC__ >= 4
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(__STL_CONFIG_H)
// generic SGI STL
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__MSL_CPP__)
// MSL standard lib:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__IBMCPP__)
// VACPP std lib (probably conformant for much earlier version).
# if __IBMCPP__ >= 1210
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(MSIPL_COMPILE_H)
// Modena C++ standard library
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library (this has to appear after any possible replacement libraries):
# if _CPPLIB_VER >= 405
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#else
# define BOOST_HASH_CONFORMANT_FLOATS 0
#endif
#if BOOST_HASH_CONFORMANT_FLOATS
// The standard library is known to be compliant, so don't use the
// configuration mechanism.
namespace boost {
namespace hash_detail {
template <typename Float>
struct call_ldexp {
typedef Float float_type;
inline Float operator()(Float x, int y) const {
return std::ldexp(x, y);
}
};
template <typename Float>
struct call_frexp {
typedef Float float_type;
inline Float operator()(Float x, int* y) const {
return std::frexp(x, y);
}
};
template <typename Float>
struct select_hash_type
{
typedef Float type;
};
}
}
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
@@ -243,4 +331,6 @@ namespace boost
}
}
#endif // BOOST_HASH_CONFORMANT_FLOATS
#endif

View File

@@ -1,33 +1,31 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2005-2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <cstring>
// 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>
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
// Can we use fpclassify?
@@ -50,6 +48,153 @@
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
////////////////////////////////////////////////////////////////////////
// Binary hash function
//
// Only used for floats with known iec559 floats, and certain values in
// numeric_limits
inline std::size_t hash_binary(char* ptr, std::size_t length)
{
std::size_t seed = 0;
if (length >= sizeof(std::size_t)) {
std::memcpy(&seed, ptr, sizeof(std::size_t));
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
while(length >= sizeof(std::size_t)) {
std::size_t buffer = 0;
std::memcpy(&buffer, ptr, sizeof(std::size_t));
hash_float_combine(seed, buffer);
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
}
}
if (length > 0) {
std::size_t buffer = 0;
std::memcpy(&buffer, ptr, length);
hash_float_combine(seed, buffer);
}
return seed;
}
template <typename Float, unsigned digits, unsigned max_exponent>
struct enable_binary_hash
{
BOOST_STATIC_CONSTANT(bool, value =
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == digits &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == max_exponent);
};
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 24, 128>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 4);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 53, 1024>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 8);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 64, 16384>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 10);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 113, 16384>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 16);
}
////////////////////////////////////////////////////////////////////////
// Portable hash function
//
// Used as a fallback when the binary hash function isn't supported.
template <class T>
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
v = ldexp(v, limits<std::size_t>::digits);
std::size_t seed = static_cast<std::size_t>(v);
v -= static_cast<T>(seed);
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value
+ limits<std::size_t>::digits - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= static_cast<T>(part);
hash_float_combine(seed, part);
}
hash_float_combine(seed, exp);
return seed;
}
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
template <class T>
inline std::size_t float_hash_impl(T v, ...)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
#endif
}
}
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
@@ -61,8 +206,15 @@ namespace boost
template <class T>
inline std::size_t float_hash_value(T v)
{
#if defined(fpclassify)
switch (fpclassify(v))
#elif BOOST_HASH_CONFORMANT_FLOATS
switch (std::fpclassify(v))
#else
using namespace std;
switch (fpclassify(v)) {
switch (fpclassify(v))
#endif
{
case FP_ZERO:
return 0;
case FP_INFINITE:
@@ -71,7 +223,7 @@ namespace boost
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v);
return float_hash_impl(v, 0);
default:
BOOST_ASSERT(0);
return 0;
@@ -86,10 +238,24 @@ 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 v == 0 ? 0 : float_hash_impl(v);
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
}
}
}
@@ -98,4 +264,8 @@ namespace boost
#undef BOOST_HASH_USE_FPCLASSIFY
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#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 -= 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 -= 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

@@ -9,8 +9,9 @@
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/limits.hpp>

View File

@@ -13,21 +13,34 @@
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/functional/hash/hash.hpp>
#include <boost/detail/container_fwd.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/static_assert.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
# include <tuple>
#endif
#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
# include <memory>
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#include <boost/type_traits/is_const.hpp>
#endif
namespace boost
{
template <class A, class B>
@@ -54,51 +67,51 @@ namespace boost
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
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 hash_range(v.begin(), v.end());
return boost::hash_range(v.begin(), v.end());
}
template <class T>
@@ -110,6 +123,83 @@ namespace boost
return seed;
}
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
template <class T, std::size_t N>
std::size_t hash_value(std::array<T, N> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
namespace hash_detail {
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t&, T const&)
{
}
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t& seed, T const& v)
{
boost::hash_combine(seed, std::get<I>(v));
boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
}
template <typename T>
inline std::size_t hash_tuple(T const& v)
{
std::size_t seed = 0;
boost::hash_detail::hash_combine_tuple<0>(seed, v);
return seed;
}
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... T>
inline std::size_t hash_value(std::tuple<T...> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
#else
inline std::size_t hash_value(std::tuple<> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
# define BOOST_HASH_TUPLE_F(z, n, _) \
template< \
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
> \
inline std::size_t hash_value(std::tuple< \
BOOST_PP_ENUM_PARAMS_Z(z, n, A) \
> const& v) \
{ \
return boost::hash_detail::hash_tuple(v); \
}
BOOST_PP_REPEAT_FROM_TO(1, 11, BOOST_HASH_TUPLE_F, _)
# undef BOOST_HASH_TUPLE_F
#endif
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
inline std::size_t hash_value(std::shared_ptr<T> const& x) {
return boost::hash_value(x.get());
}
template <typename T, typename Deleter>
inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
return boost::hash_value(x.get());
}
#endif
//
// call_hash_impl
//
@@ -139,11 +229,7 @@ namespace boost
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);
@@ -205,8 +291,6 @@ namespace boost
template <bool IsPointer>
struct hash_impl;
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct hash_impl<false>
{
@@ -227,58 +311,6 @@ namespace boost
#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
}

View File

@@ -1,11 +1,17 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2005-2014 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
//
// This also contains public domain code from MurmurHash. From the
// MurmurHash header:
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
@@ -15,15 +21,30 @@
#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
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
// are always of range '0' to '4294967295'.
// Loop executes infinitely.
#endif
#endif
#if BOOST_WORKAROUND(__GNUC__, < 3) \
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
@@ -31,40 +52,90 @@
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
#if defined(_MSC_VER)
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
#else
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
namespace boost
{
#if defined(BOOST_HASH_NO_IMPLICIT_CASTS)
namespace hash_detail
{
struct enable_hash_value { typedef std::size_t type; };
// 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;
}
template <typename T> struct basic_numbers {};
template <typename T> struct long_numbers;
template <typename T> struct ulong_numbers;
template <typename T> struct float_numbers {};
#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);
template <> struct basic_numbers<bool> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<signed char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<long> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned long> :
boost::hash_detail::enable_hash_value {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
std::size_t hash_value(wchar_t);
template <> struct basic_numbers<wchar_t> :
boost::hash_detail::enable_hash_value {};
#endif
// long_numbers is defined like this to allow for separate
// specialization for long_long and int128_type, in case
// they conflict.
template <typename T> struct long_numbers2 {};
template <typename T> struct ulong_numbers2 {};
template <typename T> struct long_numbers : long_numbers2<T> {};
template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
#if !defined(BOOST_NO_LONG_LONG)
std::size_t hash_value(boost::long_long_type);
std::size_t hash_value(boost::ulong_long_type);
template <> struct long_numbers<boost::long_long_type> :
boost::hash_detail::enable_hash_value {};
template <> struct ulong_numbers<boost::ulong_long_type> :
boost::hash_detail::enable_hash_value {};
#endif
#if defined(BOOST_HAS_INT128)
template <> struct long_numbers2<boost::int128_type> :
boost::hash_detail::enable_hash_value {};
template <> struct ulong_numbers2<boost::uint128_type> :
boost::hash_detail::enable_hash_value {};
#endif
template <> struct float_numbers<float> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<double> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<long double> :
boost::hash_detail::enable_hash_value {};
}
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T);
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
@@ -79,14 +150,17 @@ namespace boost
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&);
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::size_t hash_value(std::type_index);
#endif
// Implementation
namespace hash_detail
@@ -131,76 +205,79 @@ namespace boost
return seed;
}
template <typename SizeT>
inline void hash_combine_impl(SizeT& seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
inline void hash_combine_impl(boost::uint32_t& h1,
boost::uint32_t k1)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
k1 *= c1;
k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
}
// Don't define 64-bit hash combine on platforms without 64 bit integers,
// and also not for 32-bit gcc as it warns about the 64-bit constant.
#if !defined(BOOST_NO_INT64_T) && \
!(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
inline void hash_combine_impl(boost::uint64_t& h,
boost::uint64_t k)
{
const uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
// Completely arbitrary number, to prevent 0's
// from hashing to 0.
h += 0xe6546b64;
}
#endif // BOOST_NO_INT64_T
}
inline std::size_t hash_value(bool v)
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(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)
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_signed(v);
}
inline std::size_t hash_value(boost::ulong_long_type v)
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_unsigned(v);
}
#endif
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T v)
{
return static_cast<std::size_t>(v);
}
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
@@ -209,9 +286,15 @@ namespace boost
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);
}
@@ -225,16 +308,11 @@ namespace boost
#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);
return boost::hash_detail::hash_combine_impl(seed, hasher(v));
}
#if defined(BOOST_MSVC)
@@ -310,20 +388,18 @@ namespace boost
return hash_range(v.begin(), v.end());
}
inline std::size_t hash_value(float v)
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(double v)
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline std::size_t hash_value(std::type_index v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(long double v)
{
return boost::hash_detail::float_hash_value(v);
return v.hash_code();
}
#endif
//
// boost::hash
@@ -337,11 +413,10 @@ namespace boost
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by copy.
// passed by const reference.
//
// 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> \
@@ -361,45 +436,6 @@ namespace boost
return boost::hash_value(v); \
} \
};
#else
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(const type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#endif
BOOST_HASH_SPECIALIZE(bool)
BOOST_HASH_SPECIALIZE(char)
@@ -429,6 +465,15 @@ namespace boost
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#if defined(BOOST_HAS_INT128)
BOOST_HASH_SPECIALIZE(boost::int128_type)
BOOST_HASH_SPECIALIZE(boost::uint128_type)
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
BOOST_HASH_SPECIALIZE(std::type_index)
#endif
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
@@ -498,6 +543,11 @@ namespace boost
}
#undef BOOST_HASH_CHAR_TRAITS
#undef BOOST_FUNCTIONAL_HASH_ROTL32
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP

View File

@@ -10,11 +10,11 @@
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config.hpp>
#include <cstddef>
#include <boost/detail/workaround.hpp>
@@ -22,11 +22,7 @@ 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);

View File

@@ -3,5 +3,9 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash_fwd.hpp>
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/functional/hash/hash_fwd.hpp>

20
meta/libraries.json Normal file
View File

@@ -0,0 +1,20 @@
[
{
"key": "functional/hash",
"boost-version": "1.33.0",
"name": "Functional/Hash",
"authors": [
"Daniel James"
],
"maintainers": [
"Daniel James <dnljms -at- gmail.com>"
],
"description": "A TR1 hash function object that can be extended to hash user defined types.",
"std": [
"tr1"
],
"category": [
"Function-objects"
]
}
]

View File

@@ -1,5 +1,5 @@
# Copyright 2005-2008 Daniel James.
# Copyright 2005-2012 Daniel James.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,26 +7,27 @@ import testing ;
project hash-tests
: requirements
<define>BOOST_HASH_NO_IMPLICIT_CASTS
<warnings>all
<toolset>intel:<warnings>on
<toolset>intel:<cxxflags>-strict-ansi
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
<toolset>msvc:<warnings-as-errors>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
:
[ compile check_float_funcs.cpp ]
[ run hash_fwd_test_1.cpp ]
[ run hash_fwd_test_2.cpp ]
[ run hash_number_test.cpp ]
[ run hash_enum_test.cpp ]
[ run hash_pointer_test.cpp ]
[ run hash_function_pointer_test.cpp ]
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_long_double_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_float_test.cpp ]
[ run hash_long_double_test.cpp ]
[ run hash_string_test.cpp ]
[ run hash_range_test.cpp ]
[ run hash_custom_test.cpp ]
@@ -40,19 +41,16 @@ test-suite functional/hash
[ run hash_set_test.cpp ]
[ run hash_map_test.cpp ]
[ run hash_complex_test.cpp ]
[ run hash_type_index_test.cpp ]
[ run hash_std_array_test.cpp ]
[ run hash_std_tuple_test.cpp ]
[ run hash_std_smart_ptr_test.cpp ]
[ run link_test.cpp link_test_2.cpp ]
[ run link_ext_test.cpp link_no_ext_test.cpp ]
[ run extensions_hpp_test.cpp ]
[ run container_fwd_test.cpp ]
[ run container_fwd_test.cpp : :
: <toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<define>_GLIBCXX_DEBUG
: container_fwd_gcc_debug ]
[ run container_no_fwd_test.cpp ]
[ compile-fail hash_no_ext_fail_test.cpp ]
[ compile-fail namespace_fail_test.cpp ]
[ compile-fail implicit_fail_test.cpp ]
[ compile-fail shared_ptr_fail_test.cpp ]
[ run implicit_test.cpp ]
[ run hash_no_ext_macro_1.cpp ]
[ run hash_no_ext_macro_2.cpp ]
;
@@ -68,4 +66,17 @@ test-suite functional/hash_no_ext
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
;
# Tests to see if the floating point hash is using the binary hash.
# Not run normally because on some platforms these should fail.
test-suite functional/hash_no_generic_float
:
[ run hash_float_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_float_test_no_generic ]
[ run hash_long_double_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_long_double_test_no_generic ]
;
explicit functional/hash_no_generic_float ;
build-project ../examples ;

View File

@@ -0,0 +1,58 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cmath>
namespace test
{
template <class T1>
struct check_return_type
{
template <class T2>
static void equals(T2)
{
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
}
template <class T2>
static void equals_ref(T2&)
{
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
}
template <class T2>
static void convertible(T2)
{
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
}
};
}
int main() {
float f = 0;
double d = 0;
long double l = 0;
test::check_return_type<float>::equals(std::ldexp(f, 0));
test::check_return_type<double>::equals(std::ldexp(d, 0));
test::check_return_type<long double>::equals(std::ldexp(l, 0));
int dummy = 0;
test::check_return_type<float>::equals(std::frexp(f, &dummy));
test::check_return_type<double>::equals(std::frexp(d, &dummy));
test::check_return_type<long double>::equals(std::frexp(l, &dummy));
#if BOOST_HASH_USE_FPCLASSIFY
int (*fpc1)(float) = std::fpclassify;
int (*fpc2)(double) = std::fpclassify;
int (*fpc3)(long double) = std::fpclassify;
#endif
}

View File

@@ -11,6 +11,6 @@ template <class T>
void compile_time_tests(T*)
{
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
std::unary_function<T, std::size_t>, BOOST_HASH_TEST_NAMESPACE::hash<T> >::value));
}

View File

@@ -3,13 +3,13 @@
// Distributed under the 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
#if defined(BOOST_HASH_TEST_STD)
# define BOOST_HASH_TEST_STD_INCLUDES
# define BOOST_HASH_TEST_NAMESPACE std
#else
# define HASH_NAMESPACE boost
# define BOOST_HASH_TEST_NAMESPACE boost
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define TEST_EXTENSIONS
# define BOOST_HASH_TEST_EXTENSIONS
# endif
#endif

View File

@@ -1,114 +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/detail/container_fwd.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && \
!defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
template <class charT, class Allocator>
static void test(
std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
{
}
#else
template <class charT, class Allocator>
static void test(
std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
{
}
#endif
template <class T, class Allocator>
static void test(std::deque<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::list<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::vector<T, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::map<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::multimap<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::set<Key, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::multiset<Key, Compare, Allocator> const&)
{
}
template <std::size_t N>
static void test(std::bitset<N> const&)
{
}
template <class T>
static void test(std::complex<T> const&)
{
}
template <class X, class Y>
static void test(std::pair<X, Y> const&)
{
}
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#include <utility>
int main()
{
std::deque<int> x1;
std::list<std::string> x2;
std::vector<float> x3;
std::vector<bool> x4;
std::map<int, int> x5;
std::multimap<float, int*> x6;
std::set<std::string> x7;
std::multiset<std::vector<int> > x8;
std::bitset<10> x9;
std::string x10;
std::complex<double> x11;
std::pair<std::list<int>, char***> x12;
test(x1);
test(x2);
test(x3);
test(x4);
test(x5);
test(x6);
test(x7);
test(x8);
test(x9);
test(x10);
test(x11);
test(x12);
return 0;
}

View File

@@ -1,14 +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)
#define BOOST_DETAIL_NO_CONTAINER_FWD
#include <boost/detail/container_fwd.hpp>
int main()
{
std::set<int> x;
std::vector<std::string> y;
}

View File

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

View File

@@ -5,13 +5,13 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS)
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
@@ -35,6 +35,10 @@ int main() {}
#endif
#endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <complex>
#include <sstream>
#include <boost/limits.hpp>
@@ -42,11 +46,11 @@ int main() {}
template <class T>
void generic_complex_tests(std::complex<T> v)
{
HASH_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
HASH_NAMESPACE::hash<T> real_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
T real = v.real();
T imag = v.imag();
@@ -69,7 +73,7 @@ void complex_float_tests(Float*)
generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(-67.5324535,56.23578678));
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
}
template <class Integer>
@@ -103,4 +107,4 @@ int main()
return boost::report_errors();
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS

View File

@@ -41,8 +41,8 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -51,7 +51,7 @@ namespace boost
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -59,13 +59,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -75,25 +75,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -5,8 +5,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -15,7 +15,7 @@
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <deque>
@@ -23,11 +23,11 @@ using std::deque;
#define CONTAINER_TYPE deque
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
deque_tests::deque_hash_integer_tests();
#endif

63
test/hash_enum_test.cpp Normal file
View File

@@ -0,0 +1,63 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include "./compile_time.hpp"
namespace test {
enum enum_override { enum_override1, enum_override2 };
std::size_t hash_value(enum_override) { return 896532; }
enum enum1 { enum1a };
enum enum2 { enum2a, enum2b };
enum enum3 { enum3a = 574, enum3b };
enum enum4 { enum4a = -12574, enum4b };
}
int main() {
compile_time_tests((test::enum1*) 0);
compile_time_tests((test::enum2*) 0);
compile_time_tests((test::enum3*) 0);
compile_time_tests((test::enum4*) 0);
compile_time_tests((test::enum_override*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<test::enum1> hash1;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum2> hash2;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum3> hash3;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum4> hash4;
BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
BOOST_HASH_TEST_NAMESPACE::hash<test::enum_override> hash_override;
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override2));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
return boost::report_errors();
}

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
@@ -30,6 +30,10 @@
#endif
#endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
char const* float_type(float*) { return "float"; }
char const* float_type(double*) { return "double"; }
char const* float_type(long double*) { return "long double"; }
@@ -39,7 +43,7 @@ void float_tests(char const* name, T* = 0)
{
std::cerr
<< "\n"
<< "Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"
<< "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
<< name
<< ">\n"
<< "\n"
@@ -66,7 +70,7 @@ void float_tests(char const* name, T* = 0)
<< "\n"
;
HASH_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
T zero = 0;
T minus_zero = (T) -1 * zero;
@@ -74,9 +78,9 @@ void float_tests(char const* name, T* = 0)
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));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
#endif
BOOST_TEST(x1(zero) != x1(0.5));
@@ -102,10 +106,10 @@ void float_tests(char const* name, T* = 0)
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));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity));
== BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
#endif
if(infinity == infinity2)
@@ -187,12 +191,12 @@ void float_tests(char const* name, T* = 0)
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));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) ==
HASH_NAMESPACE::hash_value(three_quarter_max));
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
#endif
// The '!=' tests could legitimately fail, but with my hash it indicates a
@@ -223,16 +227,16 @@ void float_tests(char const* name, 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));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
#endif
#endif
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::epsilon()));
#endif
@@ -265,12 +269,12 @@ void float_tests(char const* name, T* = 0)
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)
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of boost::hash_detail::limits::denorm_min() for long
// doubles which causes this test to fail.
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
HASH_NAMESPACE::hash_value(
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()))
{
std::cerr
@@ -278,7 +282,7 @@ void float_tests(char const* name, T* = 0)
<< x1(boost::hash_detail::limits<T>::denorm_min())
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
" = "
<< HASH_NAMESPACE::hash_value(
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "
<< x1(0)
@@ -288,13 +292,13 @@ void float_tests(char const* name, T* = 0)
}
// NaN also causes borland to crash.
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS)
#if !defined(__BORLANDC__) && defined(BOOST_HASH_TEST_EXTENSIONS)
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(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_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
}
#endif

View File

@@ -44,8 +44,8 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -54,7 +54,7 @@ namespace boost
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -62,13 +62,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom<int> x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -78,25 +78,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -5,17 +5,13 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void void_func1() { static int x = 1; ++x; }
@@ -28,8 +24,8 @@ void function_pointer_tests()
compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0);
HASH_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_TEST(&void_func1 != &void_func2);
BOOST_TEST(&int_func1 != &int_func2);
@@ -42,11 +38,11 @@ void function_pointer_tests()
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(hasher_void(&void_func1)
== HASH_NAMESPACE::hash_value(&void_func1));
== BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
BOOST_TEST(hasher_int(&int_func1)
== HASH_NAMESPACE::hash_value(&int_func1));
== BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal:
BOOST_TEST(hasher_void(0) == 0);

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/functional/hash_fwd.hpp>
#include <boost/config.hpp>
@@ -25,7 +25,7 @@ namespace test {
template <class T>
std::size_t hash_value(test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
#endif
@@ -42,8 +42,8 @@ namespace test {
std::size_t hash_value(test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
#endif
@@ -61,8 +61,8 @@ namespace test {
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());
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
#endif
@@ -76,7 +76,7 @@ namespace boost
template <class T>
std::size_t hash_value(test::test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
@@ -84,8 +84,8 @@ namespace boost
std::size_t hash_value(test::test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
@@ -93,8 +93,8 @@ namespace boost
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());
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
}

View File

@@ -11,7 +11,7 @@
#include <boost/detail/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/functional/hash.hpp>
#include <string>
@@ -21,10 +21,10 @@ void fwd_test1()
test::test_type1<int> x(5);
test::test_type1<std::string> y("Test");
HASH_NAMESPACE::hash<int> hasher_int;
HASH_NAMESPACE::hash<std::string> hasher_string;
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
@@ -36,15 +36,15 @@ void fwd_test2()
test::test_type2<std::string> y("Test1", "Test2");
std::size_t seed1 = 0;
HASH_NAMESPACE::hash_combine(seed1, 5);
HASH_NAMESPACE::hash_combine(seed1, 10);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -69,15 +69,15 @@ void fwd_test3()
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());
BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 =
HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -87,7 +87,7 @@ void fwd_test3()
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
fwd_test1();
fwd_test2();
fwd_test3();

View File

@@ -8,7 +8,7 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
int main() {}
@@ -44,4 +44,4 @@ int main()
return boost::report_errors();
}
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)

View File

@@ -42,8 +42,8 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -52,7 +52,7 @@ namespace boost
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector>
#include <string>
@@ -60,13 +60,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<custom> custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -76,26 +76,26 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, custom(5));
HASH_NAMESPACE::hash_combine(seed, custom(25));
HASH_NAMESPACE::hash_combine(seed, custom(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();

View File

@@ -5,8 +5,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -15,7 +15,7 @@
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <list>
@@ -23,11 +23,11 @@ using std::list;
#define CONTAINER_TYPE list
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
list_tests::list_hash_integer_tests();
#endif

View File

@@ -5,8 +5,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -17,7 +17,7 @@
#include <map>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
using std::map;
#define CONTAINER_TYPE map
@@ -27,11 +27,11 @@ using std::multimap;
#define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp"
#endif // TEST_EXTENSTIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
map_tests::map_hash_integer_tests();
multimap_tests::multimap_hash_integer_tests();
#endif

View File

@@ -38,16 +38,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[9].insert(pair(key(-1),value(3)));
containers[9].insert(pair(key(-1),value(3)));
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
== BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {

View File

@@ -11,7 +11,7 @@
# define BOOST_HASH_NO_EXTENSIONS
#endif
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
@@ -21,7 +21,7 @@ template <class T> void ignore(T const&) {}
int main()
{
HASH_NAMESPACE::hash< int[10] > hasher;
BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
return 0;

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# if defined(BOOST_HASH_NO_EXTENSIONS)
@@ -23,14 +23,14 @@
int main()
{
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::deque<int> x;
x.push_back(1);
x.push_back(2);
HASH_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# if !defined(BOOST_HASH_NO_EXTENSIONS)
@@ -23,14 +23,14 @@
int main()
{
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::map<int, int> x;
x.insert(std::map<int, int>::value_type(53, -42));
x.insert(std::map<int, int>::value_type(14, -75));
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
@@ -16,8 +16,7 @@
#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 <boost/utility/enable_if.hpp>
#include "./compile_time.hpp"
@@ -28,15 +27,41 @@
#pragma warning(disable:4310) // cast truncates constant value
#endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T>
void numeric_test(T*)
void numeric_extra_tests(typename
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
typedef boost::hash_detail::limits<T> limits;
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
template <class T>
void numeric_extra_tests(typename
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
}
template <class T>
void numeric_test(T*)
{
compile_time_tests((T*) 0);
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T v1 = (T) -5;
BOOST_TEST(x1(v1) == x2(v1));
@@ -47,23 +72,13 @@ void numeric_test(T*)
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
if (limits::is_integer)
{
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));
}
numeric_extra_tests<T>();
#endif
}
@@ -74,8 +89,8 @@ void limits_test(T*)
if(limits::is_specialized)
{
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T min_value = (limits::min)();
T max_value = (limits::max)();
@@ -83,15 +98,15 @@ void limits_test(T*)
BOOST_TEST(x1(min_value) == x2((limits::min)()));
BOOST_TEST(x1(max_value) == x2((limits::max)()));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
if (limits::is_integer)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
== std::size_t(min_value));
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
== std::size_t(max_value));
}
#endif
@@ -103,8 +118,8 @@ void poor_quality_tests(T*)
{
typedef boost::hash_detail::limits<T> limits;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
// A hash function can legally fail these tests, but it'll not be a good
// sign.
@@ -113,13 +128,14 @@ void poor_quality_tests(T*)
if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2)));
if((limits::max)() != (limits::max)() - 1)
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1));
BOOST_TEST(x1(static_cast<T>((limits::max)()))
!= x2(static_cast<T>((limits::max)() - 1)));
}
void bool_test()
{
HASH_NAMESPACE::hash<bool> x1;
HASH_NAMESPACE::hash<bool> x2;
BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
BOOST_TEST(x1(true) == x2(true));
BOOST_TEST(x1(false) == x2(false));
@@ -157,6 +173,11 @@ int main()
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
#endif
#if defined(BOOST_HAS_INT128)
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
#endif
NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double)

View File

@@ -5,18 +5,14 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void pointer_tests()
@@ -24,8 +20,8 @@ void pointer_tests()
compile_time_tests((int**) 0);
compile_time_tests((void**) 0);
HASH_NAMESPACE::hash<int*> x1;
HASH_NAMESPACE::hash<int*> x2;
BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
int int1;
int int2;
@@ -33,9 +29,9 @@ void pointer_tests()
BOOST_TEST(x1(0) == x2(0));
BOOST_TEST(x1(&int1) == x2(&int1));
BOOST_TEST(x1(&int2) == x2(&int2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal:
BOOST_TEST(x1(0) == 0);

View File

@@ -5,23 +5,20 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS)
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector>
void hash_range_tests()
@@ -43,39 +40,39 @@ void hash_range_tests()
std::vector<int> x;
std::size_t x_seed = 0;
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10);
HASH_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
x.push_back(20);
HASH_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
std::size_t seed =
HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
}
int main()

View File

@@ -38,16 +38,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[10].push_back(-1);
containers[10].push_back(1);
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
== BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {

View File

@@ -5,8 +5,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -15,7 +15,7 @@
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <set>
@@ -31,7 +31,7 @@ using std::multiset;
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
set_tests::set_hash_integer_tests();
multiset_tests::multiset_hash_integer_tests();
#endif

View File

@@ -41,16 +41,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[11].insert(4);
containers[11].insert(5);
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
== BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {

View File

@@ -0,0 +1,103 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
#define TEST_ARRAY
#include <array>
#include <vector>
#endif
#ifdef TEST_ARRAY
template <typename T>
void array_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_array_test() {
/*
boost::hash<std::array<int, 0> > empty_array_hash;
std::array<int, 0> empty_array;
BOOST_TEST(empty_array_hash(empty_array) == boost::hash_value(empty_array));
*/
}
void int_1_array_test()
{
std::vector<std::array<int, 1> > arrays;
std::array<int, 1> val;
val[0] = 0;
arrays.push_back(val);
val[0] = 1;
arrays.push_back(val);
val[0] = 2;
arrays.push_back(val);
array_tests(arrays);
}
void string_1_array_test()
{
std::vector<std::array<std::string, 1> > arrays;
std::array<std::string, 1> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = "two";
arrays.push_back(val);
array_tests(arrays);
}
void string_3_array_test()
{
std::vector<std::array<std::string,3 > > arrays;
std::array<std::string, 3> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = ""; val[1] = "one"; val[2] = "";
arrays.push_back(val);
val[0] = ""; val[1] = ""; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "one"; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "two"; val[2] = "three";
arrays.push_back(val);
array_tests(arrays);
}
#endif // TEST_ARRAY
int main()
{
#ifdef TEST_ARRAY
empty_array_test();
int_1_array_test();
string_1_array_test();
string_3_array_test();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,80 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include "./compile_time.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
#define TEST_SMART_PTRS
#include <memory>
#endif
#ifdef TEST_SMART_PTRS
void shared_ptr_tests()
{
std::shared_ptr<int> x;
compile_time_tests(&x);
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x2;
std::shared_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
ptr2 = ptr1;
BOOST_TEST(x1(ptr1) == x2(ptr2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
BOOST_TEST(x1(ptr1) == BOOST_HASH_TEST_NAMESPACE::hash_value(ptr2));
#endif
}
void unique_ptr_tests()
{
std::unique_ptr<int> x;
compile_time_tests(&x);
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x2;
std::unique_ptr<int> ptr1(new int(10));
std::unique_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
}
#endif
int main()
{
#ifdef TEST_SMART_PTRS
shared_ptr_tests();
unique_ptr_tests();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,77 @@
// Copyright 2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
#define TEST_TUPLE
#include <tuple>
#include <vector>
#endif
#ifdef TEST_TUPLE
template <typename T>
void tuple_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_tuple_test() {
boost::hash<std::tuple<> > empty_tuple_hash;
std::tuple<> empty_tuple;
BOOST_TEST(empty_tuple_hash(empty_tuple) == boost::hash_value(empty_tuple));
}
void int_tuple_test() {
std::vector<std::tuple<int> > int_tuples;
int_tuples.push_back(std::make_tuple(0));
int_tuples.push_back(std::make_tuple(1));
int_tuples.push_back(std::make_tuple(2));
tuple_tests(int_tuples);
}
void int_string_tuple_test() {
std::vector<std::tuple<int, std::string> > int_string_tuples;
int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(0, std::string("")));
int_string_tuples.push_back(std::make_tuple(1, std::string("")));
tuple_tests(int_string_tuples);
}
#endif // TEST_TUPLE
int main()
{
#ifdef TEST_TUPLE
empty_tuple_test();
int_tuple_test();
int_string_tuple_test();
#endif
return boost::report_errors();
}

View File

@@ -5,64 +5,77 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <string>
#include "./compile_time.hpp"
void string_tests()
{
compile_time_tests((std::string*) 0);
HASH_NAMESPACE::hash<std::string> x1;
HASH_NAMESPACE::hash<std::string> x2;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
BOOST_TEST(x1("") == x2(std::string()));
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::string value1;
std::string value2("Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
void string0_tests()
{
std::string x1(1, '\0');
std::string x2(2, '\0');
std::string x3(3, '\0');
std::string x4(10, '\0');
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher;
BOOST_TEST(hasher(x1) != hasher(x2));
BOOST_TEST(hasher(x1) != hasher(x3));
BOOST_TEST(hasher(x1) != hasher(x4));
BOOST_TEST(hasher(x2) != hasher(x3));
BOOST_TEST(hasher(x2) != hasher(x4));
BOOST_TEST(hasher(x3) != hasher(x4));
}
#if !defined(BOOST_NO_STD_WSTRING)
void wstring_tests()
{
compile_time_tests((std::wstring*) 0);
HASH_NAMESPACE::hash<std::wstring> x1;
HASH_NAMESPACE::hash<std::wstring> x2;
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
BOOST_TEST(x1(L"") == x2(std::wstring()));
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::wstring value1;
std::wstring value2(L"Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end()));
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
#endif
@@ -70,6 +83,7 @@ void wstring_tests()
int main()
{
string_tests();
string0_tests();
#if !defined(BOOST_NO_STD_WSTRING)
wstring_tests();
#endif

View File

@@ -0,0 +1,53 @@
// Copyright 2011 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/detail/lightweight_test.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
void test_type_index() {
BOOST_HASH_TEST_NAMESPACE::hash<std::type_index> hasher;
#if defined(BOOST_NO_TYPEID)
std::cout<<"Unable to test std::type_index, as typeid isn't available"
<<std::endl;
#else
std::type_index int_index = typeid(int);
std::type_index int2_index = typeid(int);
std::type_index char_index = typeid(char);
BOOST_TEST(hasher(int_index) == int_index.hash_code());
BOOST_TEST(hasher(int_index) == int2_index.hash_code());
BOOST_TEST(hasher(char_index) == char_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(char_index) == char_index.hash_code());
BOOST_TEST(hasher(int_index) == hasher(int2_index));
BOOST_TEST(hasher(int_index) != hasher(char_index));
#endif
}
#endif
int main()
{
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
test_type_index();
#else
std::cout<<"<type_index> not available."<<std::endl;
#endif
return boost::report_errors();
}

View File

@@ -8,8 +8,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -18,7 +18,7 @@
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
void array_int_test()
{
@@ -29,32 +29,32 @@ void array_int_test()
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
HASH_NAMESPACE::hash<int[25]> hasher1;
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2;
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3));
BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array));
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
}
#endif
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif

View File

@@ -5,8 +5,8 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
@@ -15,7 +15,7 @@
#include <boost/detail/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector>
@@ -23,11 +23,11 @@ using std::vector;
#define CONTAINER_TYPE vector
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
vector_tests::vector_hash_integer_tests();
#endif

View File

@@ -5,24 +5,24 @@
#include "./config.hpp"
#define HASH_NAMESPACE boost
#define BOOST_HASH_TEST_NAMESPACE boost
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <vector>
int f(std::size_t hash1, int* x1) {
// Check that HASH_NAMESPACE::hash<int*> works in both files.
HASH_NAMESPACE::hash<int*> ptr_hasher;
// Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
BOOST_TEST(hash1 == ptr_hasher(x1));
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Check that std::vector<std::size_t> is avaiable in this file.
std::vector<std::size_t> x;
x.push_back(*x1);
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x);
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
#else

View File

@@ -5,7 +5,7 @@
#include "./config.hpp"
#define HASH_NAMESPACE boost
#define BOOST_HASH_TEST_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
@@ -13,7 +13,7 @@
extern int f(std::size_t, int*);
int main() {
HASH_NAMESPACE::hash<int*> ptr_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
int x = 55;
BOOST_TEST(!f(ptr_hasher(&x), &x));
return boost::report_errors();

View File

@@ -1,16 +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>
#include <boost/shared_ptr.hpp>
// This should obviously pass if shared_ptr ever supports Boost.Hash.
int main() {
boost::hash<boost::shared_ptr<int> > hash;
boost::shared_ptr<int> x(new int(10));
hash(x);
}