Compare commits

...

329 Commits

Author SHA1 Message Date
Peter Dimov 8a7fc581ed Merge branch 'develop' 2019-12-23 17:21:52 +02:00
Marshall Clow 5048576921 Merge pull request #6 from andrascii/develop
Fixed compiler guards for use of `std::unary_function` for C++17 compliance
2019-08-12 23:14:49 -07:00
Andrey 5f858645a0 Removed usage of std::unary_function for C++17 compliance 2019-08-10 12:37:49 +03:00
Andrey fd310d2706 Removed usage of std::unary_function for C++17 compliance 2019-08-10 11:59:22 +03:00
Andrey 90a0e36638 Removed usage of std::unary_function for C++17 compliance 2019-08-09 17:23:16 +03:00
Peter Dimov 1ce57acc41 Merge pull request #5 from Mike-Devel/min_cmake
[CMake] Add minimal cmake file
2019-01-23 19:23:08 +02:00
Mike Dev 81a65eb01c [CMake] Add minimal cmake file
Only supports "add_subdirectory" workflow and doesn't
run unit-tests. It generates a INTERFACE cmake target
that other libraries can use to express their dependency
on Boost.ContainerHash and get usage requiremments,
such as the include directory.
2019-01-02 23:04:19 +01:00
Daniel James 9fbda1a98a Fix appveyor build (cherry-pick) 2018-04-16 06:43:14 +01:00
Daniel James 62f29ea201 Merge branch 'develop' (early part) 2018-04-16 06:42:45 +01:00
Daniel James f054fe932f Fix appveyor build 2018-04-15 23:29:47 +01:00
Daniel James 83a874ed49 More general purpose support for iterators with odd reference type (trac #13501)
In the last release I added explicit support for `vector<bool>` which wasn't
working with libc++ because the iterator's `operator*` returned a proxy
reference type. Other implementations return a `bool` for const iterators, so
they happened to work okay.

This solves the problem in a more general purpose way by instantiating
`hash_combine` for the iterator `value_type`. So the type returned by
`operator*` will be implicitly casted to the correct type.
2018-04-15 22:44:33 +01:00
Daniel James 59f9543c10 Use boost 1.67.0 in travis and appveyor 2018-04-15 22:44:19 +01:00
Daniel James a6da082784 Stop using -Werror
So that there aren't any failures because of warnings in other modules.
2018-04-15 22:44:19 +01:00
Daniel James e73522f296 Merge branch 'develop' 2018-04-04 00:33:22 +01:00
Daniel James 3e8dbcbcc5 Changelog entry for vector<bool> fix 2018-04-04 00:32:53 +01:00
Daniel James 601b8d0378 Include vector header, needed to get the iterator type 2018-03-29 21:57:52 +01:00
Daniel James 60f5e0d393 Add explicit allocator to vector<bool> overloads
Needed when container_fwd.hpp is used, as it doesn't specify the default
arguments.
2018-03-29 19:57:49 +01:00
Daniel James e67d20d1c3 Fix std::vector<bool> with libc++
Temporary fix for:

https://svn.boost.org/trac10/ticket/13501

Will have a more general fix in 1.68.0
2018-03-29 19:14:56 +01:00
Daniel James 8c9bd9eccd Test in msvc-14.1 C++17 mode + write out hash_info 2018-03-08 15:52:07 +00:00
Daniel James 88d1c5c395 Update hash_info for Visual C++ 14.13 2018-03-07 10:11:46 +00:00
Daniel James 957818bb97 Merge branch 'develop' 2018-03-06 22:29:30 +00:00
Daniel James 21f32243a8 1.67.0 changes 2018-03-05 14:39:13 +00:00
Daniel James 9fafa9e37b Fix tutorial example (trac #11017)
Extract example into a C++ file, so that it can be tested, unfortunately this
means that it no longer links to the reference documentation.
2018-03-03 18:36:28 +00:00
Daniel James cc541b71c5 Merge branch 'develop'
- Support std::string_view, std::error_code, std::error_condition,
  std::optional, std::variant, std::monostate
- Improved testing, added appveyor build file
- Move headers from 'container_hash/hash' to 'container_hash', so
  there's not pointless nesting in the new directory layout
2018-02-26 14:07:50 +00:00
Daniel James d20a68efdb Move headers into top level of container_hash directory 2018-01-27 11:48:59 +00:00
Daniel James d45e3986f3 Remove forwarding headers in container_hash 2018-01-27 11:47:09 +00:00
Daniel James 1e263669cb Use unsigned for version number in hash_info.cpp
Was getting a `size_t` to `unsigned int` conversion when writing to stream, so
just use `unsigned` from the start.
2018-01-24 13:40:35 +00:00
Daniel James 8ea85f5ad2 Use error codes that are hopefully present on mingw 2018-01-24 13:40:35 +00:00
Daniel James e01239286c Avoid conversion warning 2018-01-24 12:57:28 +00:00
Daniel James 17809c3cbc Add appveyor tests 2018-01-22 14:46:22 +00:00
Daniel James 8963c38770 Fix hash_info for older Visual C++ 2018-01-22 11:56:43 +00:00
Daniel James 0ad83592af Test g++-7, and display output from hash_info 2018-01-21 21:09:50 +00:00
Daniel James cb6a0246df Test members in compile_test, rather than inheritance
Inheritance from unary_function is deprecated in recent C++. Better to
check the member types. Could probably drop test altogether.
2018-01-21 21:09:50 +00:00
Daniel James 27b2732916 Make hash_value(monostate) inline 2018-01-21 21:09:50 +00:00
Daniel James 4d9f438823 std::variant, std::monostate support 2018-01-21 19:28:33 +00:00
Daniel James ddc05d17df std::optional support 2018-01-21 19:28:33 +00:00
Daniel James b9ae7e7fb6 Clean up header detection for more headers + add optional 2018-01-21 18:21:46 +00:00
Daniel James 42bb81befa Support std::error_code and std::error_condition 2018-01-21 14:31:31 +00:00
Daniel James f81ee167c5 Add Visual C++ info to hash_info 2018-01-21 11:10:03 +00:00
Daniel James 5c4edf4d7d Fix string_view include on gcc 7.2
If it's included in anything earlier than c++-1z it errors.
2018-01-20 21:53:36 +00:00
Daniel James b5c3b5d00a Write out __cplusplus in hash_info 2018-01-20 21:53:03 +00:00
Daniel James def7a785a5 Remove some pointless code 2018-01-20 18:39:46 +00:00
Daniel James 3521c417b5 Small program to write out hash config info 2018-01-20 17:37:55 +00:00
Daniel James 8b77644ea0 Support std::string_view 2018-01-20 17:37:55 +00:00
Daniel James d41ead127d Merge branch 'develop' 2018-01-14 16:07:58 +00:00
Daniel James f460c21dd0 Add missing copyright 2018-01-10 15:17:33 +00:00
Daniel James c3e070a244 Fix some paths 2018-01-10 14:05:25 +00:00
Daniel James 9d5a16c288 Run concurrent test processes in travis 2018-01-06 14:29:05 +00:00
Daniel James e80c0c84bb Use cxxstd to set language version 2018-01-06 13:51:06 +00:00
Daniel James c64e516518 Build boost build ourself 2018-01-06 13:50:42 +00:00
Daniel James b40b795572 Use boost 1.66.0 in travis 2018-01-06 13:45:56 +00:00
Daniel James 8d784ed76d Merge branch 'develop' 2018-01-01 16:02:14 +00:00
Daniel James 6ca88a8146 Add forwarding headers at old locations 2017-12-29 14:12:03 +00:00
Daniel James 53fbb04e88 Move 'functional' headers and update paths 2017-12-29 13:58:48 +00:00
Daniel James c7fc03d2b9 Rename library in explicit-failures-markup 2017-12-28 23:50:18 +00:00
Daniel James fc3e0bff4f Add targets for automated doc build 2017-12-28 21:04:48 +00:00
Daniel James 376000169c Manually write out tuple overloads
A tad more usable this way.
2017-12-19 17:48:48 +00:00
Daniel James bc09240437 Update paths for headers moved to different modules
Makes it easier to see dependencies.
2017-12-19 17:48:18 +00:00
Daniel James dfa8fa5d91 Merge branch 'develop' 2017-11-11 18:40:05 +00:00
Daniel James 8098c5b302 1.66.0 release notes 2017-11-10 15:16:39 +00:00
Daniel James 7f3a063064 Merge branch 'develop' 2017-10-27 11:06:13 +01:00
Daniel James d803b3bdc0 Remove schema stuff, as it doesn't work 2017-10-02 23:31:54 +01:00
Daniel James 170558e4fa Initial explicit-failures-markup.xml 2017-10-02 13:42:23 +01:00
Daniel James 4a4cb9f7a4 Use is_zero workaround on clang
The same warning appears on clang for windows, but the workaround wasn't
used because the gcc macro wasn't defined.
2017-09-19 12:42:01 +01:00
Daniel James 7a6c0f20d5 Merge branch 'develop'
Travis improvements.
2017-09-19 11:08:15 +01:00
Daniel James 8bdfb0cf90 Use 1.65.1 in travis 2017-09-08 21:40:16 +01:00
Daniel James 3ee110f82c Download branch snapshot from cron jobs 2017-08-24 22:03:19 +01:00
Daniel James f7ad177dae Use boost 1.65 in travis
Also copied some other things that I've found to work well.
2017-08-24 10:24:52 +01:00
Daniel James 955cdaed3d Merge branch 'develop' 2017-06-11 20:49:34 +01:00
Daniel James 9c82e48bc9 Support for char16_t, char32_t, u16string, u32string 2017-05-31 22:19:54 +01:00
Daniel James 1b3bed82aa Initial support for char32_t 2017-05-31 10:17:34 +01:00
Daniel James 6dd58674aa Add ticket link to changelog entry 2017-02-03 08:41:31 +00:00
Daniel James 4a530f85d0 Merge branch 'develop' 2017-01-01 18:25:51 +00:00
Daniel James babb4f8f73 Hash changelog entry 2017-01-01 16:04:24 +00:00
Daniel James 01b81754cf Hash changelog entry 2017-01-01 16:03:48 +00:00
Daniel James 5210c845f5 Link to ticket in changelog 2016-12-05 23:01:20 +00:00
Daniel James 4b99dbdb64 Link to ticket in changelog 2016-12-05 23:00:20 +00:00
Daniel James 2cdf1c7d9e Add changelog entry for 1.63.0 2016-12-05 22:43:05 +00:00
Daniel James a489b08e27 Add changelog entry for 1.63.0 2016-12-05 22:42:44 +00:00
Daniel James b9c3499f45 Only support std::wstring when wchar_t is available
This hopefuly fixes #8552.

https://svn.boost.org/trac/boost/ticket/8552
2016-12-05 22:37:45 +00:00
Daniel James ab9f98455a Fix cast issue in poor_quality_tests
The comparison in the if statement and the test didn't match, which I
think is why this test was sometimes failling. But should still try to
write something that will work for floats.
2016-11-18 15:14:04 +00:00
Daniel James 7159a86166 Only support std::wstring when wchar_t is available
This hopefuly fixes #8552.

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

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

is now clean.

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


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

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

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

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

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

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

is now clean.

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

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


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

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

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


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

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

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

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

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


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


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

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


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


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

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


[SVN r80038]
2012-08-14 20:06:07 +00:00
Daniel James 12f49f7c53 Merge some link fixes.
[SVN r79869]
2012-08-05 08:36:49 +00:00
Daniel James 0757aea7cb Hash: Fix links to examples.
[SVN r79749]
2012-07-25 23:42:41 +00:00
Daniel James 92fe67f714 Compile error for deprecated header boost/functional/detail/container_fwd.hpp.
[SVN r79652]
2012-07-22 07:15:34 +00:00
Daniel James 73b507c728 Hash: Merge support for smart pointers.
[SVN r79548]
2012-07-16 00:18:30 +00:00
Daniel James 330040aea9 Hash: Merge update c++11 header macros.
[SVN r79544]
2012-07-15 23:28:30 +00:00
Daniel James 5ebe3ad87d Hash: Fix smart pointer macro check.
[SVN r79527]
2012-07-15 07:43:40 +00:00
Daniel James 411ac66581 Hash: std::shared_ptr, std::unique_ptr support.
[SVN r79516]
2012-07-14 22:32:29 +00:00
Daniel James 75bcfdeb36 Hash: Merge using SFINAE to avoid implicit casts.
[SVN r79394]
2012-07-09 20:53:36 +00:00
Marshall Clow af3a31090c Switch from deprecated macros to new shiny ones; no functionality change
[SVN r79392]
2012-07-09 20:12:04 +00:00
Daniel James 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 a98b37d12f Merge hash, opt-in to breaking change rather than opt-out.
[SVN r64031]
2010-07-15 01:12:23 +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 afc4d6664f Merge iostreams, hash.
Including disallowing implicit casts to `hash_value`.


[SVN r63812]
2010-07-10 14:20:45 +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
Tobias Schwinger 55fac118e9 adds Functional/Factory
[SVN r61596]
2010-04-26 23:20:27 +00:00
Daniel James 5ce1a71c84 Merge some link fixes and release notes.
[SVN r61474]
2010-04-21 23:00:35 +00:00
Daniel James 425de7d1dd Unordered/hash release notes.
[SVN r61356]
2010-04-18 13:20:45 +00:00
Daniel James a60758dec2 Disable warnings as errors for hash.
[SVN r61207]
2010-04-11 20:24:04 +00:00
Daniel James f544265741 Give up on warnings-as-errors for gcc for now.
[SVN r61113]
2010-04-06 20:14:12 +00:00
Daniel James 7af7c59420 Merge from trunk.
- Add `quick_erase` for unordered. `erase_return_void` is now deprecated.
   Fixes #3966
 - Avoid collision between 0 and 0.5. Fixes #4038


[SVN r60980]
2010-03-31 21:39:07 +00:00
Daniel James 733422d1b9 Remove optimization which causes 0.5 to hash to 0. Refs #4038.
I have an internal requirement the 0 hashes to 0, a better solution
might be to remove that, put the optimization back and hash 0 to another
value. Or alternatively, use the main combine function instead.

[SVN r60805]
2010-03-24 08:49:00 +00:00
Daniel James f3072d2023 Merge hash and unordered from trunk.
- Replace uses of deprecated C++0x macros
 - Set length of primes inside template on Sun C++. Fixes #3854
 - Missing newline at end of file.



[SVN r59911]
2010-02-25 19:05:01 +00:00
Daniel James 77f856e3cf Remove deprecated macros for hash and unordered's tests.
[SVN r59708]
2010-02-16 22:33:10 +00:00
Daniel James 6544b32920 Take advantage of the simplified parameters.
[SVN r59707]
2010-02-16 22:32:49 +00:00
Daniel James 538b8fb95a Stop using the deprecated BOOST_HAS_ macros in unordered and hash.
[SVN r59697]
2010-02-15 23:01:06 +00:00
Daniel James fdc0995489 Merge some detail changes.
- [53670] Avoid C style casts.
 - [55604] Fix #3346 boost/detail/scoped_enum_emulation.hpp enum_t conflict
   with Unix rpc/types.h
 - Don't foward declare containers when using gcc's parallel library and add a
   macro to disable forward declaration. Fixes #3866.


[SVN r59679]
2010-02-14 16:31:21 +00:00
Daniel James e042170fb9 Missing newline.
[SVN r59365]
2010-01-30 09:30:04 +00:00
Daniel James 316b1aa9f0 Don't foward declare containers when using gcc's parallel library and
add a macro to disable forward declaration. Fixes #3866.

[SVN r59282]
2010-01-27 19:32:39 +00:00
Daniel James 692d65d0e4 Merge link fix.
[SVN r59013]
2010-01-15 00:56:07 +00:00
Daniel James 0ba3e9b282 Fix link to example file. Fixes #3836.
Thanks for reporting this.

[SVN r58951]
2010-01-12 18:52:43 +00:00
Daniel James 98f0f11423 Turn warnings as errors back on.
[SVN r58949]
2010-01-12 18:51:59 +00:00
Daniel James e67ee6032a Merge unordered documentation.
[SVN r58844]
2010-01-09 17:17:53 +00:00
Daniel James 6e37c616db Update changelogs and slightly improved reference documentation for new release.
[SVN r58805]
2010-01-08 06:43:57 +00:00
Daniel James 5860602e5c Merge hash changes.
[SVN r58801]
2010-01-08 05:38:39 +00:00
Daniel James 5f10c2bb7e Explicitly cast values to avoid warning on Visual C++ 10
[SVN r58745]
2010-01-06 08:43:47 +00:00
Daniel James 6d7a55a4f7 Formatting changes, mostly to fit within 80 characters.
Also, some C casts converted to static_cast.

[SVN r58692]
2010-01-04 22:49:39 +00:00
Daniel James 0ed492ba18 Rename namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS to lower case for consistency.
[SVN r58632]
2010-01-02 11:12:23 +00:00
Daniel James 2734e22b50 Only use _GLIBCXX_DEBUG on gcc/darwin.
It looks like pathscale also uses the gcc library but debug mode doesn't
work on it.

[SVN r58567]
2009-12-29 18:06:41 +00:00
Daniel James 9938fad017 Only use gcc debug containers on the container_fwd_test.
[SVN r58395]
2009-12-15 13:16:50 +00:00
Daniel James 4787563f96 Turn off warnings as errors on gcc/darwin because the integer library currently causes some warnings.
[SVN r58394]
2009-12-15 13:16:32 +00:00
Daniel James 01630b4053 Merge unordered and hash.
Improved Codegear support in unordered.
Another warning suppression in hash.


[SVN r58223]
2009-12-07 19:26:26 +00:00
Daniel James 78eeabaeb2 Suppress another warning.
[SVN r58078]
2009-12-01 08:52:10 +00:00
Daniel James d45d471e34 Merge hash warning fixes from trunk.
[SVN r58032]
2009-11-29 16:14:10 +00:00
Daniel James 3882189584 Try to suppress some more Visual C++ warnings.
[SVN r57976]
2009-11-27 19:43:26 +00:00
Daniel James 079f8025b3 Suppress a warning that's in the windows mobile system headers.
[SVN r57963]
2009-11-26 23:15:30 +00:00
Daniel James b43c9fa145 Fix some hash /W4 warnings. Fixes #3648
[SVN r57839]
2009-11-21 19:40:54 +00:00
Daniel James b0ceeca154 Turn on warnings as errors for the hash tests.
[SVN r57720]
2009-11-16 23:56:56 +00:00
Daniel James d8bfb81914 Remove 'warnings-as-errors' flag that was breaking the build.
[SVN r57564]
2009-11-11 14:03:44 +00:00
Daniel James 9958072d2a Stricter warnings for unordered and hash.
There are still warnings in hash_complex_test.

[SVN r57537]
2009-11-10 08:15:55 +00:00
Troy D. Straszheim 99c6e89390 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
Troy D. Straszheim 84e1b951f5 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
Daniel James 3ee9d7d507 Copy the unordered and hash CMake files from release.
[SVN r56704]
2009-10-10 15:09:02 +00:00
Daniel James 1d792ecb45 Merge some documentation changes and inspect fixes.
Merged revisions 55370,55729,56440,56570-56571,56603,56697-56699 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55370 | danieljames | 2009-08-02 19:18:14 +0100 (Sun, 02 Aug 2009) | 1 line
  
  Pass through more elements in doxygen2boostbook. Refs #3309.
........
  r55729 | danieljames | 2009-08-23 11:07:25 +0100 (Sun, 23 Aug 2009) | 3 lines
  
  Add depencies on doxygen documentation to standalone documentation targets.
  
  This seems to be needed for building pdfs.
........
  r56440 | danieljames | 2009-09-27 20:11:39 +0100 (Sun, 27 Sep 2009) | 1 line
  
  Fix silly error in doxygen test file.
........
  r56570 | danieljames | 2009-10-04 11:37:36 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Clean up some unordered TODOs.
........
  r56571 | danieljames | 2009-10-04 11:37:56 +0100 (Sun, 04 Oct 2009) | 1 line
  
  Detab.
........
  r56603 | danieljames | 2009-10-05 22:29:39 +0100 (Mon, 05 Oct 2009) | 1 line
  
  Various inspect fixes.
........
  r56697 | danieljames | 2009-10-10 14:00:28 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add forwarding html file for accumulators.
........
  r56698 | danieljames | 2009-10-10 14:01:14 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Missing newline.
........
  r56699 | danieljames | 2009-10-10 14:01:30 +0100 (Sat, 10 Oct 2009) | 1 line
  
  Add copyright to boostbook reference xml.
........


[SVN r56702]
2009-10-10 14:53:46 +00:00
Daniel James e75f94f71d Various inspect fixes.
[SVN r56603]
2009-10-05 21:29:39 +00:00
Troy D. Straszheim 5db98a2dda Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
Daniel James 07b565143f Add am implementation note about the Visual C++ problems.
[SVN r54399]
2009-06-27 07:39:12 +00:00
Jürgen Hunold d8980c3f09 Fix gcc -pedantic warning: remove extra ";".
[SVN r54146]
2009-06-21 14:38:19 +00:00
Daniel James 83b052b784 I didn't mean to comment this out.
[SVN r54145]
2009-06-21 09:51:59 +00:00
Daniel James c51bebf8a4 Move the support for hashing containers into the extension header, and improve the standard tests.
[SVN r54144]
2009-06-21 09:42:40 +00:00
Daniel James 8b98036bb8 Move BOOST_HASH_CHAR_TRAITS from container_fwd into the hash headers, and undefine it.
[SVN r54143]
2009-06-21 09:42:20 +00:00
Daniel James 4774d24966 Get <boost/functional/hash/extensions.hpp> to work.
[SVN r54142]
2009-06-21 09:42:05 +00:00
Daniel James 13f44653b5 Revert [54025] "Try to avoid using special macro handling code."
[SVN r54141]
2009-06-21 09:41:46 +00:00
Daniel James e20c872440 Move includes to the header which they're used in.
[SVN r54140]
2009-06-21 09:41:30 +00:00
Daniel James 600740e2ae A few more comments in boost::hash.
[SVN r54139]
2009-06-21 09:41:11 +00:00
Daniel James 52a964ae91 Add copyright to namespace_fail_test.cpp
[SVN r54033]
2009-06-17 23:24:28 +00:00
Daniel James 3d79c2f1e4 Try to avoid using special macro handling code.
[SVN r54025]
2009-06-17 21:23:42 +00:00
Daniel James 3cf1a67771 Put the minimum amount of implementation in the same namespace as the 'using namespace' directives in order to avoid Visual C++ 8 bug.
[SVN r54024]
2009-06-17 21:22:49 +00:00
Daniel James 9cc8c20413 Remove hash_complex_test's dependency on Boost.Random.
Only test for a few values, but that should be okay as there isn't much
to test.

[SVN r53924]
2009-06-15 07:37:42 +00:00
Daniel James 9f4a6a966e Try to avoid float to int warning when a float function doesn't exist. Refs #3171.
[SVN r53828]
2009-06-12 18:24:47 +00:00
Daniel James 15d4153c37 Test the hash functions for a couple of typedefs.
[SVN r53522]
2009-06-01 06:49:45 +00:00
Daniel James 326a338add Remove misplaced visual C++ warning pragma.
[SVN r53506]
2009-05-31 15:53:09 +00:00
Daniel James b0459a20da Hash change log.
[SVN r53254]
2009-05-25 19:44:52 +00:00
Daniel James 909d0c9547 Fix a couple of clumsy errors in the last commit.
[SVN r53248]
2009-05-25 14:27:00 +00:00
Daniel James 912aed0b57 Check for float functions with less templates.
The only template mechanism now used is full specialization, so this should
hopefully be more portable to compilers we don't test.

[SVN r53247]
2009-05-25 13:45:16 +00:00
Daniel James e5d343faea Try to deal with macros for frexpl and ldexpl.
The error message for msvc-9.0~wm5~stlport5.2 suggests that frexpl and ldexpl
are macros.

[SVN r53205]
2009-05-23 15:21:38 +00:00
Jürgen Hunold 3e320b7ae5 Fix gcc -pedantic error:extra extra ';'
[SVN r53203]
2009-05-23 13:03:25 +00:00
Daniel James 8bc6175fa0 Explicitly qualify 'none' to avoid confusion with boost::none.
[SVN r53185]
2009-05-22 19:00:35 +00:00
Daniel James 6751e9cf47 Rename struct to avoid using 'type::'type' which confuses some
compilers.

[SVN r53175]
2009-05-22 13:35:56 +00:00
Daniel James 004e4df2a2 Some STLport fixes for hash.
[SVN r53169]
2009-05-22 06:01:35 +00:00
Daniel James 411f559730 Spell out exactly which functions can be used with which types.
I was hitting some ambiguity errors when the function was for the wrong type.

[SVN r53168]
2009-05-22 06:01:19 +00:00
Daniel James 8a6aba46c7 Fix a typo.
[SVN r53167]
2009-05-22 06:00:56 +00:00
Daniel James 65b103e812 Try to automatically detect which float functions are available.
[SVN r53161]
2009-05-21 21:22:04 +00:00
Daniel James c160428eff Move the two different hash float implementation into their own header.
[SVN r53160]
2009-05-21 21:21:44 +00:00
Daniel James dda32a279a Move the hash limits workaround into its own file.
[SVN r53159]
2009-05-21 21:21:11 +00:00
Daniel James f1a8a0fde8 Add a missing entry to the changelog.
[SVN r52552]
2009-04-22 21:12:49 +00:00
Daniel James 814476afa2 Fix float support on vxWorks.
Thanks to Dustin Spicuzza. Refs #2957

[SVN r52481]
2009-04-19 09:17:18 +00:00
Daniel James 9ef99e556a Don't use debug containers on darwin.
I'm getting errors from the darwin 4.2 debug containers which appear to
a problem with its implementation.

[SVN r52304]
2009-04-10 19:25:32 +00:00
Daniel James 2aff9855bb Detect gcc stdlib for gcc 4.0.1.
For some reason the normal macros aren't defined for the standard
library that comes with gcc 4.0.1 (although maybe just on BSDs?). So try
to detect the library for that compiler.

[SVN r52245]
2009-04-08 05:51:31 +00:00
Daniel James 72cb0e7788 Changelog for unordered and hash.
[SVN r52084]
2009-03-31 19:43:58 +00:00
Daniel James 220c3a4e62 Use paragraphs inside purpose tags.
[SVN r51802]
2009-03-16 20:21:05 +00:00
Daniel James b0b7f17984 Update copyright dates in hash and unordered.
[SVN r51667]
2009-03-09 20:56:23 +00:00
Daniel James 342284f4cf Remove deprecated headers.
Fixes #2412.

[SVN r51646]
2009-03-08 09:45:30 +00:00
Daniel James fe6449fea6 Move hash_fwd into the hash subdirectory.
I should have done this in the last release. But now all of the hash
implementation is in the hash subdirectory.

[SVN r51645]
2009-03-08 09:45:11 +00:00
Daniel James a3e434ec47 Fix the hash dirname.
[SVN r51407]
2009-02-22 23:49:51 +00:00
John Maddock 7c72c09288 Add PDF generation options to fix external links to point to the web site.
Added a few more Boostbook based libs that were missed first time around.
Fixed PDF naming issues.

[SVN r51284]
2009-02-17 10:05:58 +00:00
Daniel James 45dfe7d9c5 Don't copy images for the standalone hash and unordered documentation, was only
really required before the libraries were integrated into boost.

[SVN r51263]
2009-02-15 19:32:19 +00:00
Daniel James 2560590a2b Use the new 'boost:' links for the hash, unordered and quickbook documentation.
[SVN r51262]
2009-02-15 19:32:04 +00:00
John Maddock c984bbb5f0 Add Jamfile to build PDF versions of all the docs.
Tweaked some existing Jamfiles so that PDF build finds all the necessary image files etc.
Tweaked fo.xsl to provide more options by default, and improve formatting.

[SVN r51104]
2009-02-08 16:59:14 +00:00
Daniel James 0480bcf503 Rename parameter to avoid Visual C++ warning about clash with boost::array.
Fixes #2643

[SVN r50514]
2009-01-08 13:37:33 +00:00
86 changed files with 3891 additions and 1783 deletions
+36
View File
@@ -0,0 +1,36 @@
# Copyright 2017 Daniel James
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
install:
- cd c:\projects
- curl -sSL -o boost.7z https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.7z
- 7z x boost.7z
- set BOOST_ROOT=c:\projects\boost_1_67_0
- rd /s /q %BOOST_ROOT%\boost\functional\hash
- cd %BOOST_ROOT%\tools\build
- cmd /c bootstrap
- cd %APPVEYOR_BUILD_FOLDER%
- echo. 2>Jamroot.jam
build: off
test_script:
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- cd %APPVEYOR_BUILD_FOLDER%\test
- cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT% --verbose-test hash_info
- cmd /c %BOOST_ROOT%\tools\build\b2 -j 3 toolset=%TOOLSET% %CXXSTD% include=%APPVEYOR_BUILD_FOLDER%\include include=%BOOST_ROOT%
+78
View File
@@ -0,0 +1,78 @@
# Copyright (C) 2016 Daniel James.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Use Trusty to get a reasonably recent version of Boost.
sudo: required
dist: trusty
language: c++
matrix:
include:
- compiler: gcc
env: |
USER_CONFIG="using gcc : : g++-4.8 ;"
CXXSTD=03,11
- compiler: g++-7
env: |
USER_CONFIG="using gcc : : g++-7 ;"
CXXSTD=11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- compiler: clang
env: |
USER_CONFIG="using clang : : clang++ ;"
CXXSTD=03,11
- compiler: clang
env: |
USER_CONFIG="using clang : : clang++ -D_HAS_AUTO_PTR_ETC=0 ;"
CXXSTD=11
before_script:
- export BOOST_VERSION=1.67.0
- export BOOST_FILENAME=boost_1_67_0
- export BOOST_ROOT=${HOME}/boost
- cd ${TRAVIS_BUILD_DIR}
- touch Jamroot.jam
- cd $HOME
- echo $USER_CONFIG > ~/user-config.jam
- cat ~/user-config.jam
- |
mkdir $HOME/download
mkdir $HOME/extract
cd $HOME/download
if [ "$TRAVIS_EVENT_TYPE" == "cron" ]
then
if [ "$TRAVIS_BRANCH" == "master" ]
then
snapshot_branch=master
else
snapshot_branch=develop
fi
download_url=$(curl https://api.bintray.com/packages/boostorg/$snapshot_branch/snapshot/files |
python -c "import os.path, sys, json; x = json.load(sys.stdin); print '\n'.join(a['path'] for a in x if os.path.splitext(a['path'])[1] == '.bz2')" |
head -n 1 |
sed "s/^/http:\/\/dl.bintray.com\/boostorg\/$snapshot_branch\//")
else
download_url=https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/${BOOST_FILENAME}.tar.bz2/download
fi
echo "Downloading ${download_url}"
wget -O boost.tar.bz2 $download_url
cd $HOME/extract
tar -xjf $HOME/download/boost.tar.bz2
mv * ${BOOST_ROOT}
- rm -r ${BOOST_ROOT}/boost/functional
- cd ${BOOST_ROOT}/tools/build
- mkdir ${HOME}/opt
- ./bootstrap.sh
- ./b2 install --prefix=$HOME/opt
script:
- cd ${TRAVIS_BUILD_DIR}/test
- ${HOME}/opt/bin/b2 --verbose-test -j 3 cxxstd=$CXXSTD -q ${BJAM_TOOLSET} include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include hash_info
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q ${BJAM_TOOLSET} include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
+23
View File
@@ -0,0 +1,23 @@
# Copyright 2018 Mike Dev
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5)
project(BoostContainerHash LANGUAGES CXX)
add_library(boost_container_hash INTERFACE)
add_library(Boost::container_hash ALIAS boost_container_hash)
target_include_directories(boost_container_hash INTERFACE include)
target_link_libraries(boost_container_hash
INTERFACE
Boost::assert
Boost::config
Boost::core
Boost::detail
Boost::integer
Boost::static_assert
Boost::type_traits
)
-8
View File
@@ -1,8 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
message(STATUS "functional/hash docs need love")
+10 -4
View File
@@ -3,17 +3,23 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying # Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
using boostbook ;
using quickbook ;
xml hash : hash.qbk ; xml hash : hash.qbk ;
boostbook standalone : hash : boostbook standalone : hash :
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
<xsl:param>boost.root=../../../.. <xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../libraries.htm
<xsl:param>navig.graphics=1
<xsl:param>chunk.first.sections=1 <xsl:param>chunk.first.sections=1
<xsl:param>chunk.section.depth=2 <xsl:param>chunk.section.depth=2
<xsl:param>generate.section.toc.level=2 <xsl:param>generate.section.toc.level=2
<xsl:param>toc.section.depth=1 <xsl:param>toc.section.depth=1
<xsl:param>toc.max.depth=1 <xsl:param>toc.max.depth=1
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/container_hash/doc/html
; ;
###############################################################################
alias boostdoc : hash ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;
+133 -4
View File
@@ -3,6 +3,8 @@
/ Distributed under the Boost Software License, Version 1.0. (See accompanying / Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[template ticket[number]'''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[number]'''">'''#[number]'''</ulink>''']
[section:changes Change Log] [section:changes Change Log]
[h2 Boost 1.33.0] [h2 Boost 1.33.0]
@@ -41,7 +43,7 @@
the number of times combine is called and hopefully give a better the number of times combine is called and hopefully give a better
quality hash function. quality hash function.
* Improved the algorithm for hashing floating point numbers. * Improved the algorithm for hashing floating point numbers.
* On Cygwin use a binary hash function for floating point numbers, as * On Cygwin use a binary hash function for floating point numbers, as
Cygwin doesn't have decent floating point functions for `long double`. Cygwin doesn't have decent floating point functions for `long double`.
* Never uses `fpclass` which doesn't support `long double`. * Never uses `fpclass` which doesn't support `long double`.
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]: * [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
@@ -69,11 +71,11 @@
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These * Changed the warnings in the deprecated headers from 1.34.0 to errors. These
will be removed in a future version of Boost. will be removed in a future version of Boost.
* Moved detail headers out of `boost/functional/detail`, since they are part of * Moved detail headers out of `boost/container_hash/detail`, since they are part of
functional/hash, not functional. `boost/functional/detail/container_fwd.hpp` functional/hash, not container_hash. `boost/container_hash/detail/container_fwd.hpp`
has been moved to `boost/detail/container_fwd.hpp` as it's used outside of has been moved to `boost/detail/container_fwd.hpp` as it's used outside of
this library, the others have been moved to `boost/functional/hash/detail`. this library, the others have been moved to `boost/functional/hash/detail`.
[h2 Boost 1.39.0] [h2 Boost 1.39.0]
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a * Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
@@ -90,4 +92,131 @@
instead of trying to configure every possibility manually. instead of trying to configure every possibility manually.
* Workaround for when STLport doesn't support long double. * Workaround for when STLport doesn't support long double.
[h2 Boost 1.42.0]
* Reduce the number of warnings for Visual C++ warning level 4.
* Some code formatting changes to fit lines into 80 characters.
* Rename an internal namespace.
[h2 Boost 1.43.0]
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
Don't foward declare containers when using gcc's parallel library,
allow user to stop forward declaration by defining the
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
Avoid hashing 0.5 and 0 to the same number.
* Stop using deprecated `BOOST_HAS_*` macros.
[h2 Boost 1.44.0]
* Add option to prevent implicit conversions when calling `hash_value` by
defining `BOOST_HASH_NO_IMPLICIT_CASTS`. When using `boost::hash`
for a type that does not have `hash_value` declared but does have
an implicit conversion to a type that does, it would use that
implicit conversion to hash it. Which can sometimes go very wrong,
e.g. using a conversion to bool and only hashing to 2 possible
values. Since fixing this is a breaking change and was only
approached quite late in the release cycle with little discussion
it's opt-in for now. This, or something like it, will become the
default in a future version.
[h2 Boost 1.46.0]
* Avoid warning due with gcc's `-Wconversion` flag.
[h2 Boost 1.50.0]
* [@http://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
Avoid gcc's `-Wfloat-equal` warning.
* [@http://svn.boost.org/trac/boost/ticket/6806 Ticket 6806]:
Support `std::array` and `std::tuple` when available.
* Add deprecation warning to the long deprecated
`boost/container_hash/detail/container_fwd.hpp`.
[h2 Boost 1.51.0]
* Support the standard smart pointers.
* `hash_value` now implemented using SFINAE to avoid implicit casts to built
in types when calling it.
* Updated to use the new config macros.
[h2 Boost 1.52.0]
* Restore `enum` support, which was accidentally removed in the last version.
* New floating point hasher - will hash the binary representation on more
platforms, which should be faster.
[h2 Boost 1.53.0]
* Add support for `boost::int128_type` and `boost::uint128_type` where
available - currently only `__int128` and `unsigned __int128` on some
versions of gcc.
* On platforms that are known to have the standard floating point functions,
don't use automatic detection - which can break if there are ambiguous
overloads.
* Fix undefined behaviour when using the binary float hash (Thomas Heller).
[h2 Boost 1.54.0]
* [@https://svn.boost.org/trac/boost/ticket/7957 Ticket 7957]:
Fixed a typo.
[h2 Boost 1.55.0]
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9
([ticket 8822]).
* Suppress Visual C++ infinite loop warning ([ticket 8568]).
[h2 Boost 1.56.0]
* Removed some Visual C++ 6 workarounds.
* Ongoing work on improving `hash_combine`. This changes the combine function
which was previously defined in the reference documentation.
[h2 Boost 1.58.0]
* Fixed strict aliasing violation
([@https://github.com/boostorg/container_hash/pull/3 GitHub #3]).
[h2 Boost 1.63.0]
* Fixed some warnings.
* Only define hash for `std::wstring` when we know we have a `wchar_t`.
Otherwise there's a compile error as there's no overload for hashing
the characters in wide strings ([ticket 8552]).
[h2 Boost 1.64.0]
* Fix for recent versions of Visual C++ which have removed `std::unary_function`
and `std::binary_function` ([ticket 12353]).
[h2 Boost 1.65.0]
* Support for `char16_t`, `char32_t`, `u16string`, `u32string`
[h2 Boost 1.66.0]
* Avoid float comparison warning when using Clang - this workaround was
already in place for GCC, and was used when Clang pretends to be GCC,
but the warning was appearing when running Clang in other contexts.
[h2 Boost 1.67.0]
* Moved library into its own module, `container_hash`.
* Moved headers for new module name, now at:
`<boost/container_hash/hash.hpp>`,
`<boost/container_hash/hash_fwd.hpp>`,
`<boost/container_hash/extensions.hpp>`.
* Added forwarding headers to support the old headers locations.
* Support `std::string_view`, `std::error_code`, `std::error_condition`
`std::optional`, `std::variant`, `std::monostate` where available.
* Update include paths from other Boost libraries.
* Manually write out tuple overloads, rather than using the
preprocessor to generate them. Should improve usability, due
to better error messages, and easier debugging.
* Fix tutorial example ([ticket 11017]).
* Quick fix for hashing `vector<bool>` when using libc++. Will try to introduce
a more general fix in the next release.
[endsect] [endsect]
+1 -1
View File
@@ -10,7 +10,7 @@ to turn them of in order to check that your code will work with other
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`. implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
When this macro is defined, only the specialisations detailed When this macro is defined, only the specialisations detailed
in TR1 will be declared. But, if you later undefine the macro and include in TR1 will be declared. But, if you later undefine the macro and include
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined <[headerref boost/container_hash/hash.hpp]> then the non-specialised form will be defined
- activating the extensions. - activating the extensions.
It is strongly recommended that you never undefine the macro - and only define It is strongly recommended that you never undefine the macro - and only define
+8 -3
View File
@@ -1,12 +1,12 @@
[library Boost.Functional/Hash [library Boost.ContainerHash
[quickbook 1.4] [quickbook 1.5]
[authors [James, Daniel]] [authors [James, Daniel]]
[copyright 2005 2006 2007 2008 Daniel James] [copyright 2005 2006 2007 2008 Daniel James]
[purpose A TR1 hash function object that can be extended to hash user [purpose A TR1 hash function object that can be extended to hash user
defined types] defined types]
[category higher-order] [category higher-order]
[id hash] [id hash]
[dirname functional/hash] [dirname container_hash]
[license [license
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at (See accompanying file LICENSE_1_0.txt or copy at
@@ -14,11 +14,16 @@
] ]
] ]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[include:hash intro.qbk] [include:hash intro.qbk]
[include:hash tutorial.qbk] [include:hash tutorial.qbk]
[include:hash portability.qbk] [include:hash portability.qbk]
[include:hash disable.qbk] [include:hash disable.qbk]
[include:hash changes.qbk] [include:hash changes.qbk]
[include:hash rationale.qbk]
[xinclude ref.xml] [xinclude ref.xml]
[include:hash links.qbk] [include:hash links.qbk]
[include:hash thanks.qbk] [include:hash thanks.qbk]
+7 -3
View File
@@ -18,9 +18,6 @@
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html [def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]] Boost.MultiIndex]]
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]] [def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]] [def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]] [def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
@@ -44,5 +41,12 @@ __issues__ (page 63), this adds support for:
* the standard containers. * the standard containers.
* extending [classref boost::hash] for custom types. * extending [classref boost::hash] for custom types.
[note
This hash function is designed to be used in containers based on
the STL and is not suitable as a general purpose hash function.
For more details see the [link hash.rationale rationale].
]
[endsect] [endsect]
+1 -13
View File
@@ -88,18 +88,6 @@ boost namespace:
} }
Full code for this example is at Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp]. [@boost:/libs/container_hash/examples/portable.cpp /libs/container_hash/examples/portable.cpp].
[h2 Other Issues]
On Visual C++ versions 6.5 and 7.0, `hash_value` isn't overloaded for built in
arrays. __boost_hash__, [funcref boost::hash_combine] and [funcref boost::hash_range] all use a workaround to
support built in arrays so this shouldn't be a problem in most cases.
On Visual C++ versions 6.5 and 7.0, function pointers aren't currently supported.
When using GCC on Solaris, `boost::hash_value(long double)` treats
`long double`s as `double`s - so the hash function doesn't take into account the
full range of values.
[endsect] [endsect]
+50
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]
+191 -7
View File
@@ -13,7 +13,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63). <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
</para> </para>
</section> </section>
<header name="boost/functional/hash.hpp"> <header name="boost/container_hash/hash.hpp">
<para> <para>
Defines <code><classname>boost::hash</classname></code>, Defines <code><classname>boost::hash</classname></code>,
and helper functions. and helper functions.
@@ -55,6 +55,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
is defined. The specializations are still defined, so only the specializations is defined. The specializations are still defined, so only the specializations
required by TR1 are defined. required by TR1 are defined.
</para> </para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes> </notes>
<throws><para> <throws><para>
Only throws if Only throws if
@@ -153,6 +162,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method> </method>
</struct-specialization> </struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>char16_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char16_t</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>char32_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char32_t</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash"> <struct-specialization name="hash">
<template></template> <template></template>
<specialization> <specialization>
@@ -387,6 +432,42 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method> </method>
</struct-specialization> </struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::u16string</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::u16string const&amp;</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::u32string</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::u32string const&amp;</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash"> <struct-specialization name="hash">
<template> <template>
<template-type-parameter name="T"/> <template-type-parameter name="T"/>
@@ -406,6 +487,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</method> </method>
</struct-specialization> </struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::type_index</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::type_index</paramtype>
</parameter>
<returns>
<para><code>val.hash_code()</code></para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
<notes>
<para>
Only available if it's in your standard library and Boost.Config
is aware of it.
</para>
</notes>
</struct-specialization>
<free-function-group name="Support functions (Boost extension)."> <free-function-group name="Support functions (Boost extension).">
<!-- <!--
@@ -423,11 +527,28 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Called repeatedly to incrementally create a hash value from Called repeatedly to incrementally create a hash value from
several variables. several variables.
</simpara></purpose> </simpara></purpose>
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed &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> <notes>
<para><functionname>hash_value</functionname> is called without <para><functionname>hash_value</functionname> is called without
qualification, so that overloads can be found via ADL.</para> qualification, so that overloads can be found via ADL.</para>
<para>This is an extension to TR1</para> <para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes> </notes>
<throws> <throws>
Only throws if <functionname>hash_value</functionname>(T) throws. Only throws if <functionname>hash_value</functionname>(T) throws.
@@ -476,15 +597,14 @@ for(; first != last; ++first)
return seed; return seed;
</programlisting> </programlisting>
</para>For the three arguments overload: </para>
<para>For the three arguments overload:</para>
<programlisting> <programlisting>
for(; first != last; ++first) for(; first != last; ++first)
{ {
<functionname>hash_combine</functionname>(seed, *first); <functionname>hash_combine</functionname>(seed, *first);
} }
</programlisting> </programlisting>
<para>
</para>
</effects> </effects>
<notes> <notes>
<para> <para>
@@ -493,6 +613,15 @@ for(; first != last; ++first)
container. container.
</para> </para>
<para>This is an extension to TR1</para> <para>This is an extension to TR1</para>
<para>
Forward declared in
<code>&lt;boost/container_hash/hash_fwd.hpp&gt;</code>
</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes> </notes>
<throws><para> <throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code> Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
@@ -540,6 +669,16 @@ for(; first != last; ++first)
<parameter name="val"><paramtype>wchar_t</paramtype></parameter> <parameter name="val"><paramtype>wchar_t</paramtype></parameter>
</signature> </signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char16_t</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char32_t</paramtype></parameter>
</signature>
<signature> <signature>
<type>std::size_t</type> <type>std::size_t</type>
<parameter name="val"><paramtype>short</paramtype></parameter> <parameter name="val"><paramtype>short</paramtype></parameter>
@@ -716,6 +855,30 @@ for(; first != last; ++first)
<parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter> <parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter>
</signature> </signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::type_index</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N">
<type>std::size_t</type>
</template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::array&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> <description><para>
Generally shouldn't be called directly by users, instead they should use Generally shouldn't be called directly by users, instead they should use
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname> <classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
@@ -726,6 +889,11 @@ for(; first != last; ++first)
<notes> <notes>
<para>This is an extension to TR1</para> <para>This is an extension to TR1</para>
<para>
This hash function is not intended for general use, and isn't
guaranteed to be equal during separate runs of a program - so
please don't use it for any persistent storage or communication.
</para>
</notes> </notes>
<throws> <throws>
@@ -747,7 +915,8 @@ for(; first != last; ++first)
<tbody> <tbody>
<row> <row>
<entry><code>bool</code>, <entry><code>bool</code>,
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>, <code>char</code>, <code>signed char</code>, <code>unsigned char</code>,
<code>wchar_t</code>, <code>char16_t</code>, <code>char32_t</code>,
<code>short</code>, <code>unsigned short</code>, <code>short</code>, <code>unsigned short</code>,
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code> <code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
</entry> </entry>
@@ -781,7 +950,8 @@ for(; first != last; ++first)
<code>std::set&lt;K,&#160;C,&#160;A&gt;</code>, <code>std::set&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>, <code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::map&lt;K,&#160;T,&#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>
<entry><code>hash_range(val.begin(), val.end())</code></entry> <entry><code>hash_range(val.begin(), val.end())</code></entry>
</row> </row>
@@ -790,6 +960,14 @@ for(; first != last; ++first)
<entry><programlisting>size_t seed = 0; <entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, val.first); <functionname>hash_combine</functionname>(seed, val.first);
<functionname>hash_combine</functionname>(seed, val.second); <functionname>hash_combine</functionname>(seed, val.second);
return seed;</programlisting></entry>
</row>
<row>
<entry><code>std::tuple&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> return seed;</programlisting></entry>
</row> </row>
<row> <row>
@@ -798,6 +976,12 @@ return seed;</programlisting></entry>
</entry> </entry>
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry> <entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
</row> </row>
<row>
<entry>
<code>std::type_index</code>
</entry>
<entry><code>val.hash_code()</code></entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</informaltable> </informaltable>
+27
View File
@@ -0,0 +1,27 @@
#include <boost/container_hash/hash.hpp>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cassert>
//[ get_hashes
template <class Container>
std::vector<std::size_t> get_hashes(Container const& x)
{
std::vector<std::size_t> hashes;
std::transform(x.begin(), x.end(), std::back_inserter(hashes),
boost::hash<typename Container::value_type>());
return hashes;
}
//]
int main() {
std::vector<int> values;
values.push_back(10);
values.push_back(20);
std::vector<std::size_t> hashes = get_hashes(values);
assert(hashes[0] = boost::hash<int>()(values[0]));
assert(hashes[1] = boost::hash<int>()(values[1]));
}
+19 -14
View File
@@ -3,6 +3,9 @@
/ Distributed under the Boost Software License, Version 1.0. (See accompanying / Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ] / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[quickbook 1.7]
[import samples/tutorial.cpp]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html [def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]] Boost.MultiIndex]]
@@ -27,7 +30,7 @@ associative containers and you wish to use
To use [classref boost::hash] directly, create an instance and call it as a function: To use [classref boost::hash] directly, create an instance and call it as a function:
#include <``[headerref boost/functional/hash.hpp]``> #include <``[headerref boost/container_hash/hash.hpp]``>
int main() int main()
{ {
@@ -39,15 +42,7 @@ To use [classref boost::hash] directly, create an instance and call it as a func
For an example of generic use, here is a function to generate a vector For an example of generic use, here is a function to generate a vector
containing the hashes of the elements of a container: containing the hashes of the elements of a container:
template <class Container> [get_hashes]
std::vector<std::size_t> get_hashes(Container const& x)
{
std::vector<std::size_t> hashes;
std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
``[classref boost::hash]``<typename Container::value_type>());
return hashes;
}
[endsect] [endsect]
@@ -110,9 +105,9 @@ And you can now use [classref boost::hash] with book:
assert(books.find(dandelion) == books.end()); assert(books.find(dandelion) == books.end());
The full example can be found in: The full example can be found in:
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.hpp] [@boost:/libs/container_hash/examples/books.hpp /libs/container_hash/examples/books.hpp]
and and
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp]. [@boost:/libs/container_hash/examples/books.cpp /libs/container_hash/examples/books.cpp].
[tip [tip
When writing a hash function, first look at how the equality function works. When writing a hash function, first look at how the equality function works.
@@ -170,7 +165,7 @@ of point, it can be repeatedly called for any number of elements. It calls
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed. [funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
Full code for this example is at Full code for this example is at
[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp]. [@boost:/libs/container_hash/examples/point.cpp /libs/container_hash/examples/point.cpp].
[note [note
When using [funcref boost::hash_combine] the order of the When using [funcref boost::hash_combine] the order of the
@@ -198,5 +193,15 @@ To calculate the hash of an iterator range you can use [funcref boost::hash_rang
std::vector<std::string> some_strings; std::vector<std::string> some_strings;
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end()); std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
[endsect] Note that when writing template classes, you might not want to include the main
hash header as it's quite an expensive include that brings in a lot of other
headers, so instead you can include the `<boost/container_hash/hash_fwd.hpp>`
header which forward declares [classref boost::hash],
[funcref boost::hash_range] and [funcref boost::hash_combine]. You'll need to
include the main header before instantiating [classref boost::hash]. When using
a container that uses [classref boost::hash] it should do that for you, so your
type will work fine with the boost hash containers. There's an example of this
in [@boost:/libs/container_hash/examples/template.hpp template.hpp] and
[@boost:/libs/container_hash/examples/template.cpp template.cpp].
[endsect]
-15
View File
@@ -1,15 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#-------------------------------------------------------------------------
#-- Needed include directories for the tests
boost_additional_test_dependencies(config BOOST_DEPENDS test)
#-------------------------------------------------------------------------
boost_test_run(books)
boost_test_run(point)
boost_test_run(portable)
+1
View File
@@ -6,3 +6,4 @@
run books.cpp ; run books.cpp ;
run point.cpp ; run point.cpp ;
run portable.cpp ; run portable.cpp ;
run template.cpp ;
+2 -1
View File
@@ -4,7 +4,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./books.hpp" #include "./books.hpp"
#include <boost/functional/hash.hpp> #include <boost/container_hash/hash.hpp>
#include <cassert> #include <cassert>
// If std::unordered_set was available: // If std::unordered_set was available:
@@ -20,6 +20,7 @@ int main()
boost::hash<library::book> book_hasher; boost::hash<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife); std::size_t knife_hash_value = book_hasher(knife);
(void)knife_hash_value; // suppress unused variable warning
// If std::unordered_set was available: // If std::unordered_set was available:
// //
+6 -1
View File
@@ -3,7 +3,12 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp> // Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/container_hash/hash.hpp>
#include <cassert> #include <cassert>
// This example illustrates how to use boost::hash_combine to generate a hash // This example illustrates how to use boost::hash_combine to generate a hash
+6 -1
View File
@@ -3,7 +3,12 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp> // Force use of assert.
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <boost/container_hash/hash.hpp>
#include <cassert> #include <cassert>
// This example illustrates how to customise boost::hash portably, so that // This example illustrates how to customise boost::hash portably, so that
+18
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
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/container_hash/hash_fwd.hpp>
template <typename A, typename B>
class my_pair
{
A value1;
B value2;
public:
my_pair(A const& v1, B const& v2)
: value1(v1), value2(v2)
{}
bool operator==(my_pair const& other) const
{
return value1 == other.value1 &&
value2 == other.value2;
}
friend std::size_t hash_value(my_pair const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.value1);
boost::hash_combine(seed, p.value2);
return seed;
}
};
@@ -7,12 +7,100 @@
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP #define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp> #include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp> #include <boost/config/no_tr1/cmath.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020) // Set BOOST_HASH_CONFORMANT_FLOATS to 1 for libraries known to have
# pragma once // sufficiently good floating point support to not require any
// workarounds.
//
// When set to 0, the library tries to automatically
// use the best available implementation. This normally works well, but
// breaks when ambiguities are created by odd namespacing of the functions.
//
// Note that if this is set to 0, the library should still take full
// advantage of the platform's floating point support.
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__LIBCOMO__)
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
// Rogue Wave library:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(_LIBCPP_VERSION)
// libc++
# define BOOST_HASH_CONFORMANT_FLOATS 1
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
// GNU libstdc++ 3
# if defined(__GNUC__) && __GNUC__ >= 4
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(__STL_CONFIG_H)
// generic SGI STL
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__MSL_CPP__)
// MSL standard lib:
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif defined(__IBMCPP__)
// VACPP std lib (probably conformant for much earlier version).
# if __IBMCPP__ >= 1210
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#elif defined(MSIPL_COMPILE_H)
// Modena C++ standard library
# define BOOST_HASH_CONFORMANT_FLOATS 0
#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
// Dinkumware Library (this has to appear after any possible replacement libraries):
# if _CPPLIB_VER >= 405
# define BOOST_HASH_CONFORMANT_FLOATS 1
# else
# define BOOST_HASH_CONFORMANT_FLOATS 0
# endif
#else
# define BOOST_HASH_CONFORMANT_FLOATS 0
#endif #endif
#if BOOST_HASH_CONFORMANT_FLOATS
// The standard library is known to be compliant, so don't use the
// configuration mechanism.
namespace boost {
namespace hash_detail {
template <typename Float>
struct call_ldexp {
typedef Float float_type;
inline Float operator()(Float x, int y) const {
return std::ldexp(x, y);
}
};
template <typename Float>
struct call_frexp {
typedef Float float_type;
inline Float operator()(Float x, int* y) const {
return std::frexp(x, y);
}
};
template <typename Float>
struct select_hash_type
{
typedef Float type;
};
}
}
#else // BOOST_HASH_CONFORMANT_FLOATS == 0
// The C++ standard requires that the C float functions are overloarded // The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older // for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99 // library implementations don't support this. On some that don't, the C99
@@ -84,7 +172,7 @@ namespace boost {
// the boost namespace they'll always be preferable to any other function // the boost namespace they'll always be preferable to any other function
// (since the arguments are built in types, ADL can't be used). // (since the arguments are built in types, ADL can't be used).
namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { namespace boost_hash_detect_float_functions {
template <class Float> boost::hash_detail::not_found ldexp(Float, int); template <class Float> boost::hash_detail::not_found ldexp(Float, int);
template <class Float> boost::hash_detail::not_found frexp(Float, int*); template <class Float> boost::hash_detail::not_found frexp(Float, int*);
} }
@@ -103,7 +191,7 @@ namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS {
// happen mainly when there's a template in the same namesapce. // happen mainly when there's a template in the same namesapce.
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \ #define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS { \ namespace boost_hash_detect_float_functions { \
template <class Float> \ template <class Float> \
boost::hash_detail::not_found c99_func(Float, type2); \ boost::hash_detail::not_found c99_func(Float, type2); \
} \ } \
@@ -112,7 +200,7 @@ namespace boost { \
namespace hash_detail { \ namespace hash_detail { \
namespace c99_func##_detect { \ namespace c99_func##_detect { \
using namespace std; \ using namespace std; \
using namespace BOOST_HASH_DETECT_FLOAT_FUNCTIONS; \ using namespace boost_hash_detect_float_functions; \
\ \
struct check { \ struct check { \
static type1 x; \ static type1 x; \
@@ -243,4 +331,6 @@ namespace boost
} }
} }
#endif // BOOST_HASH_CONFORMANT_FLOATS
#endif #endif
@@ -0,0 +1,271 @@
// Copyright 2005-2012 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/container_hash/detail/float_functions.hpp>
#include <boost/container_hash/detail/limits.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/limits.hpp>
#include <cstring>
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
// Can we use fpclassify?
// STLport
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#define BOOST_HASH_USE_FPCLASSIFY 0
// GNU libstdc++ 3
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY 1
# else
# define BOOST_HASH_USE_FPCLASSIFY 0
# endif
// Everything else
#else
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
////////////////////////////////////////////////////////////////////////
// Binary hash function
//
// Only used for floats with known iec559 floats, and certain values in
// numeric_limits
inline std::size_t hash_binary(char* ptr, std::size_t length)
{
std::size_t seed = 0;
if (length >= sizeof(std::size_t)) {
std::memcpy(&seed, ptr, sizeof(std::size_t));
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
while(length >= sizeof(std::size_t)) {
std::size_t buffer = 0;
std::memcpy(&buffer, ptr, sizeof(std::size_t));
hash_float_combine(seed, buffer);
length -= sizeof(std::size_t);
ptr += sizeof(std::size_t);
}
}
if (length > 0) {
std::size_t buffer = 0;
std::memcpy(&buffer, ptr, length);
hash_float_combine(seed, buffer);
}
return seed;
}
template <typename Float, unsigned digits, unsigned max_exponent>
struct enable_binary_hash
{
BOOST_STATIC_CONSTANT(bool, value =
std::numeric_limits<Float>::is_iec559 &&
std::numeric_limits<Float>::digits == digits &&
std::numeric_limits<Float>::radix == 2 &&
std::numeric_limits<Float>::max_exponent == max_exponent);
};
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 24, 128>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 4);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 53, 1024>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 8);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 64, 16384>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 10);
}
template <typename Float>
inline std::size_t float_hash_impl(Float v,
BOOST_DEDUCED_TYPENAME boost::enable_if_c<
enable_binary_hash<Float, 113, 16384>::value,
std::size_t>::type)
{
return hash_binary((char*) &v, 16);
}
////////////////////////////////////////////////////////////////////////
// Portable hash function
//
// Used as a fallback when the binary hash function isn't supported.
template <class T>
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
v = ldexp(v, limits<std::size_t>::digits);
std::size_t seed = static_cast<std::size_t>(v);
v -= static_cast<T>(seed);
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value
+ limits<std::size_t>::digits - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= static_cast<T>(part);
hash_float_combine(seed, part);
}
hash_float_combine(seed, static_cast<std::size_t>(exp));
return seed;
}
#if !defined(BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC)
template <class T>
inline std::size_t float_hash_impl(T v, ...)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
#endif
}
}
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
namespace boost
{
namespace hash_detail
{
template <class T>
inline std::size_t float_hash_value(T v)
{
#if defined(fpclassify)
switch (fpclassify(v))
#elif BOOST_HASH_CONFORMANT_FLOATS
switch (std::fpclassify(v))
#else
using namespace std;
switch (fpclassify(v))
#endif
{
case FP_ZERO:
return 0;
case FP_INFINITE:
return (std::size_t)(v > 0 ? -1 : -2);
case FP_NAN:
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v, 0);
default:
BOOST_ASSERT(0);
return 0;
}
}
}
}
#else // !BOOST_HASH_USE_FPCLASSIFY
namespace boost
{
namespace hash_detail
{
template <class T>
inline bool is_zero(T v)
{
#if !defined(__GNUC__) && !defined(__clang__)
return v == 0;
#else
// GCC's '-Wfloat-equal' will complain about comparing
// v to 0, but because it disables warnings for system
// headers it won't complain if you use std::equal_to to
// compare with 0. Resulting in this silliness:
return std::equal_to<T>()(v, 0);
#endif
}
template <class T>
inline std::size_t float_hash_value(T v)
{
return boost::hash_detail::is_zero(v) ? 0 : float_hash_impl(v, 0);
}
}
}
#endif // BOOST_HASH_USE_FPCLASSIFY
#undef BOOST_HASH_USE_FPCLASSIFY
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif
@@ -9,8 +9,9 @@
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER) #if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER #define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020) #include <boost/config.hpp>
# pragma once #if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif #endif
#include <boost/limits.hpp> #include <boost/limits.hpp>
+363
View File
@@ -0,0 +1,363 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
// This implements the extensions to the standard.
// It's undocumented, so you shouldn't use it....
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/config.hpp>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
#include <boost/container_hash/hash.hpp>
#include <boost/detail/container_fwd.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/static_assert.hpp>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
# include <tuple>
#endif
#if !defined(BOOST_NO_CXX11_HDR_MEMORY)
# include <memory>
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
namespace boost
{
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const&);
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const&);
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v);
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
template <class T>
std::size_t hash_value(std::complex<T> const&);
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
boost::hash_combine(seed, v.first);
boost::hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
template <class T>
std::size_t hash_value(std::complex<T> const& v)
{
boost::hash<T> hasher;
std::size_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
}
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
template <class T, std::size_t N>
std::size_t hash_value(std::array<T, N> const& v)
{
return boost::hash_range(v.begin(), v.end());
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
namespace hash_detail {
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I == std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t&, T const&)
{
}
template <std::size_t I, typename T>
inline typename boost::enable_if_c<(I < std::tuple_size<T>::value),
void>::type
hash_combine_tuple(std::size_t& seed, T const& v)
{
boost::hash_combine(seed, std::get<I>(v));
boost::hash_detail::hash_combine_tuple<I + 1>(seed, v);
}
template <typename T>
inline std::size_t hash_tuple(T const& v)
{
std::size_t seed = 0;
boost::hash_detail::hash_combine_tuple<0>(seed, v);
return seed;
}
}
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename... T>
inline std::size_t hash_value(std::tuple<T...> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
#else
inline std::size_t hash_value(std::tuple<> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0>
inline std::size_t hash_value(std::tuple<A0> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1>
inline std::size_t hash_value(std::tuple<A0, A1> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2>
inline std::size_t hash_value(std::tuple<A0, A1, A2> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
template<typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
inline std::size_t hash_value(std::tuple<A0, A1, A2, A3, A4, A5, A6, A7, A8, A9> const& v)
{
return boost::hash_detail::hash_tuple(v);
}
#endif
#endif
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
inline std::size_t hash_value(std::shared_ptr<T> const& x) {
return boost::hash_value(x.get());
}
template <typename T, typename Deleter>
inline std::size_t hash_value(std::unique_ptr<T, Deleter> const& x) {
return boost::hash_value(x.get());
}
#endif
//
// call_hash_impl
//
// On compilers without function template ordering, this deals with arrays.
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
{
template <bool IsArray>
struct call_hash_impl
{
template <class T>
struct inner
{
static std::size_t call(T const& v)
{
using namespace boost;
return hash_value(v);
}
};
};
template <>
struct call_hash_impl<true>
{
template <class Array>
struct inner
{
static std::size_t call(Array const& v)
{
const int size = sizeof(v) / sizeof(*v);
return boost::hash_range(v, v + size);
}
};
};
template <class T>
struct call_hash
: public call_hash_impl<boost::is_array<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//
// boost::hash
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: boost::hash_detail::hash_base<T>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T, unsigned int n> struct hash<T[n]>
: boost::hash_detail::hash_base<T[n]>
{
std::size_t operator()(const T* val) const
{
return boost::hash_range(val, val+n);
}
};
#endif
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// On compilers without partial specialization, boost::hash<T>
// has already been declared to deal with pointers, so just
// need to supply the non-pointer version of hash_impl.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<false>
{
template <class T>
struct inner
: boost::hash_detail::hash_base<T>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
};
}
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
#endif
+762
View File
@@ -0,0 +1,762 @@
// Copyright 2005-2014 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
//
// This also contains public domain code from MurmurHash. From the
// MurmurHash header:
// MurmurHash3 was written by Austin Appleby, and is placed in the public
// domain. The author hereby disclaims copyright to this source code.
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/container_hash/hash_fwd.hpp>
#include <functional>
#include <iterator>
#include <boost/container_hash/detail/hash_float.hpp>
#include <string>
#include <boost/limits.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/cstdint.hpp>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
#include <system_error>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6295) // Ill-defined for-loop : 'unsigned int' values
// are always of range '0' to '4294967295'.
// Loop executes infinitely.
#endif
#endif
#if BOOST_WORKAROUND(__GNUC__, < 3) \
&& !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
#else
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
#if defined(_MSC_VER)
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
#else
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
// Detect whether standard library has C++17 headers
#if !defined(BOOST_HASH_CXX17)
# if defined(BOOST_MSVC)
# if defined(_HAS_CXX17) && _HAS_CXX17
# define BOOST_HASH_CXX17 1
# endif
# elif defined(__cplusplus) && __cplusplus >= 201703
# define BOOST_HASH_CXX17 1
# endif
#endif
#if !defined(BOOST_HASH_CXX17)
# define BOOST_HASH_CXX17 0
#endif
#if BOOST_HASH_CXX17 && defined(__has_include)
# if !defined(BOOST_HASH_HAS_STRING_VIEW) && __has_include(<string_view>)
# define BOOST_HASH_HAS_STRING_VIEW 1
# endif
# if !defined(BOOST_HASH_HAS_OPTIONAL) && __has_include(<optional>)
# define BOOST_HASH_HAS_OPTIONAL 1
# endif
# if !defined(BOOST_HASH_HAS_VARIANT) && __has_include(<variant>)
# define BOOST_HASH_HAS_VARIANT 1
# endif
#endif
#if !defined(BOOST_HASH_HAS_STRING_VIEW)
# define BOOST_HASH_HAS_STRING_VIEW 0
#endif
#if !defined(BOOST_HASH_HAS_OPTIONAL)
# define BOOST_HASH_HAS_OPTIONAL 0
#endif
#if !defined(BOOST_HASH_HAS_VARIANT)
# define BOOST_HASH_HAS_VARIANT 0
#endif
#if BOOST_HASH_HAS_STRING_VIEW
# include <string_view>
#endif
#if BOOST_HASH_HAS_OPTIONAL
# include <optional>
#endif
#if BOOST_HASH_HAS_VARIANT
# include <variant>
#endif
namespace boost
{
namespace hash_detail
{
#if defined(BOOST_NO_CXX98_FUNCTION_BASE)
template <typename T>
struct hash_base
{
typedef T argument_type;
typedef std::size_t result_type;
};
#else
template <typename T>
struct hash_base : std::unary_function<T, std::size_t> {};
#endif
struct enable_hash_value { typedef std::size_t type; };
template <typename T> struct basic_numbers {};
template <typename T> struct long_numbers;
template <typename T> struct ulong_numbers;
template <typename T> struct float_numbers {};
template <> struct basic_numbers<bool> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<signed char> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned short> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned int> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<long> :
boost::hash_detail::enable_hash_value {};
template <> struct basic_numbers<unsigned long> :
boost::hash_detail::enable_hash_value {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <> struct basic_numbers<wchar_t> :
boost::hash_detail::enable_hash_value {};
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
template <> struct basic_numbers<char16_t> :
boost::hash_detail::enable_hash_value {};
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
template <> struct basic_numbers<char32_t> :
boost::hash_detail::enable_hash_value {};
#endif
// long_numbers is defined like this to allow for separate
// specialization for long_long and int128_type, in case
// they conflict.
template <typename T> struct long_numbers2 {};
template <typename T> struct ulong_numbers2 {};
template <typename T> struct long_numbers : long_numbers2<T> {};
template <typename T> struct ulong_numbers : ulong_numbers2<T> {};
#if !defined(BOOST_NO_LONG_LONG)
template <> struct long_numbers<boost::long_long_type> :
boost::hash_detail::enable_hash_value {};
template <> struct ulong_numbers<boost::ulong_long_type> :
boost::hash_detail::enable_hash_value {};
#endif
#if defined(BOOST_HAS_INT128)
template <> struct long_numbers2<boost::int128_type> :
boost::hash_detail::enable_hash_value {};
template <> struct ulong_numbers2<boost::uint128_type> :
boost::hash_detail::enable_hash_value {};
#endif
template <> struct float_numbers<float> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<double> :
boost::hash_detail::enable_hash_value {};
template <> struct float_numbers<long double> :
boost::hash_detail::enable_hash_value {};
}
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T);
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T);
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T);
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
template <class T> std::size_t hash_value(T*);
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
std::size_t hash_value(const T (&x)[N]);
template< class T, unsigned N >
std::size_t hash_value(T (&x)[N]);
#endif
template <class Ch, class A>
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
#if BOOST_HASH_HAS_STRING_VIEW
template <class Ch>
std::size_t hash_value(
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const&);
#endif
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T);
#if BOOST_HASH_HAS_OPTIONAL
template <typename T>
std::size_t hash_value(std::optional<T> const&);
#endif
#if BOOST_HASH_HAS_VARIANT
std::size_t hash_value(std::monostate);
template <typename... Types>
std::size_t hash_value(std::variant<Types...> const&);
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::size_t hash_value(std::type_index);
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
std::size_t hash_value(std::error_code const&);
std::size_t hash_value(std::error_condition const&);
#endif
// Implementation
namespace hash_detail
{
template <class T>
inline std::size_t hash_value_signed(T val)
{
const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ static_cast<int>(size_t_bits);
std::size_t seed = 0;
T positive = val < 0 ? -1 - val : val;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <class T>
inline std::size_t hash_value_unsigned(T val)
{
const unsigned int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ static_cast<int>(size_t_bits);
std::size_t seed = 0;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <typename SizeT>
inline void hash_combine_impl(SizeT& seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
inline void hash_combine_impl(boost::uint32_t& h1,
boost::uint32_t k1)
{
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
k1 *= c1;
k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
}
// Don't define 64-bit hash combine on platforms without 64 bit integers,
// and also not for 32-bit gcc as it warns about the 64-bit constant.
#if !defined(BOOST_NO_INT64_T) && \
!(defined(__GNUC__) && ULONG_MAX == 0xffffffff)
inline void hash_combine_impl(boost::uint64_t& h,
boost::uint64_t k)
{
const boost::uint64_t m = UINT64_C(0xc6a4a7935bd1e995);
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
// Completely arbitrary number, to prevent 0's
// from hashing to 0.
h += 0xe6546b64;
}
#endif // BOOST_NO_INT64_T
}
template <typename T>
typename boost::hash_detail::basic_numbers<T>::type hash_value(T v)
{
return static_cast<std::size_t>(v);
}
template <typename T>
typename boost::hash_detail::long_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_signed(v);
}
template <typename T>
typename boost::hash_detail::ulong_numbers<T>::type hash_value(T v)
{
return hash_detail::hash_value_unsigned(v);
}
template <typename T>
typename boost::enable_if<boost::is_enum<T>, std::size_t>::type
hash_value(T v)
{
return static_cast<std::size_t>(v);
}
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const& v)
#else
template <class T> std::size_t hash_value(T* v)
#endif
{
#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
// for some reason ptrdiff_t on OpenVMS compiler with
// 64 bit is not 64 bit !!!
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<long long int>(v));
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
#endif
return x + (x >> 3);
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
{
boost::hash<T> hasher;
return boost::hash_detail::hash_combine_impl(seed, hasher(v));
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class It>
inline std::size_t hash_range(It first, It last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
}
return seed;
}
template <class It>
inline void hash_range(std::size_t& seed, It first, It last)
{
for(; first != last; ++first)
{
hash_combine<typename std::iterator_traits<It>::value_type>(seed, *first);
}
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T>
inline std::size_t hash_range(T* first, T* last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
template <class T>
inline void hash_range(std::size_t& seed, T* first, T* last)
{
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
inline std::size_t hash_value(const T (&x)[N])
{
return hash_range(x, x + N);
}
template< class T, unsigned N >
inline std::size_t hash_value(T (&x)[N])
{
return hash_range(x, x + N);
}
#endif
template <class Ch, class A>
inline std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
#if BOOST_HASH_HAS_STRING_VIEW
template <class Ch>
inline std::size_t hash_value(
std::basic_string_view<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch> > const& v)
{
return hash_range(v.begin(), v.end());
}
#endif
template <typename T>
typename boost::hash_detail::float_numbers<T>::type hash_value(T v)
{
return boost::hash_detail::float_hash_value(v);
}
#if BOOST_HASH_HAS_OPTIONAL
template <typename T>
inline std::size_t hash_value(std::optional<T> const& v) {
if (!v) {
// Arbitray value for empty optional.
return 0x12345678;
} else {
boost::hash<T> hf;
return hf(*v);
}
}
#endif
#if BOOST_HASH_HAS_VARIANT
inline std::size_t hash_value(std::monostate) {
return 0x87654321;
}
template <typename... Types>
inline std::size_t hash_value(std::variant<Types...> const& v) {
std::size_t seed = 0;
hash_combine(seed, v.index());
std::visit([&seed](auto&& x) { hash_combine(seed, x); }, v);
return seed;
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline std::size_t hash_value(std::type_index v)
{
return v.hash_code();
}
#endif
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
inline std::size_t hash_value(std::error_code const& v) {
std::size_t seed = 0;
hash_combine(seed, v.value());
hash_combine(seed, &v.category());
return seed;
}
inline std::size_t hash_value(std::error_condition const& v) {
std::size_t seed = 0;
hash_combine(seed, v.value());
hash_combine(seed, &v.category());
return seed;
}
#endif
//
// boost::hash
//
// Define the specializations required by the standard. The general purpose
// boost::hash is defined later in extensions.hpp if
// BOOST_HASH_NO_EXTENSIONS is not defined.
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by const reference.
//
// These are undefined later.
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public boost::hash_detail::hash_base<type> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public boost::hash_detail::hash_base<type> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_TEMPLATE_REF(type) \
struct hash<type> \
: public boost::hash_detail::hash_base<type> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
BOOST_HASH_SPECIALIZE(bool)
BOOST_HASH_SPECIALIZE(char)
BOOST_HASH_SPECIALIZE(signed char)
BOOST_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE(wchar_t)
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_HASH_SPECIALIZE(char16_t)
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_HASH_SPECIALIZE(char32_t)
#endif
BOOST_HASH_SPECIALIZE(short)
BOOST_HASH_SPECIALIZE(unsigned short)
BOOST_HASH_SPECIALIZE(int)
BOOST_HASH_SPECIALIZE(unsigned int)
BOOST_HASH_SPECIALIZE(long)
BOOST_HASH_SPECIALIZE(unsigned long)
BOOST_HASH_SPECIALIZE(float)
BOOST_HASH_SPECIALIZE(double)
BOOST_HASH_SPECIALIZE(long double)
BOOST_HASH_SPECIALIZE_REF(std::string)
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string<char16_t>)
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string<char32_t>)
#endif
#if BOOST_HASH_HAS_STRING_VIEW
BOOST_HASH_SPECIALIZE_REF(std::string_view)
# if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE_REF(std::wstring_view)
# endif
# if !defined(BOOST_NO_CXX11_CHAR16_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char16_t>)
# endif
# if !defined(BOOST_NO_CXX11_CHAR32_T)
BOOST_HASH_SPECIALIZE_REF(std::basic_string_view<char32_t>)
# endif
#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#if defined(BOOST_HAS_INT128)
BOOST_HASH_SPECIALIZE(boost::int128_type)
BOOST_HASH_SPECIALIZE(boost::uint128_type)
#endif
#if BOOST_HASH_HAS_OPTIONAL
template <typename T>
BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::optional<T>)
#endif
#if !defined(BOOST_HASH_HAS_VARIANT)
template <typename... T>
BOOST_HASH_SPECIALIZE_TEMPLATE_REF(std::variant<T...>)
BOOST_HASH_SPECIALIZE(std::monostate)
#endif
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
BOOST_HASH_SPECIALIZE(std::type_index)
#endif
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
#undef BOOST_HASH_SPECIALIZE_TEMPLATE_REF
// Specializing boost::hash for pointers.
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct hash<T*>
: public boost::hash_detail::hash_base<T*>
{
std::size_t operator()(T* v) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
return boost::hash_value(v);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
#endif
}
};
#else
// For compilers without partial specialization, we define a
// boost::hash for all remaining types. But hash_impl is only defined
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
// is defined there will still be a compile error for types not supported
// in the standard.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<true>
{
template <class T>
struct inner
: public boost::hash_detail::hash_base<T>
{
std::size_t operator()(T val) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
return boost::hash_value(val);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(val));
return x + (x >> 3);
#endif
}
};
};
}
template <class T> struct hash
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#undef BOOST_HASH_CHAR_TRAITS
#undef BOOST_FUNCTIONAL_HASH_ROTL32
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
// Include this outside of the include guards in case the file is included
// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
// undefined.
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#include <boost/container_hash/extensions.hpp>
#endif
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#include <boost/config/workaround.hpp>
#include <cstddef>
#if defined(BOOST_HAS_PRAGMA_ONCE)
#pragma once
#endif
namespace boost
{
template <class T> struct hash;
template <class T> void hash_combine(std::size_t& seed, T const& v);
template <class It> std::size_t hash_range(It, It);
template <class It> void hash_range(std::size_t&, It, It);
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T> inline std::size_t hash_range(T*, T*);
template <class T> inline void hash_range(std::size_t&, T*, T*);
#endif
}
#endif
@@ -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
+1 -2
View File
@@ -3,5 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash.hpp> #include <boost/container_hash/hash.hpp>
@@ -1,101 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
// Include hash implementation for the current platform.
// Cygwn
#if defined(__CYGWIN__)
# if defined(__i386__) || defined(_M_IX86)
# include <boost/functional/hash/detail/hash_float_x86.hpp>
# else
# include <boost/functional/hash/detail/hash_float_generic.hpp>
# endif
#else
# include <boost/functional/hash/detail/hash_float_generic.hpp>
#endif
// Can we use fpclassify?
// STLport
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
#define BOOST_HASH_USE_FPCLASSIFY 0
// GNU libstdc++ 3
#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
# if (defined(__USE_ISOC99) || defined(_GLIBCXX_USE_C99_MATH)) && \
!(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
# define BOOST_HASH_USE_FPCLASSIFY 1
# else
# define BOOST_HASH_USE_FPCLASSIFY 0
# endif
// Everything else
#else
# define BOOST_HASH_USE_FPCLASSIFY 0
#endif
#if BOOST_HASH_USE_FPCLASSIFY
#include <boost/config/no_tr1/cmath.hpp>
namespace boost
{
namespace hash_detail
{
template <class T>
inline std::size_t float_hash_value(T v)
{
using namespace std;
switch (fpclassify(v)) {
case FP_ZERO:
return 0;
case FP_INFINITE:
return (std::size_t)(v > 0 ? -1 : -2);
case FP_NAN:
return (std::size_t)(-3);
case FP_NORMAL:
case FP_SUBNORMAL:
return float_hash_impl(v);
default:
BOOST_ASSERT(0);
return 0;
}
}
}
}
#else // !BOOST_HASH_USE_FPCLASSIFY
namespace boost
{
namespace hash_detail
{
template <class T>
inline std::size_t float_hash_value(T v)
{
return v == 0 ? 0 : float_hash_impl(v);
}
}
}
#endif // BOOST_HASH_USE_FPCLASSIFY
#undef BOOST_HASH_USE_FPCLASSIFY
#endif
@@ -1,93 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A general purpose hash function for non-zero floating point values.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
template <class T>
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
// The result of frexp is always between 0.5 and 1, so its
// top bit will always be 1. Subtract by 0.5 to remove that.
v -= T(0.5);
v = ldexp(v, limits<std::size_t>::digits + 1);
std::size_t seed = static_cast<std::size_t>(v);
v -= seed;
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= part;
hash_float_combine(seed, part);
}
hash_float_combine(seed, exp);
return seed;
}
template <class T>
inline std::size_t float_hash_impl(T v)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif
@@ -1,56 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A non-portable hash function form non-zero floats on x86.
//
// Even if you're on an x86 platform, this might not work if their floating
// point isn't set up as this expects. So this should only be used if it's
// absolutely certain that it will work.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER
#include <boost/cstdint.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
inline std::size_t float_hash_impl(float v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr;
return seed;
}
inline std::size_t float_hash_impl(double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr);
return seed;
}
inline std::size_t float_hash_impl(long double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr++);
hash_float_combine(seed, *(boost::uint16_t*)ptr);
return seed;
}
}
}
#endif
+2 -282
View File
@@ -1,286 +1,6 @@
// Copyright 2005-2009 Daniel James. // Copyright 2017 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal #include <boost/container_hash/extensions.hpp>
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
// This implements the extensions to the standard.
// It's undocumented, so you shouldn't use it....
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/functional/hash/hash.hpp>
#include <boost/detail/container_fwd.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
#include <boost/type_traits/is_array.hpp>
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#include <boost/type_traits/is_const.hpp>
#endif
namespace boost
{
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const&);
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const&);
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v);
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v);
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v);
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v);
template <class T>
std::size_t hash_value(std::complex<T> const&);
template <class A, class B>
std::size_t hash_value(std::pair<A, B> const& v)
{
std::size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
return seed;
}
template <class T, class A>
std::size_t hash_value(std::vector<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::list<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T, class A>
std::size_t hash_value(std::deque<T, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::set<K, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class C, class A>
std::size_t hash_value(std::multiset<K, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::map<K, T, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class K, class T, class C, class A>
std::size_t hash_value(std::multimap<K, T, C, A> const& v)
{
return hash_range(v.begin(), v.end());
}
template <class T>
std::size_t hash_value(std::complex<T> const& v)
{
boost::hash<T> hasher;
std::size_t seed = hasher(v.imag());
seed ^= hasher(v.real()) + (seed<<6) + (seed>>2);
return seed;
}
//
// call_hash_impl
//
// On compilers without function template ordering, this deals with arrays.
#if defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
namespace hash_detail
{
template <bool IsArray>
struct call_hash_impl
{
template <class T>
struct inner
{
static std::size_t call(T const& v)
{
using namespace boost;
return hash_value(v);
}
};
};
template <>
struct call_hash_impl<true>
{
template <class Array>
struct inner
{
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
static std::size_t call(Array const& v)
#else
static std::size_t call(Array& v)
#endif
{
const int size = sizeof(v) / sizeof(*v);
return boost::hash_range(v, v + size);
}
};
};
template <class T>
struct call_hash
: public call_hash_impl<boost::is_array<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
}
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
//
// boost::hash
//
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: std::unary_function<T, std::size_t>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
#if BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T, unsigned int n> struct hash<T[n]>
: std::unary_function<T[n], std::size_t>
{
std::size_t operator()(const T* val) const
{
return boost::hash_range(val, val+n);
}
};
#endif
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// On compilers without partial specialization, boost::hash<T>
// has already been declared to deal with pointers, so just
// need to supply the non-pointer version of hash_impl.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <>
struct hash_impl<false>
{
template <class T>
struct inner
: std::unary_function<T, std::size_t>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const
{
return hash_value(val);
}
#else
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T>::call(val);
}
#endif
};
};
#else // Visual C++ 6.5
// Visual C++ 6.5 has problems with nested member functions and
// applying const to const types in templates. So we get this:
template <bool IsConst>
struct hash_impl_msvc
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T const& val) const
{
return hash_detail::call_hash<T const>::call(val);
}
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <>
struct hash_impl_msvc<true>
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T& val) const
{
return hash_detail::call_hash<T>::call(val);
}
};
};
template <class T>
struct hash_impl_msvc2
: public hash_impl_msvc<boost::is_const<T>::value>
::BOOST_NESTED_TEMPLATE inner<T> {};
template <>
struct hash_impl<false>
{
template <class T>
struct inner : public hash_impl_msvc2<T> {};
};
#endif // Visual C++ 6.5
}
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
}
#endif
+1 -473
View File
@@ -3,476 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal #include <boost/container_hash/hash.hpp>
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/functional/hash/hash_fwd.hpp>
#include <functional>
#include <boost/functional/hash/detail/hash_float.hpp>
#include <string>
#include <boost/limits.hpp>
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#include <boost/type_traits/is_pointer.hpp>
#endif
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
#define BOOST_HASH_CHAR_TRAITS string_char_traits
#else
#define BOOST_HASH_CHAR_TRAITS char_traits
#endif
namespace boost
{
std::size_t hash_value(bool);
std::size_t hash_value(char);
std::size_t hash_value(unsigned char);
std::size_t hash_value(signed char);
std::size_t hash_value(short);
std::size_t hash_value(unsigned short);
std::size_t hash_value(int);
std::size_t hash_value(unsigned int);
std::size_t hash_value(long);
std::size_t hash_value(unsigned long);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
std::size_t hash_value(wchar_t);
#endif
#if defined(BOOST_HAS_LONG_LONG)
std::size_t hash_value(boost::long_long_type);
std::size_t hash_value(boost::ulong_long_type);
#endif
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
template <class T> std::size_t hash_value(T*);
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
std::size_t hash_value(const T (&x)[N]);
template< class T, unsigned N >
std::size_t hash_value(T (&x)[N]);
#endif
std::size_t hash_value(float v);
std::size_t hash_value(double v);
std::size_t hash_value(long double v);
template <class Ch, class A>
std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
// Implementation
namespace hash_detail
{
template <class T>
inline std::size_t hash_value_signed(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
T positive = val < 0 ? -1 - val : val;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <class T>
inline std::size_t hash_value_unsigned(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
}
inline std::size_t hash_value(bool v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(signed char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(long v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned long v)
{
return static_cast<std::size_t>(v);
}
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline std::size_t hash_value(wchar_t v)
{
return static_cast<std::size_t>(v);
}
#endif
#if defined(BOOST_HAS_LONG_LONG)
inline std::size_t hash_value(boost::long_long_type v)
{
return hash_detail::hash_value_signed(v);
}
inline std::size_t hash_value(boost::ulong_long_type v)
{
return hash_detail::hash_value_unsigned(v);
}
#endif
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const& v)
#else
template <class T> std::size_t hash_value(T* v)
#endif
{
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
}
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T>
inline void hash_combine(std::size_t& seed, T& v)
#else
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
#endif
{
boost::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
template <class It>
inline std::size_t hash_range(It first, It last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
return seed;
}
template <class It>
inline void hash_range(std::size_t& seed, It first, It last)
{
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T>
inline std::size_t hash_range(T* first, T* last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
template <class T>
inline void hash_range(std::size_t& seed, T* first, T* last)
{
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
inline std::size_t hash_value(const T (&x)[N])
{
return hash_range(x, x + N);
}
template< class T, unsigned N >
inline std::size_t hash_value(T (&x)[N])
{
return hash_range(x, x + N);
}
#endif
template <class Ch, class A>
inline std::size_t hash_value(std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
inline std::size_t hash_value(float v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(double v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(long double v)
{
return boost::hash_detail::float_hash_value(v);
}
//
// boost::hash
//
// Define the specializations required by the standard. The general purpose
// boost::hash is defined later in extensions.hpp if BOOST_HASH_NO_EXTENSIONS
// is not defined.
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by copy.
//
// These are undefined later.
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#else
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(const type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#endif
BOOST_HASH_SPECIALIZE(bool)
BOOST_HASH_SPECIALIZE(char)
BOOST_HASH_SPECIALIZE(signed char)
BOOST_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE(wchar_t)
#endif
BOOST_HASH_SPECIALIZE(short)
BOOST_HASH_SPECIALIZE(unsigned short)
BOOST_HASH_SPECIALIZE(int)
BOOST_HASH_SPECIALIZE(unsigned int)
BOOST_HASH_SPECIALIZE(long)
BOOST_HASH_SPECIALIZE(unsigned long)
BOOST_HASH_SPECIALIZE(float)
BOOST_HASH_SPECIALIZE(double)
BOOST_HASH_SPECIALIZE(long double)
BOOST_HASH_SPECIALIZE_REF(std::string)
#if !defined(BOOST_NO_STD_WSTRING)
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if defined(BOOST_HAS_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#undef BOOST_HASH_SPECIALIZE
#undef BOOST_HASH_SPECIALIZE_REF
// Specializing boost::hash for pointers.
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T>
struct hash<T*>
: public std::unary_function<T*, std::size_t>
{
std::size_t operator()(T* v) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590)
return boost::hash_value(v);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
#endif
}
};
#else
// For compilers without partial specialization, we define a
// boost::hash for all remaining types. But hash_impl is only defined
// for pointers in 'extensions.hpp' - so when BOOST_HASH_NO_EXTENSIONS
// is defined there will still be a compile error for types not supported
// in the standard.
namespace hash_detail
{
template <bool IsPointer>
struct hash_impl;
template <>
struct hash_impl<true>
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
{
std::size_t operator()(T val) const
{
#if !BOOST_WORKAROUND(__SUNPRO_CC, <= 590)
return boost::hash_value(val);
#else
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(val));
return x + (x >> 3);
#endif
}
};
};
}
template <class T> struct hash
: public boost::hash_detail::hash_impl<boost::is_pointer<T>::value>
::BOOST_NESTED_TEMPLATE inner<T>
{
};
#endif
}
#undef BOOST_HASH_CHAR_TRAITS
#endif // BOOST_FUNCTIONAL_HASH_HASH_HPP
// Include this outside of the include guards in case the file is included
// twice - once with BOOST_HASH_NO_EXTENSIONS defined, and then with it
// undefined.
#if !defined(BOOST_HASH_NO_EXTENSIONS) \
&& !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#include <boost/functional/hash/extensions.hpp>
#endif
+1 -35
View File
@@ -3,38 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal #include <boost/container_hash/hash_fwd.hpp>
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <cstddef>
#include <boost/detail/workaround.hpp>
namespace boost
{
template <class T> struct hash;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T> void hash_combine(std::size_t& seed, T& v);
#else
template <class T> void hash_combine(std::size_t& seed, T const& v);
#endif
template <class It> std::size_t hash_range(It, It);
template <class It> void hash_range(std::size_t&, It, It);
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T> inline std::size_t hash_range(T*, T*);
template <class T> inline void hash_range(std::size_t&, T*, T*);
#endif
}
#endif
+1 -2
View File
@@ -3,5 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash_fwd.hpp> #include <boost/container_hash/hash_fwd.hpp>
+96
View File
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Daniel James
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<explicit-failures-markup>
<!-- container_hash -->
<library name="container_hash">
<mark-expected-failures>
<test name="hash_value_array_test"/>
<toolset name="msvc-6.5*"/>
<toolset name="msvc-7.0*"/>
<note author="Daniel James">
hash_value is not overloaded for arrays for older versions
of Visual C++. There is a work around so that
boost::hash&lt;T[N]&gt;, boost::hash_combine and boost::hash_range
work.
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="hash_function_pointer_test"/>
<toolset name="msvc-6.5*"/>
<toolset name="msvc-7.0*"/>
<note refid="2" author="Daniel James"/>
</mark-expected-failures>
<mark-expected-failures>
<test name="hash_function_pointer_test"/>
<toolset name="sun-5.7"/>
<toolset name="sun-5.8"/>
<toolset name="sun-5.9"/>
<note author="Daniel James">
On these compilers the wrong overload of hash_value is called
when the argument is a hash function pointer. So calling
hash_value doesn't work but boost::hash does work (and it's
recommended that user never call hash_value directly so this
shouldn't be a problem).
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="hash_long_double_test"/>
<toolset name="gcc-3.4.3_sunos"/>
<toolset name="*pa_risc"/>
<note author="Daniel James">
This platform has poor support for <code>long double</code> so
the hash function perform poorly for values out of the range
of <code>double</code> or if they differ at a greater precision
that <code>double</code> is capable of representing.
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="point" />
<test name="books" />
<toolset name="msvc-6.5*"/>
<toolset name="msvc-7.0*"/>
<note author="Daniel James">
These examples only work on compilers with support for ADL.
It is possible to work around this, but I wanted to keep the
example code as clean as possible.
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="point" />
<toolset name="borland-*"/>
<note author="Daniel James">
It appears that Borland doesn't find friend functions defined
in a class by ADL. This is easily fixed but this example is
meant to show the typical way of customising boost::hash, not
the portable way.
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="hash_global_namespace_test" />
<toolset name="borland-*"/>
<note author="Daniel James">
The test demonstrates a Borland bug - functions that aren't
in a namespace don't appear to be found by ADL.
</note>
</mark-expected-failures>
<mark-expected-failures>
<test name="container_fwd_gcc_debug"/>
<toolset name="darwin-4.2"/>
<note author="Daniel James">
Debug containers aren't supported on Apple's version of gcc 4.2.
</note>
</mark-expected-failures>
</library>
</explicit-failures-markup>
+20
View File
@@ -0,0 +1,20 @@
[
{
"key": "functional/hash",
"boost-version": "1.33.0",
"name": "Container Hash",
"authors": [
"Daniel James"
],
"maintainers": [
"Daniel James <dnljms -at- gmail.com>"
],
"description": "An STL-compatible hash function object that can be extended to hash user defined types.",
"std": [
"tr1"
],
"category": [
"Function-objects"
]
}
]
-58
View File
@@ -1,58 +0,0 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#project hash-tests
# : requirements
# <toolset>gcc:<define>_GLIBCXX_DEBUG
# ;
if (GCC)
ADD_DEFINITIONS(-D_GLIBCXX_DEBUG)
endif(GCC)
# [ run .cpp : : : <test-info>always_show_run_output ]
#-------------------------------------------------------------------------
#-- Needed include directories for the tests
boost_additional_test_dependencies(functional BOOST_DEPENDS test)
#-------------------------------------------------------------------------
SET(tests
hash_fwd_test_1
hash_fwd_test_2
hash_number_test
hash_pointer_test
hash_function_pointer_test
hash_float_test
hash_long_double_test
hash_string_test
hash_range_test
hash_custom_test
hash_global_namespace_test
hash_friend_test
hash_built_in_array_test
hash_value_array_test
hash_vector_test
hash_list_test
hash_deque_test
hash_set_test
hash_map_test
hash_complex_test
container_fwd_test
hash_no_ext_macro_1
hash_no_ext_macro_2
)
boost_test_run(link_test link_test.cpp link_test_2.cpp)
boost_test_run(link_ext_test link_ext_test.cpp link_no_ext_test.cpp
)
foreach(test ${tests})
boost_test_run(${test})
endforeach(test ${tests})
boost_test_compile_fail(hash_no_ext_fail_test)
+38 -9
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 # Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -7,20 +7,29 @@ import testing ;
project hash-tests project hash-tests
: requirements : requirements
<toolset>gcc:<define>_GLIBCXX_DEBUG <warnings>all
<toolset>gcc:<cxxflags>-Wsign-promo <toolset>intel:<warnings>on
#<toolset>gcc:<cxxflags>-Wextra #<toolset>intel:<cxxflags>-strict-ansi
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
<toolset>clang:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wsign-conversion -Wconversion -Wfloat-equal -Wshadow"
#<toolset>msvc:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
; ;
test-suite functional/hash test-suite container_hash/hash
: :
[ run hash_info.cpp : : : <test-info>always_show_run_output ]
[ compile check_float_funcs.cpp ]
[ run hash_fwd_test_1.cpp ] [ run hash_fwd_test_1.cpp ]
[ run hash_fwd_test_2.cpp ] [ run hash_fwd_test_2.cpp ]
[ run hash_number_test.cpp ] [ run hash_number_test.cpp ]
[ run hash_enum_test.cpp ]
[ run hash_pointer_test.cpp ] [ run hash_pointer_test.cpp ]
[ run hash_function_pointer_test.cpp ] [ run hash_function_pointer_test.cpp ]
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ] [ run hash_float_test.cpp ]
[ run hash_long_double_test.cpp : : : <test-info>always_show_run_output ] [ run hash_long_double_test.cpp ]
[ run hash_string_test.cpp ] [ run hash_string_test.cpp ]
[ run hash_range_test.cpp ] [ run hash_range_test.cpp ]
[ run hash_custom_test.cpp ] [ run hash_custom_test.cpp ]
@@ -34,17 +43,24 @@ test-suite functional/hash
[ run hash_set_test.cpp ] [ run hash_set_test.cpp ]
[ run hash_map_test.cpp ] [ run hash_map_test.cpp ]
[ run hash_complex_test.cpp ] [ run hash_complex_test.cpp ]
[ run hash_optional_test.cpp ]
[ run hash_variant_test.cpp ]
[ run hash_type_index_test.cpp ]
[ run hash_system_error_test.cpp ]
[ run hash_std_array_test.cpp ]
[ run hash_std_tuple_test.cpp ]
[ run hash_std_smart_ptr_test.cpp ]
[ run link_test.cpp link_test_2.cpp ] [ run link_test.cpp link_test_2.cpp ]
[ run link_ext_test.cpp link_no_ext_test.cpp ] [ run link_ext_test.cpp link_no_ext_test.cpp ]
[ run extensions_hpp_test.cpp ] [ run extensions_hpp_test.cpp ]
[ run container_fwd_test.cpp ]
[ compile-fail hash_no_ext_fail_test.cpp ] [ compile-fail hash_no_ext_fail_test.cpp ]
[ compile-fail namespace_fail_test.cpp ] [ compile-fail namespace_fail_test.cpp ]
[ run implicit_test.cpp ]
[ run hash_no_ext_macro_1.cpp ] [ run hash_no_ext_macro_1.cpp ]
[ run hash_no_ext_macro_2.cpp ] [ run hash_no_ext_macro_2.cpp ]
; ;
test-suite functional/hash_no_ext test-suite container_hash/hash_no_ext
: :
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ] [ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ] [ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
@@ -55,4 +71,17 @@ test-suite functional/hash_no_ext
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ] [ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
; ;
# Tests to see if the floating point hash is using the binary hash.
# Not run normally because on some platforms these should fail.
test-suite container_hash/hash_no_generic_float
:
[ run hash_float_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_float_test_no_generic ]
[ run hash_long_double_test.cpp
: : : <define>BOOST_HASH_DETAIL_TEST_WITHOUT_GENERIC
: hash_long_double_test_no_generic ]
;
explicit container_hash/hash_no_generic_float ;
build-project ../examples ; build-project ../examples ;
+58
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
}
+7 -3
View File
@@ -5,12 +5,16 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp> #include <boost/type_traits/is_same.hpp>
template <class T> template <class T>
void compile_time_tests(T*) void compile_time_tests(T*)
{ {
BOOST_STATIC_ASSERT((boost::is_base_and_derived< BOOST_STATIC_ASSERT((boost::is_same<T,
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value)); typename BOOST_HASH_TEST_NAMESPACE::hash<T>::argument_type
>::value));
BOOST_STATIC_ASSERT((boost::is_same<std::size_t,
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::result_type
>::value));
} }
+16 -5
View File
@@ -3,12 +3,23 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if defined(TEST_STD) #if defined(BOOST_HASH_TEST_STD)
# define TEST_STD_INCLUDES # define BOOST_HASH_TEST_STD_INCLUDES
# define HASH_NAMESPACE std # define BOOST_HASH_TEST_NAMESPACE std
#else #else
# define HASH_NAMESPACE boost # define BOOST_HASH_TEST_NAMESPACE boost
# if !defined(BOOST_HASH_NO_EXTENSIONS) # if !defined(BOOST_HASH_NO_EXTENSIONS)
# define TEST_EXTENSIONS # define BOOST_HASH_TEST_EXTENSIONS
# endif # endif
#endif #endif
#if defined(_WIN32_WCE)
// The standard windows mobile headers trigger this warning so I disable it
// before doing anything else.
#pragma warning(disable:4201) // nonstandard extension used :
// nameless struct/union
#endif
#define HASH_TEST_CAT(x, y) HASH_TEST_CAT2(x, y)
#define HASH_TEST_CAT2(x, y) x##y
-109
View File
@@ -1,109 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/detail/container_fwd.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
{
}
#else
template <class charT, class Allocator>
static void test(std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
{
}
#endif
template <class T, class Allocator>
static void test(std::deque<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::list<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::vector<T, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::map<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::multimap<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::set<Key, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::multiset<Key, Compare, Allocator> const&)
{
}
template <std::size_t N>
static void test(std::bitset<N> const&)
{
}
template <class T>
static void test(std::complex<T> const&)
{
}
template <class X, class Y>
static void test(std::pair<X, Y> const&)
{
}
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#include <utility>
int main()
{
std::deque<int> x1;
std::list<std::string> x2;
std::vector<float> x3;
std::vector<bool> x4;
std::map<int, int> x5;
std::multimap<float, int*> x6;
std::set<std::string> x7;
std::multiset<std::vector<int> > x8;
std::bitset<10> x9;
std::string x10;
std::complex<double> x11;
std::pair<std::list<int>, char***> x12;
test(x1);
test(x2);
test(x3);
test(x4);
test(x5);
test(x6);
test(x7);
test(x8);
test(x9);
test(x10);
test(x11);
test(x12);
return 0;
}
+5 -3
View File
@@ -3,12 +3,14 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Check that boost/functional/hash/extensions.hpp works okay. // Check that boost/container_hash/extensions.hpp works okay.
// //
// It probably should be in boost/functional/hash/detail, but since it isn't it // It probably should be in boost/container_hash/detail, but since it isn't it
// should work. // should work.
#include <boost/functional/hash/extensions.hpp> #include "./config.hpp"
#include <boost/container_hash/extensions.hpp>
int main() { int main() {
int x[2] = { 2, 3 }; int x[2] = { 2, 3 };
+17 -17
View File
@@ -5,17 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
void array_int_test() void array_int_test()
{ {
@@ -27,47 +27,47 @@ void array_int_test()
8, -12, 23, 65, 45, 8, -12, 23, 65, 45,
-1, 93, -54, 987, 3 -1, 93, -54, 987, 3
}; };
HASH_NAMESPACE::hash<int[25]> hasher1; BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
const int length2 = 1; const int length2 = 1;
int array2[1] = {3}; int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2; BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
const int length3 = 2; const int length3 = 2;
int array3[2] = {2, 3}; int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3; BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1) BOOST_TEST(hasher1(array1)
== HASH_NAMESPACE::hash_range(array1, array1 + length1)); == BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
BOOST_TEST(hasher2(array2) BOOST_TEST(hasher2(array2)
== HASH_NAMESPACE::hash_range(array2, array2 + length2)); == BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
BOOST_TEST(hasher3(array3) BOOST_TEST(hasher3(array3)
== HASH_NAMESPACE::hash_range(array3, array3 + length3)); == BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
} }
void two_dimensional_array_test() void two_dimensional_array_test()
{ {
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}}; int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher; BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
std::size_t seed1 = 0; std::size_t seed1 = 0;
for(int i = 0; i < 3; ++i) for(int i = 0; i < 3; ++i)
{ {
std::size_t seed2 = 0; std::size_t seed2 = 0;
for(int j = 0; j < 2; ++j) for(int j = 0; j < 2; ++j)
HASH_NAMESPACE::hash_combine(seed2, array[i][j]); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
HASH_NAMESPACE::hash_combine(seed1, seed2); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
} }
BOOST_TEST(hasher(array) == seed1); BOOST_TEST(hasher(array) == seed1);
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3)); BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
} }
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
array_int_test(); array_int_test();
two_dimensional_array_test(); two_dimensional_array_test();
#endif #endif
+36 -22
View File
@@ -5,42 +5,52 @@
#include "./config.hpp" #include "./config.hpp"
#if !defined(TEST_EXTENSIONS) #if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {} int main() {}
#else #else
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#if defined(BOOST_MSVC)
#pragma warning(disable:4244) // conversion from 'unsigned long' to
// 'unsigned short', possible loss of data
#pragma warning(disable:4245) // conversion from 'int' to
// 'const unsigned short',
// signed/unsigned mismatch
#pragma warning(disable:4305) // truncation from 'double' to
// 'const std::complex<float>::_Ty'
#pragma warning(disable:4309) // truncation of constant value
#pragma warning(disable:4512) // assignment operator could not be generated
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <complex> #include <complex>
#include <sstream> #include <sstream>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'unsigned long' to 'unsigned short', possible loss of data
#pragma warning(disable:4512) // assignment operator could not be generated
#endif
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class T> template <class T>
void generic_complex_tests(std::complex<T> v) void generic_complex_tests(std::complex<T> v)
{ {
HASH_NAMESPACE::hash<std::complex<T> > complex_hasher; BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_TEST(complex_hasher(v) == complex_hasher(v)); BOOST_TEST(complex_hasher(v) == complex_hasher(v));
HASH_NAMESPACE::hash<T> real_hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
T real = v.real(); T real = v.real();
T imag = v.imag(); T imag = v.imag();
@@ -63,7 +73,7 @@ void complex_float_tests(Float*)
generic_complex_tests(complex(0.5,0)); generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0)); generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0)); generic_complex_tests(complex(25,0));
generic_complex_tests(complex(-67.5324535,56.23578678)); generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
} }
template <class Integer> template <class Integer>
@@ -74,23 +84,27 @@ void complex_integral_tests(Integer*)
generic_complex_tests(complex(15342,124)); generic_complex_tests(complex(15342,124));
generic_complex_tests(complex(25,54356)); generic_complex_tests(complex(25,54356));
generic_complex_tests(complex(5325,2346)); generic_complex_tests(complex(5325,2346));
generic_complex_tests(complex(-243897,-49923874)); generic_complex_tests(complex(Integer(-243897),Integer(-49923874)));
generic_complex_tests(complex(-543,763)); generic_complex_tests(complex(Integer(-543),Integer(763)));
} }
int main() int main()
{ {
// I've comments out the short and unsigned short tests
// as they cause warnings and don't really test
// anything that the other tests already deal with.
complex_float_tests((float*) 0); complex_float_tests((float*) 0);
complex_float_tests((double*) 0); complex_float_tests((double*) 0);
complex_float_tests((long double*) 0); complex_float_tests((long double*) 0);
complex_integral_tests((short*) 0); //complex_integral_tests((short*) 0);
complex_integral_tests((int*) 0); complex_integral_tests((int*) 0);
complex_integral_tests((long*) 0); complex_integral_tests((long*) 0);
complex_integral_tests((unsigned short*) 0); //complex_integral_tests((unsigned short*) 0);
complex_integral_tests((unsigned int*) 0); complex_integral_tests((unsigned int*) 0);
complex_integral_tests((unsigned long*) 0); complex_integral_tests((unsigned long*) 0);
return boost::report_errors(); return boost::report_errors();
} }
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
+19 -18
View File
@@ -3,6 +3,7 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/config.hpp> #include <boost/config.hpp>
#include <cstddef> #include <cstddef>
@@ -14,7 +15,7 @@ namespace test
std::size_t hash() const std::size_t hash() const
{ {
return value_ * 10; return static_cast<std::size_t>(value_ * 10);
} }
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -40,17 +41,17 @@ namespace boost
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector> #include <vector>
#include <string> #include <string>
@@ -58,13 +59,13 @@ namespace boost
void custom_tests() void custom_tests()
{ {
HASH_NAMESPACE::hash<test::custom> custom_hasher; BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u); BOOST_TEST(custom_hasher(10) == 100u);
test::custom x(55); test::custom x(55);
BOOST_TEST(custom_hasher(x) == 550u); BOOST_TEST(custom_hasher(x) == 550u);
{ {
using namespace HASH_NAMESPACE; using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x)); BOOST_TEST(custom_hasher(x) == hash_value(x));
} }
@@ -74,25 +75,25 @@ void custom_tests()
custom_vector.push_back(35); custom_vector.push_back(35);
std::size_t seed = 0; std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom(5)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
HASH_NAMESPACE::hash_combine(seed, test::custom(25)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
HASH_NAMESPACE::hash_combine(seed, test::custom(35)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
std::size_t seed2 = 0; std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2); BOOST_TEST(seed == seed2);
} }
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests(); custom_tests();
#endif #endif
return boost::report_errors(); return boost::report_errors();
+7 -7
View File
@@ -5,17 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <deque> #include <deque>
@@ -23,11 +23,11 @@ using std::deque;
#define CONTAINER_TYPE deque #define CONTAINER_TYPE deque
#include "./hash_sequence_test.hpp" #include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
deque_tests::deque_hash_integer_tests(); deque_tests::deque_hash_integer_tests();
#endif #endif
+63
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/container_hash/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#include "./compile_time.hpp"
namespace test {
enum enum_override { enum_override1, enum_override2 };
std::size_t hash_value(enum_override) { return 896532; }
enum enum1 { enum1a };
enum enum2 { enum2a, enum2b };
enum enum3 { enum3a = 574, enum3b };
enum enum4 { enum4a = -12574, enum4b };
}
int main() {
compile_time_tests((test::enum1*) 0);
compile_time_tests((test::enum2*) 0);
compile_time_tests((test::enum3*) 0);
compile_time_tests((test::enum4*) 0);
compile_time_tests((test::enum_override*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<test::enum1> hash1;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum2> hash2;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum3> hash3;
BOOST_HASH_TEST_NAMESPACE::hash<test::enum4> hash4;
BOOST_TEST(hash1(test::enum1a) == hash1(test::enum1a));
BOOST_TEST(hash2(test::enum2a) == hash2(test::enum2a));
BOOST_TEST(hash2(test::enum2a) != hash2(test::enum2b));
BOOST_TEST(hash2(test::enum2b) == hash2(test::enum2b));
BOOST_TEST(hash3(test::enum3a) == hash3(test::enum3a));
BOOST_TEST(hash3(test::enum3a) != hash3(test::enum3b));
BOOST_TEST(hash3(test::enum3b) == hash3(test::enum3b));
BOOST_TEST(hash4(test::enum4a) == hash4(test::enum4a));
BOOST_TEST(hash4(test::enum4a) != hash4(test::enum4b));
BOOST_TEST(hash4(test::enum4b) == hash4(test::enum4b));
BOOST_HASH_TEST_NAMESPACE::hash<test::enum_override> hash_override;
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override2));
BOOST_TEST(hash_override(test::enum_override1) ==
hash_override(test::enum_override1));
return boost::report_errors();
}
+128 -60
View File
@@ -5,24 +5,33 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <cmath> #include <cmath>
#include <boost/functional/hash/detail/limits.hpp> #include <boost/container_hash/detail/limits.hpp>
#include <boost/functional/hash/detail/float_functions.hpp> #include <boost/container_hash/detail/float_functions.hpp>
#include <boost/detail/workaround.hpp> #include <boost/config/workaround.hpp>
#include <iostream> #include <iostream>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable:4127) // conditional expression is constant
#pragma warning(disable:4723) // conditional expression is constant
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif #endif
char const* float_type(float*) { return "float"; } char const* float_type(float*) { return "float"; }
@@ -32,26 +41,36 @@ char const* float_type(long double*) { return "long double"; }
template <class T> template <class T>
void float_tests(char const* name, T* = 0) void float_tests(char const* name, T* = 0)
{ {
std::cerr<<"\n" std::cerr
<<"Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"<<name<<">\n" << "\n"
<<"\n" << "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
<<"boost::hash_detail::limits<T>::digits = " << name
<<boost::hash_detail::limits<T>::digits<<"\n" << ">\n"
<<"boost::hash_detail::limits<int>::digits = " << "\n"
<<boost::hash_detail::limits<int>::digits<<"\n" << "boost::hash_detail::limits<T>::digits = "
<<"boost::hash_detail::limits<std::size_t>::digits = " << boost::hash_detail::limits<T>::digits<< "\n"
<<boost::hash_detail::limits<std::size_t>::digits<<"\n" << "boost::hash_detail::limits<int>::digits = "
<<"\n" << boost::hash_detail::limits<int>::digits<< "\n"
<<"boost::hash_detail::call_ldexp<T>::float_type = " << "boost::hash_detail::limits<std::size_t>::digits = "
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_ldexp<T>::float_type*)0)<<"\n" << boost::hash_detail::limits<std::size_t>::digits
<<"boost::hash_detail::call_frexp<T>::float_type = " << "\n"
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::call_frexp<T>::float_type*)0)<<"\n" << "\n"
<<"boost::hash_detail::select_hash_type<T>::type = " << "boost::hash_detail::call_ldexp<T>::float_type = "
<<float_type((BOOST_DEDUCED_TYPENAME boost::hash_detail::select_hash_type<T>::type*)0)<<"\n" << float_type(static_cast<BOOST_DEDUCED_TYPENAME
<<"\n" boost::hash_detail::call_ldexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::call_frexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_frexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::select_hash_type<T>::type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::select_hash_type<T>::type*>(0))
<< "\n"
<< "\n"
; ;
HASH_NAMESPACE::hash<T> x1; BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
T zero = 0; T zero = 0;
T minus_zero = (T) -1 * zero; T minus_zero = (T) -1 * zero;
@@ -59,16 +78,23 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(zero == minus_zero); BOOST_TEST(zero == minus_zero);
BOOST_TEST(x1(zero) == x1(minus_zero)); BOOST_TEST(x1(zero) == x1(minus_zero));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero)); BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero)); BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
#endif #endif
BOOST_TEST(x1(zero) != x1(0.5));
BOOST_TEST(x1(minus_zero) != x1(0.5));
BOOST_TEST(x1(0.5) != x1(-0.5));
BOOST_TEST(x1(1) != x1(-1));
using namespace std; using namespace std;
// Doing anything with infinity causes borland to crash. // Doing anything with infinity causes borland to crash.
#if defined(__BORLANDC__) #if defined(__BORLANDC__)
std::cerr<<"Not running infinity checks on Borland, as it causes it to crash.\n"; std::cerr
<< "Not running infinity checks on Borland, as it causes it to crash."
"\n";
#else #else
if(boost::hash_detail::limits<T>::has_infinity) { if(boost::hash_detail::limits<T>::has_infinity) {
T infinity = -log(zero); T infinity = -log(zero);
@@ -80,10 +106,10 @@ void float_tests(char const* name, T* = 0)
T minus_infinity2 = (T) -1. / zero; T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero; T minus_infinity3 = (T) 1. / minus_zero;
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity)); BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity) BOOST_TEST(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity)); == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
#endif #endif
if(infinity == infinity2) if(infinity == infinity2)
@@ -107,19 +133,40 @@ void float_tests(char const* name, T* = 0)
// This should really be 'has_denorm == denorm_present' but some // This should really be 'has_denorm == denorm_present' but some
// compilers don't have 'denorm_present'. See also a later use. // compilers don't have 'denorm_present'. See also a later use.
if(boost::hash_detail::limits<T>::has_denorm) { if(boost::hash_detail::limits<T>::has_denorm) {
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity)) { if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(infinity))
std::cerr<<"x1(denorm_min) == x1(infinity) == "<<x1(infinity)<<"\n"; {
std::cerr
<< "x1(denorm_min) == x1(infinity) == "
<< x1(infinity)
<< "\n";
} }
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(minus_infinity)) {
std::cerr<<"x1(denorm_min) == x1(-infinity) == "<<x1(minus_infinity)<<"\n"; if(x1(boost::hash_detail::limits<T>::denorm_min()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(denorm_min) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
} }
} }
if(boost::hash_detail::limits<T>::has_quiet_NaN) { if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity)) { if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(infinity))
std::cerr<<"x1(quiet_NaN) == x1(infinity) == "<<x1(infinity)<<"\n"; {
std::cerr
<< "x1(quiet_NaN) == x1(infinity) == "
<< x1(infinity)
<< "\n";
} }
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(minus_infinity)) {
std::cerr<<"x1(quiet_NaN) == x1(-infinity) == "<<x1(minus_infinity)<<"\n"; if(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
x1(minus_infinity))
{
std::cerr
<< "x1(quiet_NaN) == x1(-infinity) == "
<< x1(minus_infinity)
<< "\n";
} }
} }
} }
@@ -138,14 +185,22 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(half_max != three_quarter_max); BOOST_TEST(half_max != three_quarter_max);
BOOST_TEST(quarter_max != three_quarter_max); BOOST_TEST(quarter_max != three_quarter_max);
#if defined(TEST_EXTENSIONS) BOOST_TEST(max != -max);
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max)); BOOST_TEST(half_max != -half_max);
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max)); BOOST_TEST(quarter_max != -quarter_max);
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max)); BOOST_TEST(three_quarter_max != -three_quarter_max);
BOOST_TEST(x1(three_quarter_max) == HASH_NAMESPACE::hash_value(three_quarter_max));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) ==
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
#endif #endif
// The '!=' tests could legitimately fail, but with my hash it indicates a bug. // The '!=' tests could legitimately fail, but with my hash it indicates a
// bug.
BOOST_TEST(x1(max) == x1(max)); BOOST_TEST(x1(max) == x1(max));
BOOST_TEST(x1(max) != x1(quarter_max)); BOOST_TEST(x1(max) != x1(quarter_max));
BOOST_TEST(x1(max) != x1(half_max)); BOOST_TEST(x1(max) != x1(half_max));
@@ -157,6 +212,12 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(x1(half_max) != x1(three_quarter_max)); BOOST_TEST(x1(half_max) != x1(three_quarter_max));
BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max)); BOOST_TEST(x1(three_quarter_max) == x1(three_quarter_max));
BOOST_TEST(x1(max) != x1(-max));
BOOST_TEST(x1(half_max) != x1(-half_max));
BOOST_TEST(x1(quarter_max) != x1(-quarter_max));
BOOST_TEST(x1(three_quarter_max) != x1(-three_quarter_max));
// Intel with gcc stdlib sometimes segfaults on calls to asin and acos. // Intel with gcc stdlib sometimes segfaults on calls to asin and acos.
#if !((defined(__INTEL_COMPILER) || defined(__ICL) || \ #if !((defined(__INTEL_COMPILER) || defined(__ICL) || \
defined(__ICC) || defined(__ECC)) && \ defined(__ICC) || defined(__ECC)) && \
@@ -166,16 +227,17 @@ void float_tests(char const* name, T* = 0)
if(v1 == v2) if(v1 == v2)
BOOST_TEST(x1(v1) == x1(v2)); BOOST_TEST(x1(v1) == x1(v2));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1)); BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2)); BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
#endif #endif
#endif #endif
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) == BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::epsilon())); BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::epsilon()));
#endif #endif
BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0); BOOST_TEST(boost::hash_detail::limits<T>::epsilon() != (T) 0);
@@ -207,31 +269,37 @@ void float_tests(char const* name, T* = 0)
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) { if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n"; std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
} }
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(TEST_EXTENSIONS) #if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the // The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of boost::hash_detail::limits::denorm_min() for long // specialization of boost::hash_detail::limits::denorm_min() for long
// doubles which causes this test to fail. // doubles which causes this test to fail.
if(x1(boost::hash_detail::limits<T>::denorm_min()) != if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::denorm_min())) BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()))
{ {
std::cerr<<"x1(boost::hash_detail::limits<T>::denorm_min()) = " std::cerr
<< x1(boost::hash_detail::limits<T>::denorm_min()) << "x1(boost::hash_detail::limits<T>::denorm_min()) = "
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min()) = " << x1(boost::hash_detail::limits<T>::denorm_min())
<< HASH_NAMESPACE::hash_value( << "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
" = "
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()) boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "<<x1(0)<<"\n"; << "\nx1(0) = "
<< x1(0)
<< "\n";
} }
#endif #endif
} }
// NaN also causes borland to crash. // NaN also causes borland to crash.
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS) #if !defined(__BORLANDC__) && defined(BOOST_HASH_TEST_EXTENSIONS)
if(boost::hash_detail::limits<T>::has_quiet_NaN) { if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) { if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n"; std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
} }
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) == BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
HASH_NAMESPACE::hash_value(boost::hash_detail::limits<T>::quiet_NaN())); BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
} }
#endif #endif
} }
+20 -18
View File
@@ -3,6 +3,8 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/config.hpp> #include <boost/config.hpp>
#include <cstddef> #include <cstddef>
@@ -15,7 +17,7 @@ namespace test
std::size_t hash() const std::size_t hash() const
{ {
return value_ * 10; return static_cast<std::size_t>(value_ * 10);
} }
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -42,17 +44,17 @@ namespace boost
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector> #include <vector>
#include <string> #include <string>
@@ -60,13 +62,13 @@ namespace boost
void custom_tests() void custom_tests()
{ {
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher; BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u); BOOST_TEST(custom_hasher(10) == 100u);
test::custom<int> x(55); test::custom<int> x(55);
BOOST_TEST(custom_hasher(x) == 550u); BOOST_TEST(custom_hasher(x) == 550u);
{ {
using namespace HASH_NAMESPACE; using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x)); BOOST_TEST(custom_hasher(x) == hash_value(x));
} }
@@ -76,25 +78,25 @@ void custom_tests()
custom_vector.push_back(35); custom_vector.push_back(35);
std::size_t seed = 0; std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
std::size_t seed2 = 0; std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2); BOOST_TEST(seed == seed2);
} }
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests(); custom_tests();
#endif #endif
return boost::report_errors(); return boost::report_errors();
+8 -12
View File
@@ -5,17 +5,13 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp" #include "./compile_time.hpp"
void void_func1() { static int x = 1; ++x; } void void_func1() { static int x = 1; ++x; }
@@ -28,8 +24,8 @@ void function_pointer_tests()
compile_time_tests((void(**)()) 0); compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0); compile_time_tests((int(**)(int)) 0);
HASH_NAMESPACE::hash<void(*)()> hasher_void; BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int; BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_TEST(&void_func1 != &void_func2); BOOST_TEST(&void_func1 != &void_func2);
BOOST_TEST(&int_func1 != &int_func2); BOOST_TEST(&int_func1 != &int_func2);
@@ -42,11 +38,11 @@ void function_pointer_tests()
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1)); BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2)); BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0)); BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(hasher_void(&void_func1) BOOST_TEST(hasher_void(&void_func1)
== HASH_NAMESPACE::hash_value(&void_func1)); == BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
BOOST_TEST(hasher_int(&int_func1) BOOST_TEST(hasher_int(&int_func1)
== HASH_NAMESPACE::hash_value(&int_func1)); == BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal: // This isn't specified in Peter's proposal:
BOOST_TEST(hasher_void(0) == 0); BOOST_TEST(hasher_void(0) == 0);
+14 -12
View File
@@ -5,8 +5,8 @@
#include "./config.hpp" #include "./config.hpp"
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) #if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/functional/hash_fwd.hpp> #include <boost/container_hash/hash_fwd.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <cstddef> #include <cstddef>
@@ -25,7 +25,7 @@ namespace test {
template <class T> template <class T>
std::size_t hash_value(test_type1<T> const& x) std::size_t hash_value(test_type1<T> const& x)
{ {
HASH_NAMESPACE::hash<T> hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value); return hasher(x.value);
} }
#endif #endif
@@ -42,8 +42,8 @@ namespace test {
std::size_t hash_value(test_type2<T> const& x) std::size_t hash_value(test_type2<T> const& x)
{ {
std::size_t seed = 0; std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed; return seed;
} }
#endif #endif
@@ -60,8 +60,9 @@ namespace test {
template <class T> template <class T>
std::size_t hash_value(test_type3<T> const& x) std::size_t hash_value(test_type3<T> const& x)
{ {
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); std::size_t seed =
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed; return seed;
} }
#endif #endif
@@ -75,7 +76,7 @@ namespace boost
template <class T> template <class T>
std::size_t hash_value(test::test_type1<T> const& x) std::size_t hash_value(test::test_type1<T> const& x)
{ {
HASH_NAMESPACE::hash<T> hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value); return hasher(x.value);
} }
@@ -83,16 +84,17 @@ namespace boost
std::size_t hash_value(test::test_type2<T> const& x) std::size_t hash_value(test::test_type2<T> const& x)
{ {
std::size_t seed = 0; std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed; return seed;
} }
template <class T> template <class T>
std::size_t hash_value(test::test_type3<T> const& x) std::size_t hash_value(test::test_type3<T> const& x)
{ {
std::size_t seed = HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end()); std::size_t seed =
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed; return seed;
} }
} }
+24 -21
View File
@@ -5,13 +5,15 @@
// This checks that template code implemented using hash_fwd will work. // This checks that template code implemented using hash_fwd will work.
#include "./config.hpp"
#include "./hash_fwd_test.hpp" #include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) #if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/functional/hash.hpp> #include <boost/container_hash/hash.hpp>
#include <string> #include <string>
void fwd_test1() void fwd_test1()
@@ -19,10 +21,10 @@ void fwd_test1()
test::test_type1<int> x(5); test::test_type1<int> x(5);
test::test_type1<std::string> y("Test"); test::test_type1<std::string> y("Test");
HASH_NAMESPACE::hash<int> hasher_int; BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
HASH_NAMESPACE::hash<std::string> hasher_string; BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_TEST(hasher_int(5) == hasher_test_int(x)); BOOST_TEST(hasher_int(5) == hasher_test_int(x));
BOOST_TEST(hasher_string("Test") == hasher_test_string(y)); BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
@@ -34,15 +36,15 @@ void fwd_test2()
test::test_type2<std::string> y("Test1", "Test2"); test::test_type2<std::string> y("Test1", "Test2");
std::size_t seed1 = 0; std::size_t seed1 = 0;
HASH_NAMESPACE::hash_combine(seed1, 5); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
HASH_NAMESPACE::hash_combine(seed1, 10); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
std::size_t seed2 = 0; std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1")); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2")); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x)); BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y)); BOOST_TEST(seed2 == hasher_test_string(y));
@@ -66,14 +68,16 @@ void fwd_test3()
test::test_type3<int> x(values1.begin(), values1.end()); test::test_type3<int> x(values1.begin(), values1.end());
test::test_type3<std::string> y(values2.begin(), values2.end()); test::test_type3<std::string> y(values2.begin(), values2.end());
std::size_t seed1 = HASH_NAMESPACE::hash_range(values1.begin(), values1.end()); std::size_t seed1 =
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 = HASH_NAMESPACE::hash_range(values2.begin(), values2.end()); std::size_t seed2 =
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string; BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x)); BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y)); BOOST_TEST(seed2 == hasher_test_string(y));
@@ -83,11 +87,10 @@ void fwd_test3()
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
fwd_test1(); fwd_test1();
fwd_test2(); fwd_test2();
fwd_test3(); fwd_test3();
#endif #endif
return boost::report_errors(); return boost::report_errors();
} }
+5 -3
View File
@@ -6,14 +6,16 @@
// This test just makes sure a header which uses hash_fwd can compile without // This test just makes sure a header which uses hash_fwd can compile without
// the main hash headers. // the main hash headers.
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES) #include "./config.hpp"
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
int main() {} int main() {}
#else #else
#include "./hash_fwd_test.hpp" #include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
template <class T> void unused(T const&) {} template <class T> void unused(T const&) {}
@@ -42,4 +44,4 @@ int main()
return boost::report_errors(); return boost::report_errors();
} }
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES) #endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
+20 -18
View File
@@ -6,6 +6,8 @@
// This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed // This test demonstrates an ADL bug in Borland 5.5 where ADL isn't performed
// in the global namespace. // in the global namespace.
#include "./config.hpp"
#include <boost/config.hpp> #include <boost/config.hpp>
#include <cstddef> #include <cstddef>
@@ -15,7 +17,7 @@ struct custom
std::size_t hash() const std::size_t hash() const
{ {
return value_ * 10; return static_cast<std::size_t>(value_ * 10);
} }
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -40,17 +42,17 @@ namespace boost
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector> #include <vector>
#include <string> #include <string>
@@ -58,13 +60,13 @@ namespace boost
void custom_tests() void custom_tests()
{ {
HASH_NAMESPACE::hash<custom> custom_hasher; BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u); BOOST_TEST(custom_hasher(10) == 100u);
custom x(55); custom x(55);
BOOST_TEST(custom_hasher(x) == 550u); BOOST_TEST(custom_hasher(x) == 550u);
{ {
using namespace HASH_NAMESPACE; using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x)); BOOST_TEST(custom_hasher(x) == hash_value(x));
} }
@@ -74,26 +76,26 @@ void custom_tests()
custom_vector.push_back(35); custom_vector.push_back(35);
std::size_t seed = 0; std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, custom(5)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
HASH_NAMESPACE::hash_combine(seed, custom(25)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
HASH_NAMESPACE::hash_combine(seed, custom(35)); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
std::size_t seed2 = 0; std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u); BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
HASH_NAMESPACE::hash_range(custom_vector.begin(), custom_vector.end())); custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2); BOOST_TEST(seed == seed2);
} }
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests(); custom_tests();
#endif #endif
return boost::report_errors(); return boost::report_errors();
+102
View File
@@ -0,0 +1,102 @@
// Copyright 2017 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Not a test, just a small program to write out configuration info
#include <boost/container_hash/hash.hpp>
#include <iostream>
#include <algorithm>
#if defined(BOOST_MSVC)
struct msvc_version {
unsigned version;
char const* description;
friend bool operator<(msvc_version const& v1, msvc_version const& v2) {
return v1.version < v2.version;
}
};
void write_compiler_info() {
// From:
// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B
// https://blogs.msdn.microsoft.com/vcblog/2017/11/15/side-by-side-minor-version-msvc-toolsets-in-visual-studio-2017/
msvc_version versions[] = {
{0, "Old Visual C++"},
{1000, "Visual C++ 4.x, VS4.0?"},
{1100, "Visual C++ 5.0, VS97"},
{1200, "Visual C++ 6.0, VS6.0"},
{1300, "Visual C++ 7.0, VS.NET 2002"},
{1310, "Visual C++ 7.1, VS.NET 2003"},
{1400, "Visual C++ 8.0, VS2005"},
{1500, "Visual C++ 9.0, VS2008"},
{1600, "Visual C++ 10.0, VS2010"},
{1700, "Visual C++ 11.0, VS2012"},
{1800, "Visual C++ 12.0, VS2013"},
{1900, "Visual C++ 14.00, VS2015"},
{1910, "Visual C++ 14.10, VS2017 15.1/2"},
{1911, "Visual C++ 14.11, VS2017 15.3/4"},
{1912, "Visual C++ 14.12, VS2017 15.5"},
{1913, "Visual C++ 14.13, VS2017 15.6"}
};
msvc_version msvc = { BOOST_MSVC, "" };
msvc_version* v = std::upper_bound(versions,
versions + sizeof(versions) / sizeof(*versions),
msvc) - 1;
unsigned difference = msvc.version - v->version;
std::cout << v->description << std::endl;
if (difference) {
std::cout << "+" << difference << std::endl;
}
}
#else
void write_compiler_info() {
}
#endif
int main() {
write_compiler_info();
#if defined(__cplusplus)
std::cout << "__cplusplus: "
<< __cplusplus
<< std::endl;
#endif
std::cout << "BOOST_HASH_CXX17: "
<< BOOST_HASH_CXX17
<< std::endl;
std::cout << "BOOST_HASH_HAS_STRING_VIEW: "
<< BOOST_HASH_HAS_STRING_VIEW
<< std::endl;
std::cout << "BOOST_HASH_HAS_OPTIONAL: "
<< BOOST_HASH_HAS_OPTIONAL
<< std::endl;
std::cout << "BOOST_HASH_HAS_VARIANT: "
<< BOOST_HASH_HAS_VARIANT
<< std::endl;
#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::cout << "No <typeindex>" << std::endl;
#else
std::cout << "<typeindex>" << std::endl;
#endif
#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
std::cout << "No <system_error>" << std::endl;
#else
std::cout << "<system_error>" << std::endl;
#endif
}
+7 -7
View File
@@ -5,17 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <list> #include <list>
@@ -23,11 +23,11 @@ using std::list;
#define CONTAINER_TYPE list #define CONTAINER_TYPE list
#include "./hash_sequence_test.hpp" #include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
list_tests::list_hash_integer_tests(); list_tests::list_hash_integer_tests();
#endif #endif
+7 -7
View File
@@ -5,19 +5,19 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <map> #include <map>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
using std::map; using std::map;
#define CONTAINER_TYPE map #define CONTAINER_TYPE map
@@ -27,11 +27,11 @@ using std::multimap;
#define CONTAINER_TYPE multimap #define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp" #include "./hash_map_test.hpp"
#endif // TEST_EXTENSTIONS #endif // BOOST_HASH_TEST_EXTENSIONS
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
map_tests::map_hash_integer_tests(); map_tests::map_hash_integer_tests();
multimap_tests::multimap_hash_integer_tests(); multimap_tests::multimap_hash_integer_tests();
#endif #endif
+16 -15
View File
@@ -7,44 +7,45 @@
#error "CONTAINER_TYPE not defined" #error "CONTAINER_TYPE not defined"
#else #else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4244) // conversion from 'int' to 'float'
#pragma warning(disable:4245) // signed/unsigned mismatch #pragma warning(disable:4245) // signed/unsigned mismatch
#endif #endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
{ {
template <class T> template <class T>
void integer_tests(T* = 0) void integer_tests(T* = 0)
{ {
const int number_of_containers = 10; const int number_of_containers = 10;
T containers[number_of_containers]; T containers[number_of_containers];
typedef typename T::value_type pair; typedef BOOST_DEDUCED_TYPENAME T::value_type pair;
typedef BOOST_DEDUCED_TYPENAME T::key_type key;
typedef BOOST_DEDUCED_TYPENAME T::mapped_type value;
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
for(int j = 0; j < i; ++j) for(int j = 0; j < i; ++j)
containers[i].insert(pair(0, 0)); containers[i].insert(pair(key(0), value(0)));
} }
containers[6].insert(pair(1,0)); containers[6].insert(pair(key(1),value(0)));
containers[7].insert(pair(1,0)); containers[7].insert(pair(key(1),value(0)));
containers[7].insert(pair(1,0)); containers[7].insert(pair(key(1),value(0)));
containers[8].insert(pair(-1,1)); containers[8].insert(pair(key(-1),value(1)));
containers[9].insert(pair(-1,3)); containers[9].insert(pair(key(-1),value(3)));
containers[9].insert(pair(-1,3)); containers[9].insert(pair(key(-1),value(3)));
HASH_NAMESPACE::hash<T> hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2])); BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) == BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2])); BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2]) BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range( == BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end())); containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -56,7 +57,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
} }
} }
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests()) void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
{ {
integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0); integer_tests((CONTAINER_TYPE<char, unsigned char>*) 0);
integer_tests((CONTAINER_TYPE<int, float>*) 0); integer_tests((CONTAINER_TYPE<int, float>*) 0);
+14 -5
View File
@@ -3,17 +3,26 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost #include "./config.hpp"
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions // Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
// (or at least one of them). // (or at least one of them).
#define BOOST_HASH_NO_EXTENSIONS #if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
#endif
#include <boost/functional/hash.hpp> #ifdef BOOST_HASH_TEST_STD_INCLUDES
#include <boost/functional/hash.hpp> # include <functional>
#else
# include <boost/container_hash/hash.hpp>
#endif
template <class T> void ignore(T const&) {}
int main() int main()
{ {
HASH_NAMESPACE::hash< int[10] > hasher; BOOST_HASH_TEST_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
return 0; return 0;
} }
+15 -11
View File
@@ -3,31 +3,35 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost #include "./config.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header without BOOST_HASH_NO_EXTENSIONS defined // Include header without BOOST_HASH_NO_EXTENSIONS defined
#if defined(BOOST_HASH_NO_EXTENSIONS) # if defined(BOOST_HASH_NO_EXTENSIONS)
#undef BOOST_HASH_NO_EXTENSIONS # undef BOOST_HASH_NO_EXTENSIONS
#endif # endif
#include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
// Include header with BOOST_HASH_NO_EXTENSIONS defined // Include header with BOOST_HASH_NO_EXTENSIONS defined
#define BOOST_HASH_NO_EXTENSIONS # define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <deque> #include <deque>
#include <cassert>
int main() int main()
{ {
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::deque<int> x; std::deque<int> x;
x.push_back(1); x.push_back(1);
x.push_back(2); x.push_back(2);
HASH_NAMESPACE::hash<std::deque<int> > hasher; BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x)); BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors(); return boost::report_errors();
} }
+15 -10
View File
@@ -3,30 +3,35 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost #include "./config.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header with BOOST_HASH_NO_EXTENSIONS defined // Include header with BOOST_HASH_NO_EXTENSIONS defined
#if !defined(BOOST_HASH_NO_EXTENSIONS) # if !defined(BOOST_HASH_NO_EXTENSIONS)
#define BOOST_HASH_NO_EXTENSIONS # define BOOST_HASH_NO_EXTENSIONS
#endif # endif
#include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
// Include header without BOOST_HASH_NO_EXTENSIONS defined // Include header without BOOST_HASH_NO_EXTENSIONS defined
#undef BOOST_HASH_NO_EXTENSIONS # undef BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <map> #include <map>
int main() int main()
{ {
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::map<int, int> x; std::map<int, int> x;
x.insert(std::map<int, int>::value_type(53, -42)); x.insert(std::map<int, int>::value_type(53, -42));
x.insert(std::map<int, int>::value_type(14, -75)); x.insert(std::map<int, int>::value_type(14, -75));
HASH_NAMESPACE::hash<std::map<int, int> > hasher; BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x)); BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors(); return boost::report_errors();
} }
+71 -38
View File
@@ -5,19 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <iostream> #include <iostream>
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/container_hash/detail/limits.hpp>
#include <boost/functional/hash/detail/limits.hpp> #include <boost/core/enable_if.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp" #include "./compile_time.hpp"
@@ -28,15 +26,41 @@
#pragma warning(disable:4310) // cast truncates constant value #pragma warning(disable:4310) // cast truncates constant value
#endif #endif
#if defined(__GNUC__) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T> template <class T>
void numeric_test(T*) void numeric_extra_tests(typename
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{ {
typedef boost::hash_detail::limits<T> limits; typedef boost::hash_detail::limits<T> limits;
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
template <class T>
void numeric_extra_tests(typename
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
}
template <class T>
void numeric_test(T*)
{
compile_time_tests((T*) 0); compile_time_tests((T*) 0);
HASH_NAMESPACE::hash<T> x1; BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2; BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T v1 = (T) -5; T v1 = (T) -5;
BOOST_TEST(x1(v1) == x2(v1)); BOOST_TEST(x1(v1) == x2(v1));
@@ -47,20 +71,13 @@ void numeric_test(T*)
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0))); BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10))); BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5))); BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0))); BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10))); BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25))); BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
if (limits::is_integer) numeric_extra_tests<T>();
{
if(limits::is_signed || limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
#endif #endif
} }
@@ -71,8 +88,8 @@ void limits_test(T*)
if(limits::is_specialized) if(limits::is_specialized)
{ {
HASH_NAMESPACE::hash<T> x1; BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2; BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T min_value = (limits::min)(); T min_value = (limits::min)();
T max_value = (limits::max)(); T max_value = (limits::max)();
@@ -80,15 +97,15 @@ void limits_test(T*)
BOOST_TEST(x1(min_value) == x2((limits::min)())); BOOST_TEST(x1(min_value) == x2((limits::min)()));
BOOST_TEST(x1(max_value) == x2((limits::max)())); BOOST_TEST(x1(max_value) == x2((limits::max)()));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value)); BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value)); BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
if (limits::is_integer) if (limits::is_integer)
{ {
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value)
== std::size_t(min_value)); == std::size_t(min_value));
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value)
== std::size_t(max_value)); == std::size_t(max_value));
} }
#endif #endif
@@ -100,8 +117,8 @@ void poor_quality_tests(T*)
{ {
typedef boost::hash_detail::limits<T> limits; typedef boost::hash_detail::limits<T> limits;
HASH_NAMESPACE::hash<T> x1; BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2; BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
// A hash function can legally fail these tests, but it'll not be a good // A hash function can legally fail these tests, but it'll not be a good
// sign. // sign.
@@ -109,15 +126,20 @@ void poor_quality_tests(T*)
BOOST_TEST(x1(T(1)) != x2(T(-1))); BOOST_TEST(x1(T(1)) != x2(T(-1)));
if(T(1) != T(2)) if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2))); BOOST_TEST(x1(T(1)) != x2(T(2)));
if((limits::max)() != (limits::max)() - 1)
BOOST_TEST(x1((limits::max)()) != x2((limits::max)() - 1)); // TODO: This test is useless for floating point numbers.
T max_number = static_cast<T>((limits::max)());
T max_minus_one = static_cast<T>(max_number - 1);
if (max_number != max_minus_one) {
BOOST_TEST(x1(max_number) != x1(max_minus_one));
}
} }
void bool_test() void bool_test()
{ {
HASH_NAMESPACE::hash<bool> x1; BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
HASH_NAMESPACE::hash<bool> x2; BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
BOOST_TEST(x1(true) == x2(true)); BOOST_TEST(x1(true) == x2(true));
BOOST_TEST(x1(false) == x2(false)); BOOST_TEST(x1(false) == x2(false));
BOOST_TEST(x1(true) != x2(false)); BOOST_TEST(x1(true) != x2(false));
@@ -141,6 +163,12 @@ int main()
NUMERIC_TEST(unsigned char, uchar) NUMERIC_TEST(unsigned char, uchar)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T #ifndef BOOST_NO_INTRINSIC_WCHAR_T
NUMERIC_TEST(wchar_t, wchar) NUMERIC_TEST(wchar_t, wchar)
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
NUMERIC_TEST(char16_t, char16)
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
NUMERIC_TEST(char32_t, char32)
#endif #endif
NUMERIC_TEST(short, short) NUMERIC_TEST(short, short)
NUMERIC_TEST(unsigned short, ushort) NUMERIC_TEST(unsigned short, ushort)
@@ -149,11 +177,16 @@ int main()
NUMERIC_TEST(long, hash_long) NUMERIC_TEST(long, hash_long)
NUMERIC_TEST(unsigned long, ulong) NUMERIC_TEST(unsigned long, ulong)
#if defined(BOOST_HAS_LONG_LONG) #if !defined(BOOST_NO_LONG_LONG)
NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long) NUMERIC_TEST_NO_LIMITS(boost::long_long_type, long_long)
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long) NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
#endif #endif
#if defined(BOOST_HAS_INT128)
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
#endif
NUMERIC_TEST(float, float) NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double) NUMERIC_TEST(double, double)
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2018 Daniel James
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifndef BOOST_HASH_TEST_STD_INCLUDES
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if BOOST_HASH_HAS_OPTIONAL
#include <optional>
#include <string>
void test_optional_int()
{
std::optional<int> x1a;
std::optional<int> x1b;
std::optional<int> x2a(10);
std::optional<int> x2b(x2a);
std::optional<int> x3(20);
boost::hash<std::optional<int> > hasher;
BOOST_TEST(hasher(x1a) == hasher(x1a));
BOOST_TEST(hasher(x1a) == hasher(x1b));
BOOST_TEST(hasher(x1a) != hasher(x2a));
BOOST_TEST(hasher(x1a) != hasher(x3));
BOOST_TEST(hasher(x2a) == hasher(x2a));
BOOST_TEST(hasher(x2b) == hasher(x2b));
BOOST_TEST(hasher(x2a) != hasher(x3));
BOOST_TEST(hasher(x3) == hasher(x3));
}
void test_optional_string()
{
std::optional<std::string> x1a;
std::optional<std::string> x1b;
std::optional<std::string> x2a("10");
std::optional<std::string> x2b(x2a);
std::optional<std::string> x3("20");
boost::hash<std::optional<std::string> > hasher;
BOOST_TEST(hasher(x1a) == hasher(x1a));
BOOST_TEST(hasher(x1a) == hasher(x1b));
BOOST_TEST(hasher(x1a) != hasher(x2a));
BOOST_TEST(hasher(x1a) != hasher(x3));
BOOST_TEST(hasher(x2a) == hasher(x2a));
BOOST_TEST(hasher(x2b) == hasher(x2b));
BOOST_TEST(hasher(x2a) != hasher(x3));
BOOST_TEST(hasher(x3) == hasher(x3));
}
#endif
int main()
{
#if BOOST_HASH_HAS_OPTIONAL
test_optional_int();
test_optional_string();
#else
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<optional> not available." << std::endl;
#endif
return boost::report_errors();
}
+8 -12
View File
@@ -5,18 +5,14 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp" #include "./compile_time.hpp"
void pointer_tests() void pointer_tests()
@@ -24,8 +20,8 @@ void pointer_tests()
compile_time_tests((int**) 0); compile_time_tests((int**) 0);
compile_time_tests((void**) 0); compile_time_tests((void**) 0);
HASH_NAMESPACE::hash<int*> x1; BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
HASH_NAMESPACE::hash<int*> x2; BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
int int1; int int1;
int int2; int int2;
@@ -33,9 +29,9 @@ void pointer_tests()
BOOST_TEST(x1(0) == x2(0)); BOOST_TEST(x1(0) == x2(0));
BOOST_TEST(x1(&int1) == x2(&int1)); BOOST_TEST(x1(&int1) == x2(&int1));
BOOST_TEST(x1(&int2) == x2(&int2)); BOOST_TEST(x1(&int2) == x2(&int2));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1)); BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2)); BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal: // This isn't specified in Peter's proposal:
BOOST_TEST(x1(0) == 0); BOOST_TEST(x1(0) == 0);
+29 -30
View File
@@ -5,23 +5,20 @@
#include "./config.hpp" #include "./config.hpp"
#if !defined(TEST_EXTENSIONS) #if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {} int main() {}
#else #else
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector> #include <vector>
void hash_range_tests() void hash_range_tests()
@@ -43,37 +40,39 @@ void hash_range_tests()
std::vector<int> x; std::vector<int> x;
std::size_t x_seed = 0; std::size_t x_seed = 0;
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end())); == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end())); != BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10); x.push_back(10);
HASH_NAMESPACE::hash_combine(x_seed, 10); BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end())); != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end())); == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
x.push_back(20); x.push_back(20);
HASH_NAMESPACE::hash_combine(x_seed, 20); BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end())); BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end())); != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end())); != BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end()) BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end())); == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
std::size_t seed = HASH_NAMESPACE::hash_range(values3.begin(), values3.end()); std::size_t seed =
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end()); BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(values5.begin(), values5.end())); BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed ==
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
} }
int main() int main()
+17 -17
View File
@@ -7,18 +7,18 @@
#error "CONTAINER_TYPE not defined" #error "CONTAINER_TYPE not defined"
#else #else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch #pragma warning(disable:4245) // signed/unsigned mismatch
#endif #endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
{ {
template <class T> template <class T>
void integer_tests(T* = 0) void integer_tests(T* = 0)
{ {
typedef typename T::value_type value_type;
const int number_of_containers = 11; const int number_of_containers = 11;
T containers[number_of_containers]; T containers[number_of_containers];
@@ -27,27 +27,27 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[i].push_back(0); containers[i].push_back(0);
} }
containers[5].push_back(1); containers[5].push_back(value_type(1));
containers[6].push_back(1); containers[6].push_back(value_type(1));
containers[6].push_back(1); containers[6].push_back(value_type(1));
containers[7].push_back(-1); containers[7].push_back(value_type(-1));
containers[8].push_back(-1); containers[8].push_back(value_type(-1));
containers[8].push_back(-1); containers[8].push_back(value_type(-1));
containers[9].push_back(1); containers[9].push_back(value_type(1));
containers[9].push_back(-1); containers[9].push_back(value_type(-1));
containers[10].push_back(-1); containers[10].push_back(value_type(-1));
containers[10].push_back(1); containers[10].push_back(value_type(1));
HASH_NAMESPACE::hash<T> hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2])); BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) == BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2])); BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2]) BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range( == BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end())); containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -59,7 +59,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
} }
} }
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests()) void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
{ {
integer_tests((CONTAINER_TYPE<char>*) 0); integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0); integer_tests((CONTAINER_TYPE<int>*) 0);
+6 -6
View File
@@ -5,17 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <set> #include <set>
@@ -31,7 +31,7 @@ using std::multiset;
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
set_tests::set_hash_integer_tests(); set_tests::set_hash_integer_tests();
multiset_tests::multiset_hash_integer_tests(); multiset_tests::multiset_hash_integer_tests();
#endif #endif
+20 -20
View File
@@ -7,18 +7,18 @@
#error "CONTAINER_TYPE not defined" #error "CONTAINER_TYPE not defined"
#else #else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4245) // signed/unsigned mismatch #pragma warning(disable:4245) // signed/unsigned mismatch
#endif #endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests) namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
{ {
template <class T> template <class T>
void integer_tests(T* = 0) void integer_tests(T* = 0)
{ {
typedef typename T::value_type value_type;
const int number_of_containers = 12; const int number_of_containers = 12;
T containers[number_of_containers]; T containers[number_of_containers];
@@ -27,30 +27,30 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[i].insert(0); containers[i].insert(0);
} }
containers[6].insert(1); containers[6].insert(value_type(1));
containers[7].insert(1); containers[7].insert(value_type(1));
containers[7].insert(1); containers[7].insert(value_type(1));
containers[8].insert(-1); containers[8].insert(value_type(-1));
containers[9].insert(-1); containers[9].insert(value_type(-1));
containers[9].insert(-1); containers[9].insert(value_type(-1));
containers[10].insert(-1); containers[10].insert(value_type(-1));
containers[10].insert(1); containers[10].insert(value_type(1));
containers[11].insert(1); containers[11].insert(value_type(1));
containers[11].insert(2); containers[11].insert(value_type(2));
containers[11].insert(3); containers[11].insert(value_type(3));
containers[11].insert(4); containers[11].insert(value_type(4));
containers[11].insert(5); containers[11].insert(value_type(5));
HASH_NAMESPACE::hash<T> hasher; BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) { for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2])); BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) == BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2])); BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2]) BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range( == BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end())); containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) { for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -62,7 +62,7 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
} }
} }
void BOOST_PP_CAT(CONTAINER_TYPE, _hash_integer_tests()) void HASH_TEST_CAT(CONTAINER_TYPE, _hash_integer_tests())
{ {
integer_tests((CONTAINER_TYPE<char>*) 0); integer_tests((CONTAINER_TYPE<char>*) 0);
integer_tests((CONTAINER_TYPE<int>*) 0); integer_tests((CONTAINER_TYPE<int>*) 0);
+103
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/container_hash/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_ARRAY)
#define TEST_ARRAY
#include <array>
#include <vector>
#endif
#ifdef TEST_ARRAY
template <typename T>
void array_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_array_test() {
/*
boost::hash<std::array<int, 0> > empty_array_hash;
std::array<int, 0> empty_array;
BOOST_TEST(empty_array_hash(empty_array) == boost::hash_value(empty_array));
*/
}
void int_1_array_test()
{
std::vector<std::array<int, 1> > arrays;
std::array<int, 1> val;
val[0] = 0;
arrays.push_back(val);
val[0] = 1;
arrays.push_back(val);
val[0] = 2;
arrays.push_back(val);
array_tests(arrays);
}
void string_1_array_test()
{
std::vector<std::array<std::string, 1> > arrays;
std::array<std::string, 1> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = "two";
arrays.push_back(val);
array_tests(arrays);
}
void string_3_array_test()
{
std::vector<std::array<std::string,3 > > arrays;
std::array<std::string, 3> val;
arrays.push_back(val);
val[0] = "one";
arrays.push_back(val);
val[0] = ""; val[1] = "one"; val[2] = "";
arrays.push_back(val);
val[0] = ""; val[1] = ""; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "one"; val[2] = "one";
arrays.push_back(val);
val[0] = "one"; val[1] = "two"; val[2] = "three";
arrays.push_back(val);
array_tests(arrays);
}
#endif // TEST_ARRAY
int main()
{
#ifdef TEST_ARRAY
empty_array_test();
int_1_array_test();
string_1_array_test();
string_3_array_test();
#endif
return boost::report_errors();
}
+80
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/container_hash/hash.hpp>
#endif
#include <boost/core/lightweight_test.hpp>
#include "./compile_time.hpp"
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_SMART_PTR)
#define TEST_SMART_PTRS
#include <memory>
#endif
#ifdef TEST_SMART_PTRS
void shared_ptr_tests()
{
std::shared_ptr<int> x;
compile_time_tests(&x);
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::shared_ptr<int> > x2;
std::shared_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
ptr2 = ptr1;
BOOST_TEST(x1(ptr1) == x2(ptr2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
BOOST_TEST(x1(ptr1) == BOOST_HASH_TEST_NAMESPACE::hash_value(ptr2));
#endif
}
void unique_ptr_tests()
{
std::unique_ptr<int> x;
compile_time_tests(&x);
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::unique_ptr<int> > x2;
std::unique_ptr<int> ptr1(new int(10));
std::unique_ptr<int> ptr2;
BOOST_TEST(x1(x) == x2(ptr2));
BOOST_TEST(x1(x) != x2(ptr1));
ptr2.reset(new int(10));
BOOST_TEST(x1(ptr1) == x2(ptr1));
BOOST_TEST(x1(ptr1) != x2(ptr2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
}
#endif
int main()
{
#ifdef TEST_SMART_PTRS
shared_ptr_tests();
unique_ptr_tests();
#endif
return boost::report_errors();
}
+77
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/container_hash/hash.hpp>
# endif
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_NO_CXX11_HDR_TUPLE)
#define TEST_TUPLE
#include <tuple>
#include <vector>
#endif
#ifdef TEST_TUPLE
template <typename T>
void tuple_tests(T const& v) {
boost::hash<typename T::value_type> hf;
for(typename T::const_iterator i = v.begin(); i != v.end(); ++i) {
for(typename T::const_iterator j = v.begin(); j != v.end(); ++j) {
if (i != j)
BOOST_TEST(hf(*i) != hf(*j));
else
BOOST_TEST(hf(*i) == hf(*j));
}
}
}
void empty_tuple_test() {
boost::hash<std::tuple<> > empty_tuple_hash;
std::tuple<> empty_tuple;
BOOST_TEST(empty_tuple_hash(empty_tuple) == boost::hash_value(empty_tuple));
}
void int_tuple_test() {
std::vector<std::tuple<int> > int_tuples;
int_tuples.push_back(std::make_tuple(0));
int_tuples.push_back(std::make_tuple(1));
int_tuples.push_back(std::make_tuple(2));
tuple_tests(int_tuples);
}
void int_string_tuple_test() {
std::vector<std::tuple<int, std::string> > int_string_tuples;
int_string_tuples.push_back(std::make_tuple(0, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(1, std::string("one")));
int_string_tuples.push_back(std::make_tuple(2, std::string("two")));
int_string_tuples.push_back(std::make_tuple(0, std::string("one")));
int_string_tuples.push_back(std::make_tuple(1, std::string("zero")));
int_string_tuples.push_back(std::make_tuple(0, std::string("")));
int_string_tuples.push_back(std::make_tuple(1, std::string("")));
tuple_tests(int_string_tuples);
}
#endif // TEST_TUPLE
int main()
{
#ifdef TEST_TUPLE
empty_tuple_test();
int_tuple_test();
int_string_tuple_test();
#endif
return boost::report_errors();
}
+134 -27
View File
@@ -5,73 +5,180 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_STD_INCLUDES #ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
#else #else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <string> #include <string>
#include "./compile_time.hpp" #include "./compile_time.hpp"
void string_tests() void string_tests()
{ {
compile_time_tests((std::string*) 0); compile_time_tests((std::string*) 0);
HASH_NAMESPACE::hash<std::string> x1; BOOST_HASH_TEST_NAMESPACE::hash<std::string> x1;
HASH_NAMESPACE::hash<std::string> x2; BOOST_HASH_TEST_NAMESPACE::hash<std::string> x2;
BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo")); BOOST_TEST(x1("Hello") == x2(std::string("Hel") + "lo"));
BOOST_TEST(x1("") == x2(std::string())); BOOST_TEST(x1("") == x2(std::string()));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
std::string value1; std::string value1;
std::string value2("Hello"); std::string value2("Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1)); BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2)); BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) == BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end())); BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) == BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end())); BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif #endif
} }
#if !defined(BOOST_NO_STD_WSTRING) void string0_tests()
{
std::string x1(1, '\0');
std::string x2(2, '\0');
std::string x3(3, '\0');
std::string x4(10, '\0');
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher;
BOOST_TEST(hasher(x1) != hasher(x2));
BOOST_TEST(hasher(x1) != hasher(x3));
BOOST_TEST(hasher(x1) != hasher(x4));
BOOST_TEST(hasher(x2) != hasher(x3));
BOOST_TEST(hasher(x2) != hasher(x4));
BOOST_TEST(hasher(x3) != hasher(x4));
}
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
void wstring_tests() void wstring_tests()
{ {
compile_time_tests((std::wstring*) 0); compile_time_tests((std::wstring*) 0);
HASH_NAMESPACE::hash<std::wstring> x1; BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x1;
HASH_NAMESPACE::hash<std::wstring> x2; BOOST_HASH_TEST_NAMESPACE::hash<std::wstring> x2;
BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo")); BOOST_TEST(x1(L"Hello") == x2(std::wstring(L"Hel") + L"lo"));
BOOST_TEST(x1(L"") == x2(std::wstring())); BOOST_TEST(x1(L"") == x2(std::wstring()));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
std::wstring value1; std::wstring value1;
std::wstring value2(L"Hello"); std::wstring value2(L"Hello");
BOOST_TEST(x1(value1) == HASH_NAMESPACE::hash_value(value1)); BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == HASH_NAMESPACE::hash_value(value2)); BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(HASH_NAMESPACE::hash_value(value1) == BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
HASH_NAMESPACE::hash_range(value1.begin(), value1.end())); BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(HASH_NAMESPACE::hash_value(value2) == BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
HASH_NAMESPACE::hash_range(value2.begin(), value2.end())); BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif #endif
} }
#endif #endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
void u16string_tests()
{
compile_time_tests((std::u16string*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<std::u16string> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::u16string> x2;
BOOST_TEST(x1(u"Hello") == x2(std::u16string(u"Hel") + u"lo"));
BOOST_TEST(x1(u"") == x2(std::u16string()));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::u16string value1;
std::u16string value2(u"Hello");
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
void u32string_tests()
{
compile_time_tests((std::u32string*) 0);
BOOST_HASH_TEST_NAMESPACE::hash<std::u32string> x1;
BOOST_HASH_TEST_NAMESPACE::hash<std::u32string> x2;
BOOST_TEST(x1(U"Hello") == x2(std::u32string(U"Hel") + U"lo"));
BOOST_TEST(x1(U"") == x2(std::u32string()));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::u32string value1;
std::u32string value2(U"Hello");
BOOST_TEST(x1(value1) == BOOST_HASH_TEST_NAMESPACE::hash_value(value1));
BOOST_TEST(x1(value2) == BOOST_HASH_TEST_NAMESPACE::hash_value(value2));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value1) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value1.begin(), value1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(value2) ==
BOOST_HASH_TEST_NAMESPACE::hash_range(value2.begin(), value2.end()));
#endif
}
#endif
template <typename StringType>
void generic_string_tests(StringType*)
{
std::string x1(1, '\0');
std::string x2(2, '\0');
std::string x3(3, '\0');
std::string x4(10, '\0');
std::string x5 = x2 + "hello" + x2;
StringType strings[] = {
"",
"hello",
x1,
x2,
x3,
x4,
x5
};
std::size_t const strings_length = sizeof(strings) / sizeof(StringType);
boost::hash<StringType> hash;
for (std::size_t i = 0; i < strings_length; ++i) {
std::size_t hash_i = hash(strings[i]);
for (std::size_t j = 0; j < strings_length; ++j) {
std::size_t hash_j = hash(strings[j]);
BOOST_TEST((hash_i == hash_j) == (i == j));
}
}
}
int main() int main()
{ {
string_tests(); string_tests();
#if !defined(BOOST_NO_STD_WSTRING) string0_tests();
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
wstring_tests(); wstring_tests();
#endif #endif
#if !defined(BOOST_NO_CXX11_CHAR16_T)
u16string_tests();
#endif
#if !defined(BOOST_NO_CXX11_CHAR32_T)
u32string_tests();
#endif
generic_string_tests((std::string*) 0);
#if BOOST_HASH_HAS_STRING_VIEW
generic_string_tests((std::string_view*) 0);
#endif
return boost::report_errors(); return boost::report_errors();
} }
+55
View File
@@ -0,0 +1,55 @@
// Copyright 2018 Daniel James
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifndef BOOST_HASH_TEST_STD_INCLUDES
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
#include <system_error>
void test_error_code()
{
std::error_code err1a = std::make_error_code(std::errc::argument_list_too_long);
std::error_code err1b = std::make_error_code(std::errc::argument_list_too_long);
std::error_code err2 = std::make_error_code(std::errc::bad_file_descriptor);
boost::hash<std::error_code> hasher;
BOOST_TEST(hasher(err1a) == hasher(err1a));
BOOST_TEST(hasher(err1a) == hasher(err1b));
BOOST_TEST(hasher(err1a) != hasher(err2));
}
void test_error_condition()
{
std::error_condition err1a = std::make_error_condition(std::errc::directory_not_empty);
std::error_condition err1b = std::make_error_condition(std::errc::directory_not_empty);
std::error_condition err2 = std::make_error_condition(std::errc::filename_too_long);
boost::hash<std::error_condition> hasher;
BOOST_TEST(hasher(err1a) == hasher(err1a));
BOOST_TEST(hasher(err1a) == hasher(err1b));
BOOST_TEST(hasher(err1a) != hasher(err2));
}
#endif
int main()
{
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
test_error_code();
test_error_condition();
#else
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<system_error> not available." << std::endl;
#endif
return boost::report_errors();
}
+53
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/container_hash/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
#include <typeindex>
void test_type_index() {
BOOST_HASH_TEST_NAMESPACE::hash<std::type_index> hasher;
#if defined(BOOST_NO_TYPEID)
std::cout<<"Unable to test std::type_index, as typeid isn't available"
<<std::endl;
#else
std::type_index int_index = typeid(int);
std::type_index int2_index = typeid(int);
std::type_index char_index = typeid(char);
BOOST_TEST(hasher(int_index) == int_index.hash_code());
BOOST_TEST(hasher(int_index) == int2_index.hash_code());
BOOST_TEST(hasher(char_index) == char_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(int_index) == int2_index.hash_code());
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(char_index) == char_index.hash_code());
BOOST_TEST(hasher(int_index) == hasher(int2_index));
BOOST_TEST(hasher(int_index) != hasher(char_index));
#endif
}
#endif
int main()
{
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
test_type_index();
#else
std::cout<<"<type_index> not available."<<std::endl;
#endif
return boost::report_errors();
}
+14 -14
View File
@@ -8,17 +8,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
void array_int_test() void array_int_test()
{ {
@@ -29,32 +29,32 @@ void array_int_test()
8, -12, 23, 65, 45, 8, -12, 23, 65, 45,
-1, 93, -54, 987, 3 -1, 93, -54, 987, 3
}; };
HASH_NAMESPACE::hash<int[25]> hasher1; BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
int array2[1] = {3}; int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2; BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
int array3[2] = {2, 3}; int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3; BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1) == HASH_NAMESPACE::hash_value(array1)); BOOST_TEST(hasher1(array1) == BOOST_HASH_TEST_NAMESPACE::hash_value(array1));
BOOST_TEST(hasher2(array2) == HASH_NAMESPACE::hash_value(array2)); BOOST_TEST(hasher2(array2) == BOOST_HASH_TEST_NAMESPACE::hash_value(array2));
BOOST_TEST(hasher3(array3) == HASH_NAMESPACE::hash_value(array3)); BOOST_TEST(hasher3(array3) == BOOST_HASH_TEST_NAMESPACE::hash_value(array3));
} }
void two_dimensional_array_test() void two_dimensional_array_test()
{ {
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}}; int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher; BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_value(array)); BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_value(array));
} }
#endif #endif
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
array_int_test(); array_int_test();
two_dimensional_array_test(); two_dimensional_array_test();
#endif #endif
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2018 Daniel James
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#ifndef BOOST_HASH_TEST_STD_INCLUDES
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/config.hpp>
#include <boost/core/lightweight_test.hpp>
#if BOOST_HASH_HAS_VARIANT
#include <variant>
#include <string>
void test_monostate()
{
std::monostate x1;
std::monostate x2;
boost::hash<std::monostate> hasher;
BOOST_TEST(hasher(x1) == hasher(x2));
}
void test_variant_int()
{
std::variant<std::monostate, int> x1a;
std::variant<std::monostate, int> x1b;
std::variant<std::monostate, int> x2a(10);
std::variant<std::monostate, int> x2b(x2a);
std::variant<std::monostate, int> x3(20);
boost::hash<std::variant<std::monostate, int> > hasher;
BOOST_TEST(hasher(x1a) == hasher(x1a));
BOOST_TEST(hasher(x1a) == hasher(x1b));
BOOST_TEST(hasher(x1a) != hasher(x2a));
BOOST_TEST(hasher(x1a) != hasher(x3));
BOOST_TEST(hasher(x2a) == hasher(x2a));
BOOST_TEST(hasher(x2b) == hasher(x2b));
BOOST_TEST(hasher(x2a) != hasher(x3));
BOOST_TEST(hasher(x3) == hasher(x3));
}
struct custom1 {
int value;
friend std::size_t hash_value(custom1 v) { return boost::hash_value(v.value); }
};
struct custom2 {
int value;
friend std::size_t hash_value(custom2 v) { return boost::hash_value(v.value); }
};
void test_variant_unique_types()
{
custom1 x11 = { 0 };
custom1 x12 = { 1 };
custom2 x21 = { 0 };
custom2 x22 = { 1 };
boost::hash<custom1> hasher1;
boost::hash<custom2> hasher2;
BOOST_TEST(hasher1(x11) == hasher2(x21));
BOOST_TEST(hasher1(x11) != hasher2(x22));
BOOST_TEST(hasher1(x12) != hasher2(x21));
BOOST_TEST(hasher1(x12) == hasher2(x22));
typedef std::variant<custom1, custom2> variant_type;
variant_type y11(x11);
variant_type y12(x12);
variant_type y21(x21);
variant_type y22(x22);
boost::hash<variant_type> hasher;
BOOST_TEST(hasher(y11) != hasher(y21));
BOOST_TEST(hasher(y11) != hasher(y22));
BOOST_TEST(hasher(y12) != hasher(y21));
BOOST_TEST(hasher(y12) != hasher(y22));
}
#endif
int main()
{
#if BOOST_HASH_HAS_VARIANT
test_variant_int();
test_variant_unique_types();
#else
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "<variant> not available." << std::endl;
#endif
return boost::report_errors();
}
+40 -7
View File
@@ -5,17 +5,17 @@
#include "./config.hpp" #include "./config.hpp"
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES # ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional> # include <functional>
# else # else
# include <boost/functional/hash.hpp> # include <boost/container_hash/hash.hpp>
# endif # endif
#endif #endif
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
#include <vector> #include <vector>
@@ -23,13 +23,46 @@ using std::vector;
#define CONTAINER_TYPE vector #define CONTAINER_TYPE vector
#include "./hash_sequence_test.hpp" #include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS #endif // BOOST_HASH_TEST_EXTENSIONS
namespace vector_bool_tests
{
void vector_bool_test() {
std::vector<bool> x_empty1,x_empty2,x1,x1a,x2,x3;
x1.push_back(0);
x1a.push_back(0);
x2.push_back(1);
x3.push_back(0);
x3.push_back(0);
BOOST_HASH_TEST_NAMESPACE::hash<std::vector<bool> > hasher;
BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty1));
BOOST_TEST_EQ(hasher(x_empty1), hasher(x_empty2));
BOOST_TEST_NE(hasher(x_empty1), hasher(x1));
BOOST_TEST_NE(hasher(x_empty1), hasher(x2));
BOOST_TEST_NE(hasher(x_empty1), hasher(x3));
BOOST_TEST_EQ(hasher(x1), hasher(x1));
BOOST_TEST_EQ(hasher(x1), hasher(x1a));
BOOST_TEST_NE(hasher(x1), hasher(x2));
BOOST_TEST_NE(hasher(x1), hasher(x3));
BOOST_TEST_EQ(hasher(x2), hasher(x2));
BOOST_TEST_NE(hasher(x2), hasher(x3));
BOOST_TEST_EQ(hasher(x3), hasher(x3));
}
}
int main() int main()
{ {
#ifdef TEST_EXTENSIONS #ifdef BOOST_HASH_TEST_EXTENSIONS
vector_tests::vector_hash_integer_tests(); vector_tests::vector_hash_integer_tests();
#endif #endif
vector_bool_tests::vector_bool_test();
return boost::report_errors(); return boost::report_errors();
} }
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2010 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/container_hash/hash.hpp>
namespace test
{
struct base {};
std::size_t hash_value(base const&) { return 0; }
struct converts { operator base() const { return base(); } };
}
int main() {
boost::hash<test::converts> hash;
test::converts x;
hash(x);
}
+11 -9
View File
@@ -3,24 +3,26 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost #include "./config.hpp"
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp> #define BOOST_HASH_TEST_NAMESPACE boost
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <vector> #include <vector>
int f(std::size_t hash1, int* x1) { int f(std::size_t hash1, int* x1) {
// Check that HASH_NAMESPACE::hash<int*> works in both files. // Check that BOOST_HASH_TEST_NAMESPACE::hash<int*> works in both files.
HASH_NAMESPACE::hash<int*> ptr_hasher; BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
BOOST_TEST(hash1 == ptr_hasher(x1)); BOOST_TEST(hash1 == ptr_hasher(x1));
#if defined(TEST_EXTENSIONS) #if defined(BOOST_HASH_TEST_EXTENSIONS)
// Check that std::vector<std::size_t> is avaiable in this file. // Check that std::vector<std::size_t> is avaiable in this file.
std::vector<std::size_t> x; std::vector<std::size_t> x;
x.push_back(*x1); x.push_back(static_cast<std::size_t>(*x1));
HASH_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher; BOOST_HASH_TEST_NAMESPACE::hash<std::vector<std::size_t> > vector_hasher;
return vector_hasher(x) != HASH_NAMESPACE::hash_value(x); return vector_hasher(x) != BOOST_HASH_TEST_NAMESPACE::hash_value(x);
#else #else
+6 -4
View File
@@ -3,15 +3,17 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define HASH_NAMESPACE boost #include "./config.hpp"
#define BOOST_HASH_TEST_NAMESPACE boost
#define BOOST_HASH_NO_EXTENSIONS #define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp> #include <boost/container_hash/hash.hpp>
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
extern int f(std::size_t, int*); extern int f(std::size_t, int*);
int main() { int main() {
HASH_NAMESPACE::hash<int*> ptr_hasher; BOOST_HASH_TEST_NAMESPACE::hash<int*> ptr_hasher;
int x = 55; int x = 55;
BOOST_TEST(!f(ptr_hasher(&x), &x)); BOOST_TEST(!f(ptr_hasher(&x), &x));
return boost::report_errors(); return boost::report_errors();
+3 -1
View File
@@ -3,7 +3,9 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp> #include "./config.hpp"
#include <boost/container_hash/hash.hpp>
extern int f(); extern int f();
int main() { return f(); } int main() { return f(); }
+3 -1
View File
@@ -3,6 +3,8 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash.hpp> #include "./config.hpp"
#include <boost/container_hash/hash.hpp>
int f() { return 0; } int f() { return 0; }
+4 -2
View File
@@ -6,9 +6,11 @@
// Check that I haven't inadvertantly pulled namespace std into the global // Check that I haven't inadvertantly pulled namespace std into the global
// namespace. // namespace.
#include "./config.hpp"
#include <list> #include <list>
#include <boost/functional/hash.hpp> #include <boost/container_hash/hash.hpp>
typedef list<int> foo; typedef list<int> foo;
int main() {} int main() {}