Compare commits

...

396 Commits

Author SHA1 Message Date
Peter Dimov f722383d1d Change macos-10.15 to macos-11 in ci.yml 2022-08-31 18:17:01 +03:00
Peter Dimov 21530840e1 Add hash_string_test4.cpp 2022-08-31 15:09:29 +03:00
Peter Dimov d0c1e36fc1 Add hash_string_test3.cpp 2022-08-31 14:51:47 +03:00
Peter Dimov e00f53a69c Remove msvc-14.2 from appveyor.yml 2022-07-16 14:10:28 +03:00
Peter Dimov b0c9904414 Test _MSVC_STL_VERSION instead of BOOST_MSVC because clang-cl 2022-07-16 13:37:15 +03:00
Peter Dimov 2d557a746d Add hash_vector_test2.cpp 2022-07-16 11:16:06 +03:00
Peter Dimov 417180dd03 Update appveyor.yml 2022-07-14 20:16:19 +03:00
Peter Dimov 5ba74cd3a9 Update hash_value for pointers to handle the case when uintptr_t is larger than size_t 2022-07-03 23:35:46 +03:00
Peter Dimov c14d3a1e2b Add a comment explaining why to_underlying isn't used in hash_value for enums 2022-07-03 21:08:14 +03:00
Peter Dimov a3cac265b1 Disable examples/template.cpp for msvc-8.0 2022-07-03 20:28:28 +03:00
Peter Dimov c28d0b813b Directly cast to size_t all integrals no wider than size_t 2022-06-26 01:25:45 +03:00
Peter Dimov e39bf42dfc Update hash_string_test2.cpp 2022-06-15 22:56:57 +03:00
Peter Dimov 58502fddca Add hash_container_test.cpp 2022-06-15 22:52:56 +03:00
Peter Dimov 5701dd3119 Merge branch 'master' into develop 2022-06-14 15:38:19 +03:00
Peter Dimov 53c12550fa Define _SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING in hash_reference_values.cpp (refs #23) 2022-06-14 14:42:22 +03:00
Peter Dimov 561cc5d010 Merge branch 'master' into develop 2022-06-13 14:26:03 +03:00
Peter Dimov bdf4bfe910 Disable C4996 in hash_complex_test.cpp (refs #23) 2022-06-13 14:05:35 +03:00
Peter Dimov 06e1b613f0 Add benchmark/char_seq.cpp 2022-06-08 17:48:06 +03:00
Peter Dimov 12be64b71e Update benchmark/unordered.cpp 2022-06-08 14:18:28 +03:00
Peter Dimov 4e2811c4e1 Add old_boost_hash to benchmark/unordered.cpp 2022-06-07 02:33:18 +03:00
Peter Dimov 2dc57b745f Output number of collisions in benchmark/unordered.cpp 2022-06-07 02:08:00 +03:00
Peter Dimov de618bf974 Add benchmark/unordered.cpp 2022-06-06 22:45:49 +03:00
Peter Dimov 87c9eefe6e Add ubuntu-22.04 to posix-cmake jobs 2022-06-04 18:17:35 +03:00
Peter Dimov 98bbd2ba56 Disable hash_fs_path_test for msvc-14.0 cxxstd=latest 2022-06-04 15:53:54 +03:00
Peter Dimov 08ea1677be Disable -Wshadow and -Wconversion for the fs path tests because of gcc-4.8 2022-06-04 14:25:47 +03:00
Peter Dimov 3d3350646f Disable use of <filesystem> under MinGW (fails on GHA) 2022-06-04 14:19:01 +03:00
Peter Dimov 884ce4b708 Disable -Wsign-conversion for GCC 8 2022-06-04 02:01:50 +03:00
Peter Dimov db1e23b611 Disable -Wsign-conversion for GCC in hash_reference_values.cpp 2022-06-04 01:49:26 +03:00
Peter Dimov 5ddcd7c8e7 Disable detail_is_range_test2.cpp under CMake 2022-06-03 22:44:32 +03:00
Peter Dimov 0e2e911df5 Attempt to fix -Wsign-conversion warnings under some GCC versions 2022-06-03 22:43:04 +03:00
Peter Dimov b3c9b35a13 Disable -Wc99-extensions for Clang 2022-06-03 21:38:02 +03:00
Peter Dimov c9c77cb104 Update warning suppressions 2022-06-03 20:59:41 +03:00
Peter Dimov 873a60d009 Disable -Wvariadic-macros for Clang as well 2022-06-03 20:19:01 +03:00
Peter Dimov b8d315fac5 Update is_range, disable -Wvariadic-macros for GCC 2022-06-03 20:14:07 +03:00
Peter Dimov e0e86a1413 Add detail_is_range_test2.cpp 2022-06-03 20:01:26 +03:00
Peter Dimov 866bd60dd3 Reject ranges that have themselves as their value_type (e.g. filesystem::path) 2022-06-03 19:52:03 +03:00
Peter Dimov 6781cff622 Add hash_fs_path_test.cpp 2022-06-03 19:31:33 +03:00
Peter Dimov dd605d0d1c Link CMake tests to Boost::utility 2022-05-30 03:05:54 +03:00
Peter Dimov dd172db079 Remove infinity special cases for libstdc++ 2022-05-30 02:52:22 +03:00
Peter Dimov e04ca1f442 Match floating point hash values in 32 bit mode 2022-05-30 02:35:00 +03:00
Peter Dimov 0eada2ae93 Revert hash_combine for floats 2022-05-30 02:26:12 +03:00
Peter Dimov 943ef0ab82 Avoid -Wconversion with is_signed and enums 2022-05-30 02:19:54 +03:00
Peter Dimov 14f8934bff Revert integral hashing 2022-05-30 01:57:56 +03:00
Peter Dimov f08204e29a Revert hash_value for std::complex 2022-05-29 21:59:17 +03:00
Peter Dimov 7ad0365048 Merge branch 'develop' into feature/refresh 2022-05-12 18:00:03 +03:00
Peter Dimov b3e424b650 Add gcc-12, clang-13, clang-14 to GHA 2022-05-11 22:23:41 +03:00
Peter Dimov d2986d9a64 Test boost::core::string_view in hash_string_test2 2022-04-29 02:01:46 +03:00
Peter Dimov 000276988f Add hash_string_test2 2022-04-28 21:13:23 +03:00
Peter Dimov 355603c0c2 Update ci.yml 2022-03-09 16:36:40 +02:00
Peter Dimov 33cd0a5964 Merge pull request #21 from cmazakas/doc-fixes
Doc fixes
2022-02-09 00:06:51 +02:00
Christian Mazakas fc11122353 Refactor links to no longer open up a new tab 2022-02-08 13:18:06 -08:00
Christian Mazakas cb233af718 Update [listing]s to become proper source code blocks 2022-02-08 13:18:01 -08:00
Christian Mazakas 8d820ee7d0 Remove unnecessary cross-references 2022-02-08 13:17:19 -08:00
Peter Dimov 3800d712d5 Merge pull request #20 from cmazakas/qbk-cleanup
Remove unneeded QuickBook and sample files from docs
2022-02-08 01:36:02 +02:00
Christian Mazakas dee871f45c Remove unneeded QuickBook and sample files from docs 2022-02-07 13:11:32 -08:00
Peter Dimov 143a55ea3b Add doc/.gitignore 2022-02-05 02:13:07 +02:00
Peter Dimov 4ab431f12f Update index.html 2022-02-05 02:12:27 +02:00
Christian Mazakas 773307fe1c Add Reference section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 06db43a56a Add Copyright section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 5906cba1a0 Add Acknowledgements section 2022-02-04 15:16:18 -08:00
Christian Mazakas b2222c2755 Add Links section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 6600a26460 Add Rationale to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas c95e02fe85 Add Change List to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 334eac8166 Add Disabling section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 21dbdb9b47 Add Portability section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 74f9abe52c Add Combining Hashes section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 37f3e6fcb7 Add Extending boost::hash section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 301c76646c Add Tutorial section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas a67e350fd9 Add Introduction section to AsciiDoc 2022-02-04 15:16:18 -08:00
Christian Mazakas 2d23e7e056 Update Jamfile to produce AsciiDoc and add corresponding file stubs 2022-02-03 15:33:02 -08:00
Peter Dimov 9bdebb3df4 Merge branch 'develop' into feature/refresh 2021-10-19 17:37:20 +03:00
Peter Dimov e9ffeceeab Merge branch 'develop' into feature/reference 2021-10-19 01:57:24 +03:00
Peter Dimov 4a685b2b16 Add address-model=32 tests to ci.yml 2021-10-19 01:07:05 +03:00
Peter Dimov 8315ec2ba7 Comment out (uint128)-1 test under GCC 9 and below 2021-10-18 03:20:23 +03:00
Peter Dimov 1a4888cdb4 Add (uint128)-1 comment 2021-10-18 03:01:41 +03:00
Peter Dimov 9e938aca41 Revert "Update (uint128)-1 test"
This reverts commit cab5c6c8d7.
2021-10-18 03:00:17 +03:00
Peter Dimov 7abcf22762 Update long double infinity reference values for 32 bit GCC-like without fpclassify 2021-10-18 02:38:25 +03:00
Peter Dimov dbb410b7ef Update long double reference values for 32 bit GCC 2021-10-18 02:31:06 +03:00
Peter Dimov cab5c6c8d7 Update (uint128)-1 test 2021-10-18 02:21:58 +03:00
Peter Dimov 526e4d472d Add reference values for std::complex 2021-10-18 02:16:50 +03:00
Peter Dimov fca37b0d43 Fix long double infinity 2021-10-18 01:11:24 +03:00
Peter Dimov 0a795c62a3 Update (uint128)-1 and long double infinity values 2021-10-18 00:55:31 +03:00
Peter Dimov 4ff953b568 Fix clang 2021-10-18 00:37:46 +03:00
Peter Dimov cfbc94b128 Update infinity reference values 2021-10-18 00:15:16 +03:00
Peter Dimov f0bed67909 Update long double values for g++ 64 bit 2021-10-18 00:01:15 +03:00
Peter Dimov 1c27af1e2e Add hash_reference_values.cpp 2021-10-17 23:54:39 +03:00
Peter Dimov ebac66dc1e Print hash_info output in ci.yml 2021-10-17 20:22:06 +03:00
Peter Dimov f0e75dd010 Reenable clang-win in appveyor.yml 2021-10-17 20:20:57 +03:00
Peter Dimov 5959103346 Extend __GNUC__ warning suppression to __clang__ 2021-10-17 20:13:56 +03:00
Peter Dimov 3c3948ccdb Take care of size_t -> int warnings under g++ 4.8 2021-10-17 19:54:23 +03:00
Peter Dimov 998d8da8c8 Disable warning in test/check_float_funcs.cpp 2021-10-17 19:54:12 +03:00
Peter Dimov bdc2840738 Update test/Jamfile 2021-10-17 19:52:16 +03:00
Peter Dimov 56f790d896 Add hash_integral_test.cpp 2021-10-17 19:36:53 +03:00
Peter Dimov 355c1cd7a4 Add hash_number_test2 2021-10-17 19:28:51 +03:00
Peter Dimov c9b2d6fc90 Reenable clang-win in appveyor.yml 2021-10-17 19:08:15 +03:00
Peter Dimov 2424ada9f9 Bias integral values so that small integers hash to themselves even when having a wide type 2021-10-17 19:03:15 +03:00
Peter Dimov faea988310 Revert change to hash_number_test.cpp 2021-10-17 17:49:10 +03:00
Peter Dimov 64c367734d Print hash_info output in ci.yml 2021-10-17 16:45:40 +03:00
Peter Dimov 6d84f9a41b Print size_t and floating point widths in hash_info 2021-10-17 16:43:02 +03:00
Peter Dimov aaa1f441ac GCC 32 bit under Windows has an 80 bit long double in 12 bytes, not 16 2021-10-17 16:17:44 +03:00
Peter Dimov 3487450f62 Add CMake tests to ci.yml 2021-10-17 08:46:35 +03:00
Peter Dimov 8f163568f4 Add test/CMakeLists.txt 2021-10-17 08:37:07 +03:00
Peter Dimov a4cbaa95b3 Regenerate CMakeLists.txt 2021-10-17 08:35:11 +03:00
Peter Dimov 6ffc99adb7 Update test/Jamfile 2021-10-17 08:22:24 +03:00
Peter Dimov bb99a2b1ae Leave detail/limits.hpp a stub; update test 2021-10-17 08:15:10 +03:00
Peter Dimov f05e8840d2 Remove float support files 2021-10-17 08:14:35 +03:00
Peter Dimov dff8843bb2 Remove unnecessary include 2021-10-17 07:52:03 +03:00
Peter Dimov 15ae39e176 Implement floating point hashing inline in hash.hpp 2021-10-17 07:47:34 +03:00
Peter Dimov 39e4a4f184 Switch to type_traits/enable_if to eliminate the Core dependency 2021-10-17 07:10:47 +03:00
Peter Dimov 88fbad7438 Remove Borland workarounds 2021-10-17 04:00:10 +03:00
Peter Dimov 0737c56fec Move boost::hash into hash.hpp, delete specializations 2021-10-17 03:54:41 +03:00
Peter Dimov 2b9251069f Move std::tuple support to detail/hash_tuple.hpp 2021-10-17 02:40:29 +03:00
Peter Dimov a63c85007f Move std::unique_ptr, std::shared_ptr support into hash.hpp 2021-10-17 02:14:19 +03:00
Peter Dimov 7a29dee42a Move std::pair support into hash.hpp 2021-10-17 02:11:51 +03:00
Peter Dimov a0a6fa0616 Move std::complex support to hash.hpp 2021-10-17 02:03:50 +03:00
Peter Dimov fe66085fbc Add hash_forward_list_test.cpp 2021-10-17 01:15:01 +03:00
Peter Dimov 24598bd45f Take care of g++ warning on 4294967291 2021-10-17 00:47:28 +03:00
Peter Dimov 7f2a43226e Take care of size_t -> int warnings under g++ 4.8 2021-10-17 00:31:08 +03:00
Peter Dimov 668f28660d Disable warning in test/check_float_funcs.cpp 2021-10-17 00:17:01 +03:00
Peter Dimov 9348a89fb4 Fix msvc-14.1 errors caused by their unconstrained stdext::hash_value overload (!) 2021-10-17 00:09:20 +03:00
Peter Dimov 3f2612d36e Update test/Jamfile, turn warnings-as-errors=on, fix g++ warning 2021-10-16 22:22:29 +03:00
Peter Dimov 3cf502b34c Add generic hash_value functions for ranges to hash.hpp, remove those from extensions.hpp 2021-10-16 22:12:31 +03:00
Peter Dimov b2e3beea3f Remove unnecessary warning suppression 2021-10-16 21:02:28 +03:00
Peter Dimov d308495a67 Add detail/is_unordered_range.hpp 2021-10-16 21:01:07 +03:00
Peter Dimov 00c837d523 Add detail/is_contiguous_range.hpp 2021-10-16 20:54:51 +03:00
Peter Dimov 415f2fafe2 Add detail/is_range.hpp 2021-10-16 20:44:32 +03:00
Peter Dimov 9bbedce029 Add missing include 2021-10-16 18:46:00 +03:00
Peter Dimov 2fc970b6ae Simplify hash_value for integrals 2021-10-16 17:29:02 +03:00
Peter Dimov 4e11c855cb Remove use of <functional> 2021-10-16 16:55:27 +03:00
Peter Dimov bd379e1a46 Remove VMS workaround 2021-10-16 16:54:08 +03:00
Peter Dimov b201ff97a8 Use Config macros for detecting C++17 headers 2021-10-16 16:43:11 +03:00
Peter Dimov e89fe04479 Remove more BOOST_NO_FUNCTION_TEMPLATE_ORDERING workarounds 2021-10-16 16:26:42 +03:00
Peter Dimov 7ce3f759ec Remove __DMC__ workarounds 2021-10-16 16:24:56 +03:00
Peter Dimov 917ac6a88a Remove BOOST_HASH_CHAR_TRAITS 2021-10-16 16:22:33 +03:00
Peter Dimov 9782883434 Remove BOOST_NO_FUNCTION_TEMPLATE_ORDERING workarounds 2021-10-16 16:20:54 +03:00
Peter Dimov f0ef7b8e84 Remove BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workarounds 2021-10-16 16:18:02 +03:00
Peter Dimov 21f2b5e1db Fix hash_combine_impl to only test for a specific bit width and not for concrete types 2021-10-12 19:52:37 +03:00
Peter Dimov b55fbc9252 Update key in libraries.json 2021-10-12 19:51:11 +03:00
Peter Dimov a0465807c7 Switch to 18.04 in ci.yml 2021-10-12 19:06:13 +03:00
Peter Dimov e03c31c9bc Add -I examples to depinst 2021-10-12 17:56:31 +03:00
Peter Dimov c4d9a95b82 Update appveyor.yml 2021-10-12 17:40:47 +03:00
Peter Dimov 5f5a5d0648 Merge pull request #14 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-10-12 17:33:26 +03:00
Peter Dimov fd2781afc9 Update ci.yml 2021-08-10 17:56:49 +03:00
Peter Dimov d045cf2ecb Update ci.yml 2021-08-10 17:48:23 +03:00
Peter Dimov b4e4bf577f Add -I examples to depinst 2021-08-10 17:37:22 +03:00
Peter Dimov 310ca091a2 Add .github/workflows/ci.yml 2021-08-10 17:32:10 +03:00
Peter Dimov e69c4c830e Update CMakeLists.txt 2021-06-10 01:18:25 +03:00
Edward Diener aaf0d2525f [skip ci] Add "cxxstd" json field. The "cxxstd" json field is being added to each Boost library's meta json information for libraries in order to specify the minumum C++ standard compilation level. The value of this field matches one of the values for 'cxxstd' in Boost.Build. The purpose of doing this is to provide information for the Boost website documentation for each library which will specify the minimum C++ standard compilation that an end-user must employ in order to use the particular library. This will aid end-users who want to know if they can successfully use a Boost library based on their C++ compiler's compilation level, without having to search the library's documentation to find this out. 2021-01-19 12:42:27 -05:00
Glen Fernandes 171c012d47 Merge pull request #11 from boostorg/mclow-patch-1
Remove use of non-existant Boost.Config macro BOOST_NO_CXX11_HDR_MEMORY
2020-10-25 14:06:10 -04:00
Marshall Clow e0331c0bd4 Remove use of non-existant Boost.Config macro BOOST_NO_CXX11_HDR_MEMORY
Thanks to Jeff Trull for the catch.
2020-09-10 20:09:23 -07:00
Marshall Clow e30bbab19f Merge pull request #9 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74. Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost conf…
2020-04-16 07:53:06 -07:00
Edward Diener 1818113f4c Change __BORLANDC__ to BOOST_BORLANDC, which is defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-23 11:50:36 -04:00
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
124 changed files with 6058 additions and 3408 deletions
+72
View File
@@ -0,0 +1,72 @@
# Copyright 2017 Daniel James
# Copyright 2016-2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
- /feature\/.*/
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
ADDRMD: 32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-12.0,msvc-14.0
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: clang-win
ADDRMD: 64
CXXSTD: 14,17,latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: clang-win
CXXSTD: 14,17,latest
ADDRMD: 64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
TOOLSET: gcc
CXXSTD: 03,11,14,1z
install:
- set BOOST_BRANCH=develop
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
- cd ..
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\container_hash\
- python tools/boostdep/depinst/depinst.py -I examples container_hash
- cmd /c bootstrap
- b2 -d0 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j3 --verbose-test libs/container_hash/test//hash_info toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
- b2 -j3 libs/container_hash/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker
+386
View File
@@ -0,0 +1,386 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "03,11"
os: ubuntu-18.04
install: g++-4.8-multilib
address-model: 32,64
- toolset: gcc-5
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: g++-5-multilib
address-model: 32,64
- toolset: gcc-6
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: g++-6-multilib
address-model: 32,64
- toolset: gcc-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: g++-7-multilib
address-model: 32,64
- toolset: gcc-8
cxxstd: "03,11,14,17,2a"
os: ubuntu-18.04
install: g++-8-multilib
address-model: 32,64
- toolset: gcc-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-9-multilib
address-model: 32,64
- toolset: gcc-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: g++-10-multilib
address-model: 32,64
- toolset: gcc-11
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
install: g++-11-multilib
address-model: 32,64
- toolset: gcc-12
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: g++-12-multilib
address-model: 32,64
- toolset: clang
compiler: clang++-3.9
cxxstd: "03,11,14"
os: ubuntu-18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "03,11,14"
os: ubuntu-18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "03,11,14,1z"
os: ubuntu-18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "03,11,14,17"
os: ubuntu-18.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "03,11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-11
cxxstd: "03,11,14,17,2a"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-12
cxxstd: "03,11,14,17,20"
os: ubuntu-20.04
- toolset: clang
compiler: clang++-13
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "03,11,14,17,20"
os: ubuntu-22.04
install: clang-14
- toolset: clang
cxxstd: "03,11,14,17,2a"
os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py -I examples --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
export ADDRMD=${{matrix.address-model}}
./b2 -j3 --verbose-test libs/$LIBRARY/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} ${ADDRMD:+address-model=$ADDRMD} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: 14,latest
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py -I examples --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 --verbose-test libs/%LIBRARY%/test//hash_info toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
posix-cmake-subdir:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Use library with add_subdirectory
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_subdir_test
mkdir __build__ && cd __build__
cmake ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-install:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DCMAKE_INSTALL_PREFIX=~/.local ..
- name: Install
run: |
cd ../boost-root/__build__
cmake --build . --target install
- name: Use the installed library
run: |
cd ../boost-root/libs/$LIBRARY/test/cmake_install_test && mkdir __build__ && cd __build__
cmake -DCMAKE_INSTALL_PREFIX=~/.local ..
cmake --build .
ctest --output-on-failure --no-tests=error
posix-cmake-test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-18.04
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v2
- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
- name: Configure
run: |
cd ../boost-root
mkdir __build__ && cd __build__
cmake -DBOOST_INCLUDE_LIBRARIES=$LIBRARY -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd ../boost-root/__build__
cmake --build . --target tests
- name: Run tests
run: |
cd ../boost-root/__build__
ctest --output-on-failure --no-tests=error
+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
+25
View File
@@ -0,0 +1,25 @@
# Generated by `boostdep --cmake container_hash`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_container_hash VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_container_hash INTERFACE)
add_library(Boost::container_hash ALIAS boost_container_hash)
target_include_directories(boost_container_hash INTERFACE include)
target_link_libraries(boost_container_hash
INTERFACE
Boost::config
Boost::type_traits
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
+101
View File
@@ -0,0 +1,101 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _CRT_SECURE_NO_WARNINGS
#include <boost/container_hash/hash.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/core/type_name.hpp>
#include <boost/config.hpp>
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <chrono>
// test_hash_speed
template<class T, class V> void test_hash_speed( int N, V const& v )
{
std::vector<T> w;
w.reserve( N );
for( int i = 0; i < N; ++i )
{
w.emplace_back( v[i].begin(), v[i].end() );
}
typedef std::chrono::steady_clock clock_type;
clock_type::time_point t1 = clock_type::now();
std::size_t q = 0;
boost::hash<T> const h;
for( int i = 0; i < N; ++i )
{
q += h( w[i] );
}
clock_type::time_point t2 = clock_type::now();
long long ms1 = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
std::string type = boost::core::type_name<T>();
#if defined( _MSC_VER )
std::printf( "%25s : q=%20Iu, %lld ms\n", type.c_str(), q, ms1 );
#else
std::printf( "%25s : q=%20zu, %lld ms\n", type.c_str(), q, ms1 );
#endif
}
int main()
{
int const N = 1048576 * 8;
std::vector<std::string> v;
{
v.reserve( N );
boost::detail::splitmix64 rnd;
for( int i = 0; i < N; ++i )
{
char buffer[ 64 ];
unsigned long long k = rnd();
if( k & 1 )
{
sprintf( buffer, "prefix_%llu_suffix", k );
}
else
{
sprintf( buffer, "{%u}", static_cast<unsigned>( k ) );
}
v.push_back( buffer );
}
}
std::puts( "Char sequence hashing test:\n" );
test_hash_speed< std::string >( N, v );
test_hash_speed< std::vector<char> >( N, v );
test_hash_speed< std::deque<char> >( N, v );
test_hash_speed< std::list<char> >( N, v );
std::puts( "" );
}
+389
View File
@@ -0,0 +1,389 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _CRT_SECURE_NO_WARNINGS
#include <boost/container_hash/hash.hpp>
#include <boost/unordered_set.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/core/type_name.hpp>
#include <boost/config.hpp>
#include <cstddef>
#include <cstdio>
#include <cstdint>
#include <string>
#include <vector>
#include <chrono>
#include <functional>
// mul31_hash
class mul31_hash
{
public:
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
{
char const * p = st.data();
std::size_t n = st.size();
#if SIZE_MAX > UINT32_MAX
std::size_t h = 0xCBF29CE484222325ull;
#else
std::size_t h = 0x811C9DC5u;
#endif
for( std::size_t i = 0; i < n; ++i )
{
h = h * 31 + static_cast<unsigned char>( p[i] );
}
return h;
}
};
// mul31_unrolled_hash
template<int Bits> struct mul31_unrolled_hash_impl;
template<> struct mul31_unrolled_hash_impl<32>
{
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
{
char const * p = st.data();
std::size_t n = st.size();
std::size_t h = 0x811C9DC5u;
while( n >= 4 )
{
h = h * (31u * 31u * 31u * 31u)
+ static_cast<unsigned char>( p[0] ) * (31u * 31u * 31u)
+ static_cast<unsigned char>( p[1] ) * (31u * 31u)
+ static_cast<unsigned char>( p[2] ) * 31u
+ static_cast<unsigned char>( p[3] );
p += 4;
n -= 4;
}
while( n > 0 )
{
h = h * 31u + static_cast<unsigned char>( *p );
++p;
--n;
}
return h;
}
};
template<> struct mul31_unrolled_hash_impl<64>
{
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
{
char const * p = st.data();
std::size_t n = st.size();
std::size_t h = 0xCBF29CE484222325ull;
while( n >= 8 )
{
h = h * (31ull * 31ull * 31ull * 31ull * 31ull * 31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[0] ) * (31ull * 31ull * 31ull * 31ull * 31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[1] ) * (31ull * 31ull * 31ull * 31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[2] ) * (31ull * 31ull * 31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[3] ) * (31ull * 31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[4] ) * (31ull * 31ull * 31ull)
+ static_cast<unsigned char>( p[5] ) * (31ull * 31ull)
+ static_cast<unsigned char>( p[6] ) * 31ull
+ static_cast<unsigned char>( p[7] );
p += 8;
n -= 8;
}
while( n > 0 )
{
h = h * 31u + static_cast<unsigned char>( *p );
++p;
--n;
}
return h;
}
};
struct mul31_unrolled_hash: mul31_unrolled_hash_impl< std::numeric_limits<std::size_t>::digits > {};
// fnv1a_hash
template<int Bits> struct fnv1a_hash_impl;
template<> struct fnv1a_hash_impl<32>
{
std::size_t operator()( std::string const& s ) const
{
std::size_t h = 0x811C9DC5u;
char const * first = s.data();
char const * last = first + s.size();
for( ; first != last; ++first )
{
h ^= static_cast<unsigned char>( *first );
h *= 0x01000193ul;
}
return h;
}
};
template<> struct fnv1a_hash_impl<64>
{
std::size_t operator()( std::string const& s ) const
{
std::size_t h = 0xCBF29CE484222325ull;
char const * first = s.data();
char const * last = first + s.size();
for( ; first != last; ++first )
{
h ^= static_cast<unsigned char>( *first );
h *= 0x00000100000001B3ull;
}
return h;
}
};
struct fnv1a_hash: fnv1a_hash_impl< std::numeric_limits<std::size_t>::digits > {};
// old_boost_hash
class old_boost_hash
{
public:
std::size_t operator()( std::string const& st ) const BOOST_NOEXCEPT
{
char const * p = st.data();
std::size_t n = st.size();
std::size_t h = 0;
for( std::size_t i = 0; i < n; ++i )
{
h ^= static_cast<unsigned char>( p[i] ) + 0x9e3779b9 + ( h << 6 ) + ( h >> 2 );
}
return h;
}
};
// test_hash_speed
template<class H, class V> void test_hash_speed( int N, V const& v )
{
typedef std::chrono::steady_clock clock_type;
clock_type::time_point t1 = clock_type::now();
std::size_t q = 0;
H const h;
for( int i = 0; i < N; ++i )
{
q += h( v[i] );
}
clock_type::time_point t2 = clock_type::now();
long long ms1 = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
std::string hash = boost::core::type_name<H>();
#if defined( _MSC_VER )
std::printf( "%25s : q=%20Iu, %lld ms\n", hash.c_str(), q, ms1 );
#else
std::printf( "%25s : q=%20zu, %lld ms\n", hash.c_str(), q, ms1 );
#endif
}
// test_hash_collision
template<class H, class V> void test_hash_collision( int N, V const& v, std::size_t n )
{
boost::unordered_set<std::size_t> s;
H const h;
for( int i = 0; i < N; ++i )
{
s.insert( h( v[i] ) );
}
std::string hash = boost::core::type_name<H>();
#if defined( _MSC_VER )
std::printf( "%25s : c=%Iu\n", hash.c_str(), n - s.size() );
#else
std::printf( "%25s : c=%zu\n", hash.c_str(), n - s.size() );
#endif
}
// test_container_speed
template<class V, class S> void test4( int N, V const& v, char const * hash, S s )
{
typedef std::chrono::steady_clock clock_type;
clock_type::time_point t1 = clock_type::now();
for( int i = 0; i < N; ++i )
{
s.insert( v[ i * 16 ] );
}
clock_type::time_point t2 = clock_type::now();
std::size_t q = 0;
for( int i = 0; i < 16 * N; ++i )
{
q += s.count( v[ i ] );
}
clock_type::time_point t3 = clock_type::now();
long long ms1 = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
long long ms2 = std::chrono::duration_cast<std::chrono::milliseconds>( t3 - t2 ).count();
std::size_t n = s.bucket_count();
std::size_t m = 0;
std::size_t c = 0;
for( std::size_t i = 0; i < n; ++i )
{
std::size_t k = s.bucket_size( i );
if( k > 1 )
{
c += k - 1;
}
if( k > m )
{
m = k;
}
}
#if defined( _MSC_VER )
std::printf( "%25s : n=%Iu, m=%Iu, c=%Iu, q=%Iu, %lld + %lld ms\n", hash, n, m, c, q, ms1, ms2 );
#else
std::printf( "%25s : n=%zu, m=%zu, c=%zu, q=%zu, %lld + %lld ms\n", hash, n, m, c, q, ms1, ms2 );
#endif
}
template<class K, class H, class V> void test_container_speed( int N, V const& v )
{
boost::unordered_set<K, H> s( 0 );
test4( N, v, boost::core::type_name<H>().c_str(), s );
}
int main()
{
int const N = 1048576 / 2; // 1048576 is too much for 32 bit
std::vector<std::string> v;
{
v.reserve( N * 16 );
boost::detail::splitmix64 rnd;
for( int i = 0; i < 16 * N; ++i )
{
char buffer[ 64 ];
unsigned long long k = rnd();
if( k & 1 )
{
sprintf( buffer, "prefix_%llu_suffix", k );
}
else
{
sprintf( buffer, "{%u}", static_cast<unsigned>( k ) );
}
v.push_back( buffer );
}
}
std::puts( "Hash speed test:\n" );
test_hash_speed<mul31_hash>( N * 16, v );
test_hash_speed<mul31_unrolled_hash>( N * 16, v );
test_hash_speed<fnv1a_hash>( N * 16, v );
test_hash_speed<old_boost_hash>( N * 16, v );
test_hash_speed<boost::hash<std::string> >( N * 16, v );
test_hash_speed<std::hash<std::string> >( N * 16, v );
std::puts( "" );
std::puts( "Hash collision test:\n" );
{
std::size_t n = 0;
{
boost::unordered_set<std::string> s;
for( int i = 0; i < N * 16; ++i )
{
s.insert( v[i] );
}
n = s.size();
}
test_hash_collision<mul31_hash>( N * 16, v, n );
test_hash_collision<mul31_unrolled_hash>( N * 16, v, n );
test_hash_collision<fnv1a_hash>( N * 16, v, n );
test_hash_collision<old_boost_hash>( N * 16, v, n );
test_hash_collision<boost::hash<std::string> >( N * 16, v, n );
test_hash_collision<std::hash<std::string> >( N * 16, v, n );
}
std::puts( "" );
typedef std::string K;
std::puts( "Container speed test:\n" );
test_container_speed<K, mul31_hash>( N, v );
test_container_speed<K, mul31_unrolled_hash>( N, v );
test_container_speed<K, fnv1a_hash>( N, v );
test_container_speed<K, old_boost_hash>( N, v );
test_container_speed<K, boost::hash<std::string> >( N, v );
test_container_speed<K, std::hash<std::string> >( N, v );
std::puts( "" );
}
+2
View File
@@ -0,0 +1,2 @@
/html/
/pdf/
+16 -10
View File
@@ -3,14 +3,20 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
xml hash : hash.qbk ;
boostbook standalone : hash :
<xsl:param>boost.root=../../../..
import asciidoctor ;
<xsl:param>chunk.first.sections=1
<xsl:param>chunk.section.depth=2
<xsl:param>generate.section.toc.level=2
<xsl:param>toc.section.depth=1
<xsl:param>toc.max.depth=1
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/functional/hash/doc/html
;
html hash.html : hash.adoc ;
install html_ : hash.html : <location>html ;
pdf hash.pdf : hash.adoc ;
explicit hash.pdf ;
install pdf_ : hash.pdf : <location>pdf ;
explicit pdf_ ;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : html_ ;
explicit boostrelease ;
-109
View File
@@ -1,109 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:changes Change Log]
[h2 Boost 1.33.0]
* Initial Release
[h2 Boost 1.33.1]
* Fixed the points example, as pointed out by 沈慧峰.
[h2 Boost 1.34.0]
* Use declarations for standard classes, so that the library
doesn't need to include all of their headers
* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header,
<[headerref boost/functional/hash.hpp]> is used.
* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which
disables the extensions to TR1.
* Minor improvements to the hash functions for floating point numbers.
* Update the portable example to hopefully be more generally portable.
[h2 Boost 1.34.1]
* [@http://svn.boost.org/trac/boost/ticket/952 Ticket 952]:
Suppress incorrect 64-bit warning on Visual C++.
[h2 Boost 1.35.0]
* Support for `long long`, `std::complex`.
* Improved algorithm for hashing floating point numbers:
* Improved portablity, as described by Daniel Krügler in
[@http://lists.boost.org/boost-users/2005/08/13418.php
a post to the boost users list].
* Fits more information into each combine loop, which can reduce the
the number of times combine is called and hopefully give a better
quality hash function.
* Improved the algorithm for hashing floating point numbers.
* On Cygwin use a binary hash function for floating point numbers, as
Cygwin doesn't have decent floating point functions for `long double`.
* Never uses `fpclass` which doesn't support `long double`.
* [@http://svn.boost.org/trac/boost/ticket/1064 Ticket 1064]:
Removed unnecessary use of `errno`.
* Explicitly overload for more built in types.
* Minor improvements to the documentation.
* A few bug and warning fixes:
* [@http://svn.boost.org/trac/boost/ticket/1509 Ticket 1509]:
Suppress another Visual C++ warning.
* Some workarounds for the Sun compilers.
[h2 Boost 1.36.0]
* Stop using OpenBSD's dodgy `std::numeric_limits`.
* Using the boost typedefs for `long long` and `unsigned long long`.
* Move the extensions into their own header.
[h2 Boost 1.37.0]
* [@http://svn.boost.org/trac/boost/ticket/2264 Ticket 2264]:
In Visual C++, always use C99 float functions for `long double` and `float` as
the C++ overloads aren't always availables.
[h2 Boost 1.38.0]
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These
will be removed in a future version of Boost.
* Moved detail headers out of `boost/functional/detail`, since they are part of
functional/hash, not functional. `boost/functional/detail/container_fwd.hpp`
has been moved to `boost/detail/container_fwd.hpp` as it's used outside of
this library, the others have been moved to `boost/functional/hash/detail`.
[h2 Boost 1.39.0]
* Move the hash_fwd.hpp implementation into the hash subdirectory, leaving a
forwarding header in the old location. You should still use the old location,
the new location is mainly for implementation and possible modularization.
* [@https://svn.boost.org/trac/boost/ticket/2412 Ticket 2412]: Removed deprecated
headers.
* [@https://svn.boost.org/trac/boost/ticket/2957 Ticket 2957]: Fix configuration
for vxworks.
[h2 Boost 1.40.0]
* Automatically configure the float functions using template metaprogramming
instead of trying to configure every possibility manually.
* Workaround for when STLport doesn't support long double.
[h2 Boost 1.42.0]
* Reduce the number of warnings for Visual C++ warning level 4.
* Some code formatting changes to fit lines into 80 characters.
* Rename an internal namespace.
[h2 Boost 1.43.0]
* [@https://svn.boost.org/trac/boost/ticket/3866 Ticket 3866]:
Don't foward declare containers when using gcc's parallel library,
allow user to stop forward declaration by defining the
`BOOST_DETAIL_NO_CONTAINER_FWD` macro.
* [@https://svn.boost.org/trac/boost/ticket/4038 Ticket 4038]:
Avoid hashing 0.5 and 0 to the same number.
* Stop using deprecated `BOOST_HAS_*` macros.
[endsect]
-29
View File
@@ -1,29 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:disable Disabling The Extensions]
While [classref boost::hash]'s extensions are generally useful, you might want
to turn them of in order to check that your code will work with other
implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`.
When this macro is defined, only the specialisations detailed
in TR1 will be declared. But, if you later undefine the macro and include
<[headerref boost/functional/hash.hpp]> then the non-specialised form will be defined
- activating the extensions.
It is strongly recommended that you never undefine the macro - and only define
it so that it applies to the complete translation unit, either by defining it
at the beginning of the main source file or, preferably, by using a compiler
switch or preference. And you really should never define it in header files.
If you are writing a library which has code in the header which requires the
extensions, then the best action is to tell users not to define the macro.
Their code won't ['require] the macro.
Translation units that are compiled with the macro defined will link with units
that were compiled without it. This feature has been designed to avoid ODR
violations.
[endsect]
+24
View File
@@ -0,0 +1,24 @@
= Boost.ContainerHash
:toc: left
:toclevels: 2
:idprefix:
:docinfo: private-footer
:source-highlighter: rouge
:nofooter:
:sectlinks:
:source-language: c++
:leveloffset: +1
include::hash/intro.adoc[]
include::hash/tutorial.adoc[]
include::hash/custom.adoc[]
include::hash/combine.adoc[]
include::hash/portability.adoc[]
include::hash/disable.adoc[]
include::hash/changes.adoc[]
include::hash/rationale.adoc[]
include::hash/ref.adoc[]
include::hash/links.adoc[]
include::hash/thanks.adoc[]
include::hash/copyright.adoc[]
-24
View File
@@ -1,24 +0,0 @@
[library Boost.Functional/Hash
[quickbook 1.4]
[authors [James, Daniel]]
[copyright 2005 2006 2007 2008 Daniel James]
[purpose A TR1 hash function object that can be extended to hash user
defined types]
[category higher-order]
[id hash]
[dirname functional/hash]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[include:hash intro.qbk]
[include:hash tutorial.qbk]
[include:hash portability.qbk]
[include:hash disable.qbk]
[include:hash changes.qbk]
[xinclude ref.xml]
[include:hash links.qbk]
[include:hash thanks.qbk]
+132
View File
@@ -0,0 +1,132 @@
[#changes]
= Change Log
:cpp: C++
:int128: __int128
:idprefix: changes_
== 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 (https://svn.boost.org/trac/boost/ticket/11017[#11017]).
* Quick fix for hashing `vector<bool>` when using lib{cpp}. Will try to introduce a more general fix in the next release.
== 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.
== Boost 1.65.0
* Support for `char16_t`, `char32_t`, `u16string`, `u32string`
== Boost 1.64.0
* Fix for recent versions of Visual {cpp} which have removed `std::unary_function` and `std::binary_function` (https://svn.boost.org/trac/boost/ticket/12353[#12353]).
== 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 (https://svn.boost.org/trac/boost/ticket/8552[#8552]).
== Boost 1.58.0
* Fixed strict aliasing violation (https://github.com/boostorg/container_hash/issues/3[GitHub #3]).
== Boost 1.56.0
* Removed some Visual {cpp} 6 workarounds.
* Ongoing work on improving `hash_combine`. This changes the combine function which was previously defined in the reference documentation.
== Boost 1.55.0
* Simplify a SFINAE check so that it will hopefully work on Sun 5.9 (https://svn.boost.org/trac10/ticket/8822[#8822]).
* Suppress Visual {cpp} infinite loop warning (https://svn.boost.org/trac10/ticket/8568[#8568]).
== Boost 1.54.0
* https://svn.boost.org/trac/boost/ticket/7957[Ticket 7957]: Fixed a typo.
== 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).
== 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.
== 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.
== Boost 1.50.0
* https://svn.boost.org/trac/boost/ticket/6771[Ticket 6771]: Avoid gcc's `-Wfloat-equal` warning.
* https://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`.
== Boost 1.46.0
* Avoid warning due with gcc's `-Wconversion` flag.
== 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.
== 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.
== Boost 1.42.0
* Reduce the number of warnings for Visual {cpp} warning level 4.
* Some code formatting changes to fit lines into 80 characters.
* Rename an internal namespace.
== Boost 1.40.0
* Automatically configure the `float` functions using template metaprogramming instead of trying to configure every possibility manually.
* Workaround for when STLport doesn't support long double.
== Boost 1.39.0
* Move the `hash_fwd.hpp` implementation into the hash subdirectory, leaving a forwarding header in the old location. You should still use the old location, the new location is mainly for implementation and possible modularization.
* https://svn.boost.org/trac/boost/ticket/2412[Ticket 2412]: Removed deprecated headers.
* https://svn.boost.org/trac/boost/ticket/2957[Ticket 2957]: Fix configuration for vxworks.
== Boost 1.38.0
* Changed the warnings in the deprecated headers from 1.34.0 to errors. These will be removed in a future version of Boost.
* Moved detail headers out of `boost/container_hash/detail`, since they are part of `functional/hash`, not `container_hash`. `boost/container_hash/detail/container_fwd.hpp` has been moved to `boost/detail/container_fwd.hpp` as it's used outside of this library, the others have been moved to `boost/functional/hash/detail`.
== Boost 1.37.0
* http://svn.boost.org/trac/boost/ticket/2264[Ticket 2264]: In Visual {cpp}, always use C99 float functions for long double and float as the {cpp} overloads aren't always availables.
== Boost 1.36.0
* Stop using OpenBSD's dodgy `std::numeric_limits`.
* Using the boost typedefs for `long long` and `unsigned long long`.
* Move the extensions into their own header.
== Boost 1.35.0
* Support for `long long`, `std::complex`.
* Improved algorithm for hashing floating point numbers:
** Improved portablity, as described by Daniel Krügler in http://lists.boost.org/boost-users/2005/08/13418.php[a post to the boost users list].
** Fits more information into each combine loop, which can reduce the the number of times combine is called and hopefully give a better quality hash function.
** Improved the algorithm for hashing floating point numbers.
** On Cygwin use a binary hash function for floating point numbers, as Cygwin doesn't have decent floating point functions for `long double`.
** Never uses `fpclass` which doesn't support `long double`.
** http://svn.boost.org/trac/boost/ticket/1064[Ticket 1064]: Removed unnecessary use of errno.
* Explicitly overload for more built in types.
* Minor improvements to the documentation.
* A few bug and warning fixes:
** http://svn.boost.org/trac/boost/ticket/1509[Ticket 1509]: Suppress another Visual {cpp} warning.
** Some workarounds for the Sun compilers.
== Boost 1.34.1
* https://svn.boost.org/trac10/ticket/952[Ticket 952]: Suppress incorrect 64-bit warning on Visual {cpp}.
== Boost 1.34.0
* Use declarations for standard classes, so that the library doesn't need to include all of their headers
* Deprecated the `<boost/functional/hash/*.hpp>` headers. Now a single header, `<boost/functional/hash.hpp>` is used.
* Add support for the `BOOST_HASH_NO_EXTENSIONS` macro, which disables the extensions to TR1.
* Minor improvements to the hash functions for floating point numbers.
* Update the portable example to hopefully be more generally portable.
== Boost 1.33.1
* Fixed the points example, as pointed out by 沈慧峰.
== Boost 1.33.0
* Initial Release
+80
View File
@@ -0,0 +1,80 @@
[#combine]
= Combining hash values
:idprefix: combine_
Say you have a point class, representing a two dimensional location:
[source]
----
class point
{
int x;
int y;
public:
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
};
----
and you wish to use it as the key for an unordered_map. You need to customise the hash for this structure. To do this we need to combine the hash values for x and y. The function `boost::hash_combine` is supplied for this purpose:
[source]
----
class point
{
...
friend std::size_t hash_value(point const& p)
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
...
};
----
Calls to `hash_combine` incrementally build the hash from the different members of `point`, it can be repeatedly called for any number of elements. It calls `hash_value` on the supplied element, and combines it with the seed.
Full code for this example is at link:../../examples/point.cpp[/libs/container_hash/examples/point.cpp].
[NOTE]
====
When using `boost::hash_combine` the order of the calls matters.
[source]
----
std::size_t seed = 0;
boost::hash_combine(seed, 1);
boost::hash_combine(seed, 2);
----
results in a different seed to:
[source]
----
std::size_t seed = 0;
boost::hash_combine(seed, 2);
boost::hash_combine(seed, 1);
----
If you are calculating a hash value for data where the order of the data doesn't matter in comparisons (e.g. a set) you will have to ensure that the data is always supplied in the same order.
====
To calculate the hash of an iterator range you can use `boost::hash_range`:
[source]
----
std::vector<std::string> some_strings;
std::size_t hash = boost::hash_range(some_strings.begin(), some_strings.end());
----
Note that when writing template classes, you might not want to include the main hash header as it's quite an expensive include that brings in a lot of other headers, so instead you can include the `<boost/container_hash/hash_fwd.hpp>` header which forward declares `boost::hash`, `boost::hash_range` and `boost::hash_combine`. You'll need to include the main header before instantiating `boost::hash`. When using a container that uses `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 link:../../examples/template.hpp[template.hpp] and link:../../examples/template.cpp[template.cpp].
+10
View File
@@ -0,0 +1,10 @@
[#copyright]
= Copyright and License
:idprefix: copyright_
*Daniel James*
Copyright (C) 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)
+68
View File
@@ -0,0 +1,68 @@
[#custom]
= Extending boost::hash for a custom data type
:idprefix: custom_
`boost::hash` is implemented by calling the function `hash_value`. The namespace isn't specified so that it can detect overloads via argument dependant lookup. So if there is a free function `hash_value` in the same namespace as a custom type, it will get called.
If you have a structure `library::book`, where each book is uniquely defined by its member `id`:
[source]
----
namespace library
{
struct book
{
int id;
std::string author;
std::string title;
// ....
};
bool operator==(book const& a, book const& b)
{
return a.id == b.id;
}
}
----
Then all you would need to do is write the function `library::hash_value`:
[source]
----
namespace library
{
std::size_t hash_value(book const& b)
{
boost::hash<int> hasher;
return hasher(b.id);
}
}
----
And you can now use `boost::hash` with book:
[source]
----
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
library::book dandelion(1354, "Paul J. Shanley",
"Hash & Dandelion Greens");
boost::hash<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife);
// If std::unordered_set is available:
std::unordered_set<library::book, boost::hash<library::book> > books;
books.insert(knife);
books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
books.insert(library::book(1953, "Snyder, Bernadette M.",
"Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
assert(books.find(knife) != books.end());
assert(books.find(dandelion) == books.end());
----
The full example can be found in: link:../../examples/books.hpp[/libs/container_hash/examples/books.hpp] and link:../../examples/books.cpp[/libs/container_hash/examples/books.cpp].
TIP: When writing a hash function, first look at how the equality function works. Objects that are equal must generate the same hash value. When objects are not equal they should generate different hash values. In this object equality was based just on the id so the hash function only hashes the id. If it was based on the object's name and author then the hash function should take them into account (how to do this is discussed in the next section).
+12
View File
@@ -0,0 +1,12 @@
[#disable]
= Disabling The Extensions
:idprefix: disable_
While ``boost::hash``'s extensions are generally useful, you might want to turn them of in order to check that your code will work with other implementations of TR1. To do this define the macro `BOOST_HASH_NO_EXTENSIONS`. When this macro is defined, only the specialisations detailed in TR1 will be declared. But, if you later undefine the macro and include `<boost/container_hash/hash.hpp>` then the non-specialised form will be defined - activating the extensions.
It is strongly recommended that you never undefine the macro - and only define it so that it applies to the complete translation unit, either by defining it at the beginning of the main source file or, preferably, by using a compiler switch or preference. And you really should never define it in header files.
If you are writing a library which has code in the header which requires the extensions, then the best action is to tell users not to define the macro. Their code won't _require_ the macro.
Translation units that are compiled with the macro defined will link with units that were compiled without it. This feature has been designed to avoid ODR violations.
+22
View File
@@ -0,0 +1,22 @@
[#intro]
= Introduction
:idprefix: intro_
`boost::hash` is an implementation of the https://en.wikipedia.org/wiki/Hash_function[hash function] object specified by the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[Draft Technical Report on C++ Library Extensions] (TR1). It is the default hash function for link:../../../unordered/index.html[Boost.Unordered], link:../../../intrusive/index.html[Boost.Intrusive]'s unordered associative containers, and link:../../../multi_index/index.html[Boost.MultiIndex]'s hash indicies and link:../../../bimap/index.html[Boost.Bimap]'s `unordered_set_of`.
As it is compliant with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1], it will work with:
* integers
* floats
* pointers
* strings
It also implements the extension proposed by Peter Dimov in issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63), this adds support for:
* arrays
* `std::pair`
* the standard containers.
* extending `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 <<rationale,rationale>>.
+12
View File
@@ -0,0 +1,12 @@
[#links]
= Links
:idprefix: links_
*A Proposal to Add Hash Tables to the Standard Library* http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html The hash table proposal explains much of the design. The hash function object is discussed in Section D.
*The C++ Standard Library Technical Report.* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf Contains the hash function specification in section 6.3.2.
*Library Extension Technical Report Issues List.* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf The library implements the extension described in Issue 6.18, pages 63-67.
*Methods for Identifying Versioned and Plagiarised Documents* Timothy C. Hoad, Justin Zobel http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf Contains the hash function that `boost::hash_combine` is based on.
+82
View File
@@ -0,0 +1,82 @@
[#portability]
= Portability
:idprefix: portability_
`boost::hash` is written to be as portable as possible, but unfortunately, several older compilers don't support argument dependent lookup (ADL) - the mechanism used for customisation. On those compilers custom overloads for `hash_value` needs to be declared in the `boost` namespace.
On a strictly standards compliant compiler, an overload defined in the `boost` namespace won't be found when `boost::hash` is instantiated, so for these compilers the overload should only be declared in the same namespace as the class.
Let's say we have a simple custom type:
[source]
----
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
friend std::size_t hash_value(custom_type x)
{
boost::hash<int> hasher;
return hasher(x.value);
}
};
}
----
On a compliant compiler, when `hash_value` is called for this type, it will look at the namespace inside the type and find `hash_value` but on a compiler which doesn't support ADL `hash_value` won't be found. To make things worse, some compilers which do support ADL won't find a friend class defined inside the class.
So first move the member function out of the class:
[source]
----
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash(custom_type x)
{
boost::hash<T> hasher;
return hasher(value);
}
};
template <class T>
inline std::size_t hash_value(custom_type<T> x)
{
return x.hash();
}
}
----
Unfortunately, I couldn't declare `hash_value` as a friend, as some compilers don't support template friends, so instead I declared a member function to calculate the hash, and called it from `hash_value`.
For compilers which don't support ADL, `hash_value` needs to be defined in the `boost` namespace:
[source]
----
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
----
Full code for this example is at link:../../examples/portable.cpp[/libs/container_hash/examples/portable.cpp].
+16
View File
@@ -0,0 +1,16 @@
[#rationale]
= Rationale
:idprefix: rationale_
The rationale can be found in the original designfootnote:[issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63)].
== 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).
+386
View File
@@ -0,0 +1,386 @@
[#ref]
= Reference
:idprefix: ref_
For the full specification, see section 6.3 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[C++ Standard Library Technical Report] and issue 6.18 of the http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf[Library Extension Technical Report Issues List] (page 63).
== Header <boost/container_hash/hash.hpp>
Defines `boost::hash`, and helper functions.
[source]
----
namespace boost {
template<typename T> struct hash;
template<> struct hash<bool>;
template<> struct hash<char>;
template<> struct hash<signed char>;
template<> struct hash<unsigned char>;
template<> struct hash<wchar_t>;
template<> struct hash<char16_t>;
template<> struct hash<char32_t>;
template<> struct hash<short>;
template<> struct hash<unsigned short>;
template<> struct hash<int>;
template<> struct hash<unsigned int>;
template<> struct hash<long>;
template<> struct hash<unsigned long>;
template<> struct hash<long long>;
template<> struct hash<unsigned long long>;
template<> struct hash<float>;
template<> struct hash<double>;
template<> struct hash<long double>;
template<> struct hash<std::string>;
template<> struct hash<std::wstring>;
template<> struct hash<std::u16string>;
template<> struct hash<std::u32string>;
template<> struct hash<std::type_index>;
template<typename T> struct hash<T*>;
// Support functions (Boost extension).
template<typename T>
void hash_combine(size_t &, T const&);
template<typename It>
std::size_t hash_range(It, It);
template<typename It>
void hash_range(std::size_t&, It, It);
// Overloadable hash implementation (Boost extension).
std::size_t hash_value(bool);
std::size_t hash_value(char);
std::size_t hash_value(signed char);
std::size_t hash_value(unsigned char);
std::size_t hash_value(wchar_t);
std::size_t hash_value(char16_t);
std::size_t hash_value(char32_t);
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);
std::size_t hash_value(long long);
std::size_t hash_value(unsigned long long);
std::size_t hash_value(float);
std::size_t hash_value(double);
std::size_t hash_value(long double);
template<typename T>
std::size_t hash_value(T* const&);
template<typename T, unsigned N>
std::size_t hash_value(T (&val)[N]);
template<typename T, unsigned N>
std::size_t hash_value(const T (&val)[N]);
template<typename Ch, typename A>
std::size_t hash_value(std::basic_string<Ch, std::char_traits<Ch>, A> const&);
template<typename A, typename B>
std::size_t hash_value(std::pair<A, B> const&);
template<typename T, typename A>
std::size_t hash_value(std::vector<T, A> const&);
template<typename T, typename A>
std::size_t hash_value(std::list<T, A> const&);
template<typename T, typename A>
std::size_t hash_value(std::deque<T, A> const&);
template<typename K, typename C, typename A>
std::size_t hash_value(std::set<K, C, A> const&);
template<typename K, typename C, typename A>
std::size_t hash_value(std::multiset<K, C, A> const&);
template<typename K, typename T, typename C, typename A>
std::size_t hash_value(std::map<K, T, C, A> const&);
template<typename K, typename T, typename C, typename A>
std::size_t hash_value(std::multimap<K, T, C, A> const&);
template<typename T> std::size_t hash_value(std::complex<T> const&);
std::size_t hash_value(std::type_index);
template<typename T, std::size_t N>
std::size_t hash_value(std::array<T, N> const&);
template<typename... T>
std::size_t hash_value(std::tuple<T...>);
}
----
== Struct template hash
=== hash
`boost::hash` — A http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf[TR1] compliant hash function object.
==== Synopsis
[source]
----
// #include <boost/container_hash/hash.hpp>
template<typename T>
struct hash : public std::unary_function<T, std::size_t> {
std::size_t operator()(T const&) const;
};
----
==== Description
[source]
----
std::size_t operator()(T const& val) const;
----
[horizontal]
Returns:: `hash_value(val)`
Notes:: The call to `hash_value` is unqualified, so that custom overloads can be found via argument dependent lookup.
+
This is not defined when the macro `BOOST_HASH_NO_EXTENSIONS` is defined. The specializations are still defined, so only the specializations required by TR1 are defined.
+
Forward declared in `<boost/container_hash/hash_fwd.hpp>`
+
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.
Throws:: Only throws if `hash_value(T)` throws.
== Specializations
`boost::hash<T>`
=== Synopsis
[source]
----
// #include <boost/container_hash/hash.hpp>
struct hash<T> {
std::size_t operator()(T const&) const;
};
----
=== Description
[source]
----
std::size_t operator()(T const val) const;
----
[horizontal]
Returns:: Unspecified in TR1, except that equal arguments yield the same result.
+
`hash_value(val)` in Boost.
[horizontal]
Throws:: Doesn't throw
== Support functions (Boost extension).
=== hash_combine
[source]
----
template<typename T>
void hash_combine(size_t &, T const&);
----
Called repeatedly to incrementally create a hash value from several variables.
[horizontal]
Effects:: Updates seed with a new hash value generated by combining it with the result of `hash_value(v)`. Will always produce the same result for the same combination of seed and `hash_value(v)` during the single run of a program.
[horizontal]
Notes:: `hash_value` is called without qualification, so that overloads can be found via ADL. +
+
This is an extension to TR1 +
+
Forward declared in `<boost/container_hash/hash_fwd.hpp>` +
+
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.
[horizontal]
Throws:: Only throws if `hash_value(T)` throws. Strong exception safety, as long as `hash_value(T)` also has strong exception safety.
=== hash_range
[source]
----
template<typename It>
std::size_t hash_range(It, It);
template<typename It>
void hash_range(std::size_t&, It, It);
----
Calculate the combined hash value of the elements of an iterator range.
[horizontal]
Effects:: For the two argument overload:
+
[source]
----
size_t seed = 0;
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
return seed;
----
+
For the three arguments overload:
+
[source]
----
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
----
[horizontal]
Notes:: `hash_range` is sensitive to the order of the elements so it wouldn't be appropriate to use this with an unordered container.
+
This is an extension to TR1
+
Forward declared in `<boost/container_hash/hash_fwd.hpp>`
+
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.
[horizontal]
Throws:: Only throws if `hash_value(std::iterator_traits<It>::value_type)` throws. `hash_range(std::size_t&, It, It)` has basic exception safety as long as `hash_value(std::iterator_traits<It>::value_type)` has basic exception safety.
== Overloadable hash implementation (Boost extension).
=== hash_value
[source]
----
std::size_t hash_value(bool val);
std::size_t hash_value(char val);
std::size_t hash_value(signed char val);
std::size_t hash_value(unsigned char val);
std::size_t hash_value(wchar_t val);
std::size_t hash_value(char16_t val);
std::size_t hash_value(char32_t val);
std::size_t hash_value(short val);
std::size_t hash_value(unsigned short val);
std::size_t hash_value(int val);
std::size_t hash_value(unsigned int val);
std::size_t hash_value(long val);
std::size_t hash_value(unsigned long val);
std::size_t hash_value(long long val);
std::size_t hash_value(unsigned long long val);
std::size_t hash_value(float val);
std::size_t hash_value(double val);
std::size_t hash_value(long double val);
template<typename T> std::size_t hash_value(T* const& val);
template<typename T, unsigned N> std::size_t hash_value(T (&val)[N]);
template<typename T, unsigned N> std::size_t hash_value(const T (&val)[N]);
template<typename Ch, typename A>
std::size_t hash_value(std::basic_string<Ch, std::char_traits<Ch>, A> const& val);
template<typename A, typename B>
std::size_t hash_value(std::pair<A, B> const& val);
template<typename T, typename A>
std::size_t hash_value(std::vector<T, A> const& val);
template<typename T, typename A>
std::size_t hash_value(std::list<T, A> const& val);
template<typename T, typename A>
std::size_t hash_value(std::deque<T, A> const& val);
template<typename K, typename C, typename A>
std::size_t hash_value(std::set<K, C, A> const& val);
template<typename K, typename C, typename A>
std::size_t hash_value(std::multiset<K, C, A> const& val);
template<typename K, typename T, typename C, typename A>
std::size_t hash_value(std::map<K, T, C, A> const& val);
template<typename K, typename T, typename C, typename A>
std::size_t hash_value(std::multimap<K, T, C, A> const& val);
template<typename T> std::size_t hash_value(std::complex<T> const& val);
std::size_t hash_value(std::type_index val);
template<typename T, std::size_t N>
std::size_t hash_value(std::array<T, N> const& val);
template<typename... T>
std::size_t hash_value(std::tuple<T...> val);
----
Implementation of the hash function.
Generally shouldn't be called directly by users, instead they should use `boost::hash`, `boost::hash_range` or `boost::hash_combine` which call `hash_value` without namespace qualification so that overloads for custom types are found via ADL.
[horizontal]
Notes:: This is an extension to TR1
+
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.
[horizontal]
Throws:: Only throws if a user supplied version of `hash_value` throws for an element of a container, or one of the types stored in a pair.
[vertical]
Returns::
+
[cols="1,1", frame=all, grid=rows]
|===
|Types |Returns
|`bool`, `char`, `signed char`, `unsigned char`, `wchar_t`, `char16_t`, `char32_t`, `short`, `unsigned short`, `int`, `unsigned int`, `long`, `unsigned long`
|val
|`long long`, `unsigned long long`
|val when `abs(val) \<= std::numeric_limits<std::size_t>::max()`.
|`float`, `double`, `long double`
|An unspecified value, except that equal arguments shall yield the same result.
|`T*`
|An unspecified value, except that equal arguments shall yield the same result.
|`T val[N]`, `const T val[N]`
|`hash_range(val, val+N)`
|`std:basic_string<Ch, std::char_traits<Ch>, A>`, `std::vector<T, A>`, `std::list<T, A>`, `std::deque<T, A>`, `std::set<K, C, A>`, `std::multiset<K, C, A>`, `std::map<K, T, C, A>`, `std::multimap<K, T, C, A>`, `std::array<T, N>`
|`hash_range(val.begin(), val.end())`
|`std::pair<A, B>`
a|
[source]
----
size_t seed = 0;
hash_combine(seed, val.first);
hash_combine(seed, val.second);
return seed;
----
|`std::tuple<T...>`
a|
[source]
----
size_t seed = 0;
hash_combine(seed, get<0>(val));
hash_combine(seed, get<1>(val));
// ....
return seed;
----
|`std::complex<T>`
|When T is a built in type and `val.imag() == 0`, the result is equal to `hash_value(val.real())`. Otherwise an unspecified value, except that equal arguments shall yield the same result.
|`std::type_index`
|`val.hash_code()`
|===
+14
View File
@@ -0,0 +1,14 @@
[#thanks]
= Acknowledgements
:idprefix: thanks_
This library is based on the design by Peter Dimov. During the initial development Joaquín M López Muñoz made many useful suggestions and contributed fixes.
The formal review was managed by Thorsten Ottosen, and the library reviewed by: David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris, Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter, Rob Stewart and Pavel Vozenilek. Since then, further constructive criticism has been made by Daniel Krügler, Alexander Nasonov and 沈慧峰.
The implementation of the hash function for pointers is based on suggestions made by Alberto Barbati and Dave Harris. Dave Harris also suggested an important improvement to `boost::hash_combine` that was taken up.
Some useful improvements to the floating point hash algorithm were suggested by Daniel Krügler.
The original implementation came from Jeremy B. Maitin-Shepard's hash table library, although this is a complete rewrite.
+48
View File
@@ -0,0 +1,48 @@
[#tutorial]
= Tutorial
:idprefix: tutorial_
When using a hash index with link:../../../multi_index/index.html[Boost.MultiIndex], you don't need to do anything to use `boost::hash` as it uses it by default. To find out how to use a user-defined type, read the <<custom,section on extending boost::hash for a custom data type>>.
If your standard library supplies its own implementation of the unordered associative containers and you wish to use `boost::hash`, just use an extra template parameter:
[source]
----
std::unordered_multiset<int, boost::hash<int> >
set_of_ints;
std::unordered_set<std::pair<int, int>, boost::hash<std::pair<int, int> > >
set_of_pairs;
std::unordered_map<int, std::string, boost::hash<int> > map_int_to_string;
----
To use `boost::hash` directly, create an instance and call it as a function:
[source]
----
#include <boost/container_hash/hash.hpp>
int main()
{
boost::hash<std::string> string_hash;
std::size_t h = string_hash("Hash me");
}
----
For an example of generic use, here is a function to generate a vector containing the hashes of the elements of a container:
[source]
----
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;
}
----
-48
View File
@@ -1,48 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:intro Introduction]
[def __tr1-full__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
Draft Technical Report on C++ Library Extensions]]
[def __tr1__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
TR1]]
[def __unordered__ [link unordered Boost.Unordered]]
[def __intrusive__ [link intrusive.unordered_set_unordered_multiset Boost.Intrusive]]
[def __multi-index__ [@boost:/libs/multi_index/doc/index.html
Boost Multi-Index Containers Library]]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[def __bimap__ [@boost:/libs/bimap/index.html Boost.Bimap]]
[def __issues__
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf
Library Extension Technical Report Issues List]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function hash function]]
[def __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table hash table]]
[classref boost::hash] is an implementation of the __hash-function__ object
specified by the __tr1-full__ (TR1). It is the default hash function for
__unordered__, __intrusive__'s unordered associative containers, and
__multi-index-short__'s hash indicies and __bimap__'s `unordered_set_of`.
As it is compliant with __tr1__, it will work with:
* integers
* floats
* pointers
* strings
It also implements the extension proposed by Peter Dimov in issue 6.18 of the
__issues__ (page 63), this adds support for:
* arrays
* `std::pair`
* the standard containers.
* extending [classref boost::hash] for custom types.
[endsect]
-27
View File
@@ -1,27 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:links Links]
[*A Proposal to Add Hash Tables to the Standard Library]
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html]
The hash table proposal explains much of the design. The hash function object
is discussed in Section D.
[*The C++ Standard Library Technical Report.]
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf]
Contains the hash function specification in section 6.3.2.
[*Library Extension Technical Report Issues List.]
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf]
The library implements the extension described in Issue 6.18, pages 63-67.
[*Methods for Identifying Versioned and Plagiarised Documents]
Timothy C. Hoad, Justin Zobel
[@http://www.cs.rmit.edu.au/~jz/fulltext/jasist-tch.pdf]
Contains the hash function that [funcref boost::hash_combine] is based on.
[endsect]
-105
View File
@@ -1,105 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:portability Portability]
[def __boost_hash__ [classref boost::hash]]
__boost_hash__ is written to be as portable as possible, but unfortunately, several
older compilers don't support argument dependent lookup (ADL) - the mechanism
used for customisation. On those compilers custom overloads for `hash_value`
needs to be declared in the boost namespace.
On a strictly standards compliant compiler, an overload defined in the
boost namespace won't be found when __boost_hash__ is instantiated,
so for these compilers the overload should only be declared in the same
namespace as the class.
Let's say we have a simple custom type:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
friend std::size_t hash_value(custom_type x)
{
__boost_hash__<int> hasher;
return hasher(x.value);
}
};
}
On a compliant compiler, when `hash_value` is called for this type,
it will look at the namespace inside the type and find `hash_value`
but on a compiler which doesn't support ADL `hash_value` won't be found.
To make things worse, some compilers which do support ADL won't find
a friend class defined inside the class.
So first move the member function out of the class:
namespace foo
{
template <class T>
class custom_type
{
T value;
public:
custom_type(T x) : value(x) {}
std::size_t hash(custom_type x)
{
__boost_hash__<T> hasher;
return hasher(value);
}
};
template <class T>
inline std::size_t hash_value(custom_type<T> x)
{
return x.hash();
}
}
Unfortunately, I couldn't declare hash_value as a friend, as some compilers
don't support template friends, so instead I declared a member function to
calculate the hash, and called it from hash_value.
For compilers which don't support ADL, hash_value needs to be defined in the
boost namespace:
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace foo
#endif
{
template <class T>
std::size_t hash_value(foo::custom_type<T> x)
{
return x.hash();
}
}
Full code for this example is at
[@boost:/libs/functional/hash/examples/portable.cpp /libs/functional/hash/examples/portable.cpp].
[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]
-810
View File
@@ -1,810 +0,0 @@
<!--
Copyright Daniel James 2005-2009
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->
<library-reference>
<section id="hash.reference.specification">
<para>For the full specification, see section 6.3 of the
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C++ Standard Library Technical Report</ulink>
and issue 6.18 of the
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1837.pdf">Library Extension Technical Report Issues List</ulink> (page 63).
</para>
</section>
<header name="boost/functional/hash.hpp">
<para>
Defines <code><classname>boost::hash</classname></code>,
and helper functions.
</para>
<namespace name="boost">
<!--
boost::hash
-->
<struct name="hash">
<template>
<template-type-parameter name="T"/>
</template>
<inherit access="public">
<classname>std::unary_function&lt;T, std::size_t&gt;</classname>
</inherit>
<purpose><simpara>A <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">TR1</ulink> compliant hash function object.</simpara></purpose>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>T const&amp;</paramtype>
</parameter>
<returns><para>
<programlisting><functionname>hash_value</functionname>(val)</programlisting>
</para></returns>
<notes>
<para>
The call to <code><functionname>hash_value</functionname></code>
is unqualified, so that custom overloads can be
found via argument dependent lookup.
</para>
<para>
This is not defined when the macro <code>BOOST_HASH_NO_EXTENSIONS</code>
is defined. The specializations are still defined, so only the specializations
required by TR1 are defined.
</para>
</notes>
<throws><para>
Only throws if
<code><functionname>hash_value</functionname>(T)</code> throws.
</para></throws>
</method>
</struct>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>bool</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>bool</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>char</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>signed char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>signed char</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned char</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned char</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>wchar_t</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>wchar_t</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>short</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>short</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned short</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned short</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>int</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>int</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned int</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned int</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>long long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>long long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>unsigned long long</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>unsigned long long</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>float</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>float</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>double</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>double</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>long double</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>long double</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::string</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::string const&amp;</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template></template>
<specialization>
<template-arg>std::wstring</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::wstring const&amp;</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
<para><functionname>hash_value</functionname>(val) in Boost.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<struct-specialization name="hash">
<template>
<template-type-parameter name="T"/>
</template>
<specialization>
<template-arg>T*</template-arg>
</specialization>
<method name="operator()" cv="const">
<type>std::size_t</type>
<parameter name="val">
<paramtype>T*</paramtype>
</parameter>
<returns>
<para>Unspecified in TR1, except that equal arguments yield the same result.</para>
</returns>
<throws><para>Doesn't throw</para></throws>
</method>
</struct-specialization>
<free-function-group name="Support functions (Boost extension).">
<!--
boost::hash_combine
-->
<function name="hash_combine">
<template>
<template-type-parameter name="T"/>
</template>
<type>void</type>
<parameter name="seed"><paramtype>size_t &amp;</paramtype></parameter>
<parameter name="v"><paramtype>T const&amp;</paramtype></parameter>
<purpose><simpara>
Called repeatedly to incrementally create a hash value from
several variables.
</simpara></purpose>
<effects><programlisting>seed ^= <functionname>hash_value</functionname>(v) + 0x9e3779b9 + (seed &lt;&lt; 6) + (seed &gt;&gt; 2);</programlisting></effects>
<notes>
<para><functionname>hash_value</functionname> is called without
qualification, so that overloads can be found via ADL.</para>
<para>This is an extension to TR1</para>
</notes>
<throws>
Only throws if <functionname>hash_value</functionname>(T) throws.
Strong exception safety, as long as <functionname>hash_value</functionname>(T)
also has strong exception safety.
</throws>
</function>
<!--
boost::hash_range
-->
<overloaded-function name="hash_range">
<signature>
<template>
<template-type-parameter name="It"/>
</template>
<type>std::size_t</type>
<parameter name="first"><paramtype>It</paramtype></parameter>
<parameter name="last"><paramtype>It</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="It"/>
</template>
<type>void</type>
<parameter name="seed"><paramtype>std::size_t&amp;</paramtype></parameter>
<parameter name="first"><paramtype>It</paramtype></parameter>
<parameter name="last"><paramtype>It</paramtype></parameter>
</signature>
<purpose><simpara>
Calculate the combined hash value of the elements of an iterator
range.
</simpara></purpose>
<effects>
<para>For the two argument overload:
<programlisting>
size_t seed = 0;
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
return seed;
</programlisting>
</para>For the three arguments overload:
<programlisting>
for(; first != last; ++first)
{
<functionname>hash_combine</functionname>(seed, *first);
}
</programlisting>
<para>
</para>
</effects>
<notes>
<para>
<code>hash_range</code> is sensitive to the order of the elements
so it wouldn't be appropriate to use this with an unordered
container.
</para>
<para>This is an extension to TR1</para>
</notes>
<throws><para>
Only throws if <code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
throws. <code>hash_range(std::size_t&amp;, It, It)</code> has basic exception safety as long as
<code><functionname>hash_value</functionname>(std::iterator_traits&lt;It&gt;::value_type)</code>
has basic exception safety.
</para></throws>
</overloaded-function>
</free-function-group>
<free-function-group name="Overloadable hash implementation (Boost extension).">
<!--
boost::hash_value - integers
-->
<overloaded-function name="hash_value">
<purpose><simpara>
Implementation of the hash function.
</simpara></purpose>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>bool</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>signed char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned char</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>wchar_t</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>short</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned short</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>int</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned int</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>unsigned long long</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>float</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>double</paramtype></parameter>
</signature>
<signature>
<type>std::size_t</type>
<parameter name="val"><paramtype>long double</paramtype></parameter>
</signature>
<signature>
<template><template-type-parameter name="T"/></template>
<type>std::size_t</type>
<parameter name="val"><paramtype>T* const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter><paramtype>T (&amp;val)[N]</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-nontype-parameter name="N"><type>unsigned</type></template-nontype-parameter>
</template>
<type>std::size_t</type>
<parameter><paramtype>const T (&amp;val)[N]</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="Ch"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val">
<paramtype>std::basic_string&lt;Ch, std::char_traits&lt;Ch&gt;, A&gt; const&amp;</paramtype>
</parameter>
</signature>
<signature>
<template>
<template-type-parameter name="A"/>
<template-type-parameter name="B"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::pair&lt;A, B&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::vector&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::list&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::deque&lt;T, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::set&lt;K, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::multiset&lt;K, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="T"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::map&lt;K, T, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="K"/>
<template-type-parameter name="T"/>
<template-type-parameter name="C"/>
<template-type-parameter name="A"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::multimap&lt;K, T, C, A&gt; const&amp;</paramtype></parameter>
</signature>
<signature>
<template>
<template-type-parameter name="T"/>
</template>
<type>std::size_t</type>
<parameter name="val"><paramtype>std::complex&lt;T&gt; const&amp;</paramtype></parameter>
</signature>
<description><para>
Generally shouldn't be called directly by users, instead they should use
<classname>boost::hash</classname>, <functionname>boost::hash_range</functionname>
or <functionname>boost::hash_combine</functionname> which
call <code>hash_value</code> without namespace qualification so that overloads
for custom types are found via ADL.
</para></description>
<notes>
<para>This is an extension to TR1</para>
</notes>
<throws>
Only throws if a user supplied version of
<code><functionname>hash_value</functionname></code>
throws for an element of a container, or
one of the types stored in a pair.
</throws>
<returns>
<informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Types</entry>
<entry>Returns</entry>
</row>
</thead>
<tbody>
<row>
<entry><code>bool</code>,
<code>char</code>, <code>signed char</code>, <code>unsigned char</code>, <code>wchar_t</code>,
<code>short</code>, <code>unsigned short</code>,
<code>int</code>, <code>unsigned int</code>, <code>long</code>, <code>unsigned long</code>
</entry>
<entry><code>val</code></entry>
</row>
<row>
<entry><code>long long</code>, <code>unsigned long long</code></entry>
<entry><code>val</code> when <code>abs(val) &lt;= std::numeric_limits&lt;std::size_t&gt;::max()</code>.</entry>
</row>
<row>
<entry><code>float</code>, <code>double</code>, <code>long double</code></entry>
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry><code>T*</code></entry>
<entry>An unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
<row>
<entry>
<code>T&#160;val[N]</code>,
<code>const&#160;T&#160;val[N]</code>
</entry>
<entry><code>hash_range(val, val+N)</code></entry>
</row>
<row>
<entry>
<code>std:basic_string&lt;Ch,&#160;std::char_traits&lt;Ch&gt;,&#160;A&gt;</code>,
<code>std::vector&lt;T,&#160;A&gt;</code>,
<code>std::list&lt;T,&#160;A&gt;</code>,
<code>std::deque&lt;T,&#160;A&gt;</code>,
<code>std::set&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::multiset&lt;K,&#160;C,&#160;A&gt;</code>,
<code>std::map&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>,
<code>std::multimap&lt;K,&#160;T,&#160;C,&#160;A&gt;</code>
</entry>
<entry><code>hash_range(val.begin(), val.end())</code></entry>
</row>
<row>
<entry><code>std::pair&lt;A, B&gt;</code></entry>
<entry><programlisting>size_t seed = 0;
<functionname>hash_combine</functionname>(seed, val.first);
<functionname>hash_combine</functionname>(seed, val.second);
return seed;</programlisting></entry>
</row>
<row>
<entry>
<code>std::complex&lt;T&gt;</code>
</entry>
<entry>When <code>T</code> is a built in type and <code>val.imag() == 0</code>, the result is equal to <code>hash_value(val.real())</code>. Otherwise an unspecified value, except that equal arguments shall yield the same result.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</returns>
</overloaded-function>
</free-function-group>
</namespace>
</header>
</library-reference>
-28
View File
@@ -1,28 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:acknowledgements Acknowledgements]
This library is based on the design by Peter Dimov. During the initial
development
Joaquín M López Muñoz made many useful suggestions and contributed fixes.
The formal review was managed by Thorsten Ottosen, and the library reviewed by:
David Abrahams, Alberto Barbati, Topher Cooper, Caleb Epstein, Dave Harris,
Chris Jefferson, Bronek Kozicki, John Maddock, Tobias Swinger, Jaap Suter,
Rob Stewart and Pavel Vozenilek. Since then, further constructive criticism has
been made by Daniel Krügler, Alexander Nasonov and 沈慧峰.
The implementation of the hash function for pointers is based on suggestions
made by Alberto Barbati and Dave Harris. Dave Harris also suggested an
important improvement to [funcref boost::hash_combine] that was taken up.
Some useful improvements to the floating point hash algorithm were suggested
by Daniel Krügler.
The original implementation came from Jeremy B. Maitin-Shepard's hash table
library, although this is a complete rewrite.
[endsect]
-202
View File
@@ -1,202 +0,0 @@
[/ Copyright 2005-2008 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[def __multi-index-short__ [@boost:/libs/multi_index/doc/index.html
Boost.MultiIndex]]
[section:tutorial Tutorial]
When using a hash index with __multi-index-short__, you don't need to do
anything to use [classref boost::hash] as it uses it by default.
To find out how to use a user-defined type, read the
[link hash.custom section on extending boost::hash for a custom data type].
If your standard library supplies its own implementation of the unordered
associative containers and you wish to use
[classref boost::hash], just use an extra template parameter:
std::unordered_multiset<int, ``[classref boost::hash]``<int> >
set_of_ints;
std::unordered_set<std::pair<int, int>, ``[classref boost::hash]``<std::pair<int, int> >
set_of_pairs;
std::unordered_map<int, std::string, ``[classref boost::hash]``<int> > map_int_to_string;
To use [classref boost::hash] directly, create an instance and call it as a function:
#include <``[headerref boost/functional/hash.hpp]``>
int main()
{
``[classref boost::hash]``<std::string> string_hash;
std::size_t h = string_hash("Hash me");
}
For an example of generic use, here is a function to generate a vector
containing the hashes of the elements of a container:
template <class Container>
std::vector<std::size_t> get_hashes(Container const& x)
{
std::vector<std::size_t> hashes;
std::transform(x.begin(), x.end(), std::insert_iterator(hashes),
``[classref boost::hash]``<typename Container::value_type>());
return hashes;
}
[endsect]
[section:custom Extending boost::hash for a custom data type]
[classref boost::hash] is implemented by calling the function
[funcref boost::hash_value hash_value].
The namespace isn't specified so that it can detect overloads via argument
dependant lookup. So if there is a free function `hash_value` in the same
namespace as a custom type, it will get called.
If you have a structure `library::book`, where each `book` is uniquely
defined by it's member `id`:
namespace library
{
struct book
{
int id;
std::string author;
std::string title;
// ....
};
bool operator==(book const& a, book const& b)
{
return a.id == b.id;
}
}
Then all you would need to do is write the function `library::hash_value`:
namespace library
{
std::size_t hash_value(book const& b)
{
``[classref boost::hash]``<int> hasher;
return hasher(b.id);
}
}
And you can now use [classref boost::hash] with book:
library::book knife(3458, "Zane Grey", "The Hash Knife Outfit");
library::book dandelion(1354, "Paul J. Shanley",
"Hash & Dandelion Greens");
``[classref boost::hash]``<library::book> book_hasher;
std::size_t knife_hash_value = book_hasher(knife);
// If std::unordered_set is available:
std::unordered_set<library::book, ``[classref boost::hash]``<library::book> > books;
books.insert(knife);
books.insert(library::book(2443, "Lindgren, Torgny", "Hash"));
books.insert(library::book(1953, "Snyder, Bernadette M.",
"Heavenly Hash: A Tasty Mix of a Mother's Meditations"));
assert(books.find(knife) != books.end());
assert(books.find(dandelion) == books.end());
The full example can be found in:
[@boost:/libs/functional/hash/examples/books.hpp /libs/functional/hash/examples/books.hpp]
and
[@boost:/libs/functional/hash/examples/books.cpp /libs/functional/hash/examples/books.cpp].
[tip
When writing a hash function, first look at how the equality function works.
Objects that are equal must generate the same hash value.
When objects are not equal they should generate different hash values.
In this object equality was based just on the id so the hash function
only hashes the id. If it was based on the object's name and author
then the hash function should take them into account
(how to do this is discussed in the next section).
]
[endsect]
[section:combine Combining hash values]
Say you have a point class, representing a two dimensional location:
class point
{
int x;
int y;
public:
point() : x(0), y(0) {}
point(int x, int y) : x(x), y(y) {}
bool operator==(point const& other) const
{
return x == other.x && y == other.y;
}
};
and you wish to use it as the key for an `unordered_map`. You need to
customise the hash for this structure. To do this we need to combine
the hash values for `x` and `y`. The function
[funcref boost::hash_combine] is supplied for this purpose:
class point
{
...
friend std::size_t hash_value(point const& p)
{
std::size_t seed = 0;
``[funcref boost::hash_combine]``(seed, p.x);
``[funcref boost::hash_combine]``(seed, p.y);
return seed;
}
...
};
Calls to hash_combine incrementally build the hash from the different members
of point, it can be repeatedly called for any number of elements. It calls
[funcref boost::hash_value hash_value] on the supplied element, and combines it with the seed.
Full code for this example is at
[@boost:/libs/functional/hash/examples/point.cpp /libs/functional/hash/examples/point.cpp].
[note
When using [funcref boost::hash_combine] the order of the
calls matters.
'''
<programlisting>
std::size_t seed = 0;
boost::hash_combine(seed, 1);
boost::hash_combine(seed, 2);
</programlisting>
results in a different seed to:
<programlisting>
std::size_t seed = 0;
boost::hash_combine(seed, 2);
boost::hash_combine(seed, 1);
</programlisting>
'''
If you are calculating a hash value for data where the order of the data
doesn't matter in comparisons (e.g. a set) you will have to ensure that the
data is always supplied in the same order.
]
To calculate the hash of an iterator range you can use [funcref boost::hash_range]:
std::vector<std::string> some_strings;
std::size_t hash = ``[funcref boost::hash_range]``(some_strings.begin(), some_strings.end());
[endsect]
+1
View File
@@ -6,3 +6,4 @@
run books.cpp ;
run point.cpp ;
run portable.cpp ;
run template.cpp : : : <toolset>msvc-8.0:<build>no ;
+1 -1
View File
@@ -4,7 +4,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./books.hpp"
#include <boost/functional/hash.hpp>
#include <boost/container_hash/hash.hpp>
#include <cassert>
// 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
// 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>
// 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
// 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>
// 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;
}
};
@@ -0,0 +1,133 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
#include <boost/container_hash/hash_fwd.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/config.hpp>
#if defined(BOOST_NO_CXX11_HDR_TUPLE)
// no support
#else
#include <tuple>
namespace boost
{
namespace hash_detail
{
template <std::size_t I, typename T>
inline typename boost::enable_if_<(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_<(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;
}
} // namespace hash_detail
#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 // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
} // namespace boost
#endif // #if defined(BOOST_NO_CXX11_HDR_TUPLE)
#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
@@ -0,0 +1,81 @@
// Copyright 2017, 2018 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_HASH_DETAIL_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
#define BOOST_HASH_DETAIL_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
#include <boost/type_traits/integral_constant.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 40700)
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iterator>
namespace boost
{
namespace hash_detail
{
template<class It, class T, class S>
integral_constant< bool, is_same<typename std::iterator_traits<It>::value_type, T>::value && is_integral<S>::value >
is_contiguous_range_check( It first, It last, T const*, T const*, S );
template<class T> decltype( is_contiguous_range_check( declval<T const&>().begin(), declval<T const&>().end(), declval<T const&>().data(), declval<T const&>().data() + declval<T const&>().size(), declval<T const&>().size() ) ) is_contiguous_range_( int );
template<class T> false_type is_contiguous_range_( ... );
template<class T> struct is_contiguous_range: decltype( hash_detail::is_contiguous_range_<T>( 0 ) )
{
};
} // namespace hash_detail
} // namespace boost
#else // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
#include <cstddef>
#include <vector>
#include <string>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
#include <array>
#endif
namespace boost
{
namespace hash_detail
{
template<class T> struct is_contiguous_range: false_type
{
};
template<class E, class T, class A> struct is_contiguous_range< std::basic_string<E, T, A> >: true_type
{
};
template<class E, class T, class A> struct is_contiguous_range< std::basic_string<E, T, A> const >: true_type
{
};
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
template<class T, std::size_t N> struct is_contiguous_range< std::array<T, N> >: true_type
{
};
template<class T, std::size_t N> struct is_contiguous_range< std::array<T, N> const >: true_type
{
};
#endif
} // namespace hash_detail
} // namespace boost
#endif // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
#endif // #ifndef BOOST_HASH_DETAIL_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
@@ -0,0 +1,57 @@
// Copyright 2017 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_HASH_DETAIL_IS_RANGE_HPP_INCLUDED
#define BOOST_HASH_DETAIL_IS_RANGE_HPP_INCLUDED
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <iterator>
namespace boost
{
namespace hash_detail
{
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 40700)
template<class T, class It>
integral_constant< bool, !is_same<typename remove_cv<T>::type, typename std::iterator_traits<It>::value_type>::value >
is_range_check( It first, It last );
template<class T> decltype( is_range_check<T>( declval<T const&>().begin(), declval<T const&>().end() ) ) is_range_( int );
template<class T> false_type is_range_( ... );
template<class T> struct is_range: decltype( is_range_<T>( 0 ) )
{
};
#else
template<class T, class E = true_type> struct is_range_: false_type
{
};
template<class T> struct is_range_< T, integral_constant< bool,
is_same<typename T::value_type, typename std::iterator_traits<typename T::const_iterator>::value_type>::value &&
is_integral<typename T::size_type>::value
> >: true_type
{
};
template<class T> struct is_range: is_range_<T>
{
};
#endif // !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
} // namespace hash_detail
} // namespace boost
#endif // #ifndef BOOST_HASH_DETAIL_IS_RANGE_HPP_INCLUDED
@@ -0,0 +1,34 @@
// Copyright 2017 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_HASH_DETAIL_IS_UNORDERED_RANGE_HPP_INCLUDED
#define BOOST_HASH_DETAIL_IS_UNORDERED_RANGE_HPP_INCLUDED
#include <boost/container_hash/detail/is_range.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost
{
namespace hash_detail
{
template<class T, class E = true_type> struct has_hasher_: false_type
{
};
template<class T> struct has_hasher_< T, integral_constant< bool,
is_same<typename T::hasher, typename T::hasher>::value
> >: true_type
{
};
template<class T> struct is_unordered_range: integral_constant< bool, is_range<T>::value && has_hasher_<T>::value >
{
};
} // namespace hash_detail
} // namespace boost
#endif // #ifndef BOOST_HASH_DETAIL_IS_UNORDERED_RANGE_HPP_INCLUDED
@@ -0,0 +1,19 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#include <limits>
namespace boost
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
}
}
#endif // #ifndef BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
@@ -0,0 +1,10 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/container_hash/hash.hpp>
#endif // #ifndef BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
+693
View File
@@ -0,0 +1,693 @@
// Copyright 2005-2014 Daniel James.
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://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.
#ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/container_hash/hash_fwd.hpp>
#include <boost/container_hash/detail/is_range.hpp>
#include <boost/container_hash/detail/is_contiguous_range.hpp>
#include <boost/container_hash/detail/is_unordered_range.hpp>
#include <boost/container_hash/detail/hash_tuple.hpp>
#include <boost/type_traits/is_enum.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/conjunction.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include <iterator>
#include <complex>
#include <utility>
#include <limits>
#include <climits>
#include <cstring>
#if !defined(BOOST_NO_CXX11_SMART_PTR)
# include <memory>
#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_NO_CXX17_HDR_OPTIONAL)
#include <optional>
#endif
#if !defined(BOOST_NO_CXX17_HDR_VARIANT)
#include <variant>
#endif
#if defined(_MSC_VER)
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) _rotl(x,r)
#else
# define BOOST_FUNCTIONAL_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r))
#endif
namespace boost
{
//
// boost::hash_value
//
// integral types
namespace hash_detail
{
template<class T,
bool bigger_than_size_t = (sizeof(T) > sizeof(std::size_t)),
bool is_unsigned = boost::is_unsigned<T>::value,
std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT,
std::size_t type_bits = sizeof(T) * CHAR_BIT>
struct hash_integral_impl;
template<class T, bool is_unsigned, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl<T, false, is_unsigned, size_t_bits, type_bits>
{
static std::size_t fn( T v )
{
return static_cast<std::size_t>( v );
}
};
template<class T, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl<T, true, false, size_t_bits, type_bits>
{
static std::size_t fn( T v )
{
typedef typename boost::make_unsigned<T>::type U;
if( v >= 0 )
{
return hash_integral_impl<U>::fn( static_cast<U>( v ) );
}
else
{
return ~hash_integral_impl<U>::fn( static_cast<U>( ~static_cast<U>( v ) ) );
}
}
};
template<class T> struct hash_integral_impl<T, true, true, 32, 64>
{
static std::size_t fn( T v )
{
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( v >> 32 ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
template<class T> struct hash_integral_impl<T, true, true, 32, 128>
{
static std::size_t fn( T v )
{
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( v >> 96 ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( v >> 64 ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( v >> 32 ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
template<class T> struct hash_integral_impl<T, true, true, 64, 128>
{
static std::size_t fn( T v )
{
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( v >> 64 ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( v ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
} // namespace hash_detail
template <typename T>
typename boost::enable_if_<boost::is_integral<T>::value, std::size_t>::type
hash_value( T v )
{
return hash_detail::hash_integral_impl<T>::fn( v );
}
// enumeration types
template <typename T>
typename boost::enable_if_<boost::is_enum<T>::value, std::size_t>::type
hash_value( T v )
{
// This should in principle return the equivalent of
//
// boost::hash_value( to_underlying(v) );
//
// However, the C++03 implementation of underlying_type,
//
// conditional<is_signed<T>, make_signed<T>, make_unsigned<T>>::type::type
//
// generates a legitimate -Wconversion warning in is_signed,
// because -1 is not a valid enum value when all the enumerators
// are nonnegative.
//
// So the legacy implementation will have to do for now.
return static_cast<std::size_t>( v );
}
// floating point types
namespace hash_detail
{
template<class T,
std::size_t Bits = sizeof(T) * CHAR_BIT,
int Digits = std::numeric_limits<T>::digits,
std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT>
struct hash_float_impl;
// float
template<class T, int Digits, std::size_t size_t_bits> struct hash_float_impl<T, 32, Digits, size_t_bits>
{
static std::size_t fn( T v )
{
boost::uint32_t w;
std::memcpy( &w, &v, sizeof( v ) );
return w;
}
};
// double
template<class T, int Digits> struct hash_float_impl<T, 64, Digits, 64>
{
static std::size_t fn( T v )
{
boost::uint64_t w;
std::memcpy( &w, &v, sizeof( v ) );
return w;
}
};
template<class T, int Digits> struct hash_float_impl<T, 64, Digits, 32>
{
static std::size_t fn( T v )
{
boost::uint32_t w[ 2 ];
std::memcpy( &w, &v, sizeof( v ) );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
// 80 bit long double in 12 bytes
template<class T> struct hash_float_impl<T, 96, 64, 64>
{
static std::size_t fn( T v )
{
boost::uint64_t w[ 2 ] = {};
std::memcpy( &w, &v, 80 / CHAR_BIT );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
template<class T> struct hash_float_impl<T, 96, 64, 32>
{
static std::size_t fn( T v )
{
boost::uint32_t w[ 3 ] = {};
std::memcpy( &w, &v, 80 / CHAR_BIT );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[2] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
// 80 bit long double in 16 bytes
template<class T> struct hash_float_impl<T, 128, 64, 64>
{
static std::size_t fn( T v )
{
boost::uint64_t w[ 2 ] = {};
std::memcpy( &w, &v, 80 / CHAR_BIT );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
template<class T> struct hash_float_impl<T, 128, 64, 32>
{
static std::size_t fn( T v )
{
boost::uint32_t w[ 3 ] = {};
std::memcpy( &w, &v, 80 / CHAR_BIT );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[2] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
// 128 bit long double
template<class T, int Digits> struct hash_float_impl<T, 128, Digits, 64>
{
static std::size_t fn( T v )
{
boost::uint64_t w[ 2 ];
std::memcpy( &w, &v, sizeof( v ) );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
template<class T, int Digits> struct hash_float_impl<T, 128, Digits, 32>
{
static std::size_t fn( T v )
{
boost::uint32_t w[ 4 ];
std::memcpy( &w, &v, sizeof( v ) );
std::size_t seed = 0;
seed ^= static_cast<std::size_t>( w[0] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[1] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[2] ) + ( seed << 6 ) + ( seed >> 2 );
seed ^= static_cast<std::size_t>( w[3] ) + ( seed << 6 ) + ( seed >> 2 );
return seed;
}
};
} // namespace hash_detail
template <typename T>
typename boost::enable_if_<boost::is_floating_point<T>::value, std::size_t>::type
hash_value( T v )
{
return boost::hash_detail::hash_float_impl<T>::fn( v + 0 );
}
// pointer types
// `x + (x >> 3)` adjustment by Alberto Barbati and Dave Harris.
template <class T> std::size_t hash_value( T* const& v )
{
boost::uintptr_t x = reinterpret_cast<boost::uintptr_t>( v );
return boost::hash_value( x + (x >> 3) );
}
// array types
template<class T, std::size_t N>
inline std::size_t hash_value( T const (&x)[ N ] )
{
return boost::hash_range( x, x + N );
}
template<class T, std::size_t N>
inline std::size_t hash_value( T (&x)[ N ] )
{
return boost::hash_range( x, x + N );
}
// complex
template <class T>
std::size_t hash_value( std::complex<T> const& v )
{
std::size_t re = boost::hash<T>()( v.real() );
std::size_t im = boost::hash<T>()( v.imag() );
im ^= re + ( im << 6 ) + ( im >> 2 );
return im;
}
// pair
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;
}
// ranges (list, set, deque...)
template <typename T>
typename boost::enable_if_<hash_detail::is_range<T>::value && !hash_detail::is_contiguous_range<T>::value && !hash_detail::is_unordered_range<T>::value, std::size_t>::type
hash_value( T const& v )
{
return boost::hash_range( v.begin(), v.end() );
}
// contiguous ranges (string, vector, array)
template <typename T>
typename boost::enable_if_<hash_detail::is_contiguous_range<T>::value, std::size_t>::type
hash_value( T const& v )
{
return boost::hash_range( v.data(), v.data() + v.size() );
}
// unordered ranges (unordered_set, unordered_map)
template <typename T>
typename boost::enable_if_<hash_detail::is_unordered_range<T>::value, std::size_t>::type
hash_value( T const& v )
{
return boost::hash_unordered_range( v.begin(), v.end() );
}
#if defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION == 141 && BOOST_CXX_VERSION >= 201700L
// resolve ambiguity with unconstrained stdext::hash_value in <xhash> :-/
template<template<class...> class L, class... T>
typename boost::enable_if_<hash_detail::is_range<L<T...>>::value && !hash_detail::is_contiguous_range<L<T...>>::value && !hash_detail::is_unordered_range<L<T...>>::value, std::size_t>::type
hash_value( L<T...> const& v )
{
return boost::hash_range( v.begin(), v.end() );
}
// contiguous ranges (string, vector, array)
template<template<class...> class L, class... T>
typename boost::enable_if_<hash_detail::is_contiguous_range<L<T...>>::value, std::size_t>::type
hash_value( L<T...> const& v )
{
return boost::hash_range( v.data(), v.data() + v.size() );
}
template<template<class, std::size_t> class L, class T, std::size_t N>
typename boost::enable_if_<hash_detail::is_contiguous_range<L<T, N>>::value, std::size_t>::type
hash_value( L<T, N> const& v )
{
return boost::hash_range( v.data(), v.data() + v.size() );
}
// unordered ranges (unordered_set, unordered_map)
template<template<class...> class L, class... T>
typename boost::enable_if_<hash_detail::is_unordered_range<L<T...>>::value, std::size_t>::type
hash_value( L<T...> const& v )
{
return boost::hash_unordered_range( v.begin(), v.end() );
}
#endif
// std::unique_ptr, std::shared_ptr
#if !defined(BOOST_NO_CXX11_SMART_PTR)
template <typename T>
std::size_t hash_value( std::shared_ptr<T> const& x )
{
return boost::hash_value( x.get() );
}
template <typename T, typename Deleter>
std::size_t hash_value( std::unique_ptr<T, Deleter> const& x )
{
return boost::hash_value( x.get() );
}
#endif
// std::type_index
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
inline std::size_t hash_value( std::type_index const& v )
{
return v.hash_code();
}
#endif
// std::error_code, std::error_condition
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
inline std::size_t hash_value( std::error_code const& v )
{
std::size_t seed = 0;
boost::hash_combine( seed, v.value() );
boost::hash_combine( seed, &v.category() );
return seed;
}
inline std::size_t hash_value( std::error_condition const& v )
{
std::size_t seed = 0;
boost::hash_combine( seed, v.value() );
boost::hash_combine( seed, &v.category() );
return seed;
}
#endif
// std::optional
#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL)
template <typename T>
std::size_t hash_value( std::optional<T> const& v )
{
if( !v )
{
// Arbitray value for empty optional.
return 0x12345678;
}
else
{
return boost::hash<T>()(*v);
}
}
#endif
// std::variant
#if !defined(BOOST_NO_CXX17_HDR_VARIANT)
inline std::size_t hash_value( std::monostate )
{
return 0x87654321;
}
template <typename... Types>
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
//
// boost::hash_combine
//
namespace hash_detail
{
template<std::size_t Bits> struct hash_combine_impl
{
template <typename SizeT>
inline static SizeT fn(SizeT seed, SizeT value)
{
seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
template<> struct hash_combine_impl<32>
{
inline static boost::uint32_t fn(boost::uint32_t h1, boost::uint32_t k1)
{
const boost::uint32_t c1 = 0xcc9e2d51;
const boost::uint32_t c2 = 0x1b873593;
k1 *= c1;
k1 = BOOST_FUNCTIONAL_HASH_ROTL32(k1,15);
k1 *= c2;
h1 ^= k1;
h1 = BOOST_FUNCTIONAL_HASH_ROTL32(h1,13);
h1 = h1*5+0xe6546b64;
return h1;
}
};
template<> struct hash_combine_impl<64>
{
inline static boost::uint64_t fn(boost::uint64_t h, boost::uint64_t k)
{
const boost::uint64_t m = (boost::uint64_t(0xc6a4a793) << 32) + 0x5bd1e995;
const int r = 47;
k *= m;
k ^= k >> r;
k *= m;
h ^= k;
h *= m;
// Completely arbitrary number, to prevent 0's
// from hashing to 0.
h += 0xe6546b64;
return h;
}
};
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
{
boost::hash<T> hasher;
seed = boost::hash_detail::hash_combine_impl<sizeof(std::size_t) * CHAR_BIT>::fn(seed, hasher(v));
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
//
// boost::hash_range
//
template <class It>
inline std::size_t hash_range(It first, It last)
{
std::size_t seed = 0;
hash_range(seed, first, last);
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);
}
}
//
// boost::hash
//
template <class T> struct hash
{
typedef T argument_type;
typedef std::size_t result_type;
std::size_t operator()( T const& val ) const
{
return hash_value( val );
}
};
#if defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION == 141 && BOOST_CXX_VERSION >= 201700L
// msvc-14.1 has stdext::hash_value for basic_string in <xhash> :-/
template<class E, class T, class A> struct hash< std::basic_string<E, T, A> >
{
typedef std::basic_string<E, T, A> argument_type;
typedef std::size_t result_type;
std::size_t operator()( std::basic_string<E, T, A> const& val ) const
{
return boost::hash_value( val );
}
};
#endif
}
#undef BOOST_FUNCTIONAL_HASH_ROTL32
#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#include <cstddef>
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);
template <class It> std::size_t hash_unordered_range(It, It);
template <class It> void hash_unordered_range(std::size_t&, It, It);
}
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
@@ -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
// 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,246 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_DETAIL_FLOAT_FUNCTIONS_HPP
#include <boost/config.hpp>
#include <boost/config/no_tr1/cmath.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
// The C++ standard requires that the C float functions are overloarded
// for float, double and long double in the std namespace, but some of the older
// library implementations don't support this. On some that don't, the C99
// float functions (frexpf, frexpl, etc.) are available.
//
// The following tries to automatically detect which are available.
namespace boost {
namespace hash_detail {
// Returned by dummy versions of the float functions.
struct not_found {
// Implicitly convertible to float and long double in order to avoid
// a compile error when the dummy float functions are used.
inline operator float() const { return 0; }
inline operator long double() const { return 0; }
};
// A type for detecting the return type of functions.
template <typename T> struct is;
template <> struct is<float> { char x[10]; };
template <> struct is<double> { char x[20]; };
template <> struct is<long double> { char x[30]; };
template <> struct is<boost::hash_detail::not_found> { char x[40]; };
// Used to convert the return type of a function to a type for sizeof.
template <typename T> is<T> float_type(T);
// call_ldexp
//
// This will get specialized for float and long double
template <typename Float> struct call_ldexp
{
typedef double float_type;
inline double operator()(double a, int b) const
{
using namespace std;
return ldexp(a, b);
}
};
// call_frexp
//
// This will get specialized for float and long double
template <typename Float> struct call_frexp
{
typedef double float_type;
inline double operator()(double a, int* b) const
{
using namespace std;
return frexp(a, b);
}
};
}
}
// A namespace for dummy functions to detect when the actual function we want
// isn't available. ldexpl, ldexpf etc. might be added tby the macros below.
//
// AFAICT these have to be outside of the boost namespace, as if they're in
// the boost namespace they'll always be preferable to any other function
// (since the arguments are built in types, ADL can't be used).
namespace boost_hash_detect_float_functions {
template <class Float> boost::hash_detail::not_found ldexp(Float, int);
template <class Float> boost::hash_detail::not_found frexp(Float, int*);
}
// Macros for generating specializations of call_ldexp and call_frexp.
//
// check_cpp and check_c99 check if the C++ or C99 functions are available.
//
// Then the call_* functions select an appropriate implementation.
//
// I used c99_func in a few places just to get a unique name.
//
// Important: when using 'using namespace' at namespace level, include as
// little as possible in that namespace, as Visual C++ has an odd bug which
// can cause the namespace to be imported at the global level. This seems to
// happen mainly when there's a template in the same namesapce.
#define BOOST_HASH_CALL_FLOAT_FUNC(cpp_func, c99_func, type1, type2) \
namespace boost_hash_detect_float_functions { \
template <class Float> \
boost::hash_detail::not_found c99_func(Float, type2); \
} \
\
namespace boost { \
namespace hash_detail { \
namespace c99_func##_detect { \
using namespace std; \
using namespace boost_hash_detect_float_functions; \
\
struct check { \
static type1 x; \
static type2 y; \
BOOST_STATIC_CONSTANT(bool, cpp = \
sizeof(float_type(cpp_func(x,y))) \
== sizeof(is<type1>)); \
BOOST_STATIC_CONSTANT(bool, c99 = \
sizeof(float_type(c99_func(x,y))) \
== sizeof(is<type1>)); \
}; \
} \
\
template <bool x> \
struct call_c99_##c99_func : \
boost::hash_detail::call_##cpp_func<double> {}; \
\
template <> \
struct call_c99_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return c99_func(a, b); \
} \
}; \
\
template <bool x> \
struct call_cpp_##c99_func : \
call_c99_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::c99 \
> {}; \
\
template <> \
struct call_cpp_##c99_func<true> { \
typedef type1 float_type; \
\
template <typename T> \
inline type1 operator()(type1 a, T b) const \
{ \
using namespace std; \
return cpp_func(a, b); \
} \
}; \
\
template <> \
struct call_##cpp_func<type1> : \
call_cpp_##c99_func< \
::boost::hash_detail::c99_func##_detect::check::cpp \
> {}; \
} \
}
#define BOOST_HASH_CALL_FLOAT_MACRO(cpp_func, c99_func, type1, type2) \
namespace boost { \
namespace hash_detail { \
\
template <> \
struct call_##cpp_func<type1> { \
typedef type1 float_type; \
inline type1 operator()(type1 x, type2 y) const { \
return c99_func(x, y); \
} \
}; \
} \
}
#if defined(ldexpf)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpf, float, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpf, float, int)
#endif
#if defined(ldexpl)
BOOST_HASH_CALL_FLOAT_MACRO(ldexp, ldexpl, long double, int)
#else
BOOST_HASH_CALL_FLOAT_FUNC(ldexp, ldexpl, long double, int)
#endif
#if defined(frexpf)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpf, float, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpf, float, int*)
#endif
#if defined(frexpl)
BOOST_HASH_CALL_FLOAT_MACRO(frexp, frexpl, long double, int*)
#else
BOOST_HASH_CALL_FLOAT_FUNC(frexp, frexpl, long double, int*)
#endif
#undef BOOST_HASH_CALL_FLOAT_MACRO
#undef BOOST_HASH_CALL_FLOAT_FUNC
namespace boost
{
namespace hash_detail
{
template <typename Float1, typename Float2>
struct select_hash_type_impl {
typedef double type;
};
template <>
struct select_hash_type_impl<float, float> {
typedef float type;
};
template <>
struct select_hash_type_impl<long double, long double> {
typedef long double type;
};
// select_hash_type
//
// If there is support for a particular floating point type, use that
// otherwise use double (there's always support for double).
template <typename Float>
struct select_hash_type : select_hash_type_impl<
BOOST_DEDUCED_TYPENAME call_ldexp<Float>::float_type,
BOOST_DEDUCED_TYPENAME call_frexp<Float>::float_type
> {};
}
}
#endif
@@ -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,91 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A general purpose hash function for non-zero floating point values.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_GENERIC_HEADER
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/integer/static_log2.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:6294) // Ill-defined for-loop: initial condition does
// not satisfy test. Loop body not executed
#endif
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
template <class T>
inline std::size_t float_hash_impl2(T v)
{
boost::hash_detail::call_frexp<T> frexp;
boost::hash_detail::call_ldexp<T> ldexp;
int exp = 0;
v = frexp(v, &exp);
// A postive value is easier to hash, so combine the
// sign with the exponent and use the absolute value.
if(v < 0) {
v = -v;
exp += limits<T>::max_exponent -
limits<T>::min_exponent;
}
v = ldexp(v, limits<std::size_t>::digits);
std::size_t seed = static_cast<std::size_t>(v);
v -= seed;
// ceiling(digits(T) * log2(radix(T))/ digits(size_t)) - 1;
std::size_t const length
= (limits<T>::digits *
boost::static_log2<limits<T>::radix>::value
+ limits<std::size_t>::digits - 1)
/ limits<std::size_t>::digits;
for(std::size_t i = 0; i != length; ++i)
{
v = ldexp(v, limits<std::size_t>::digits);
std::size_t part = static_cast<std::size_t>(v);
v -= part;
hash_float_combine(seed, part);
}
hash_float_combine(seed, exp);
return seed;
}
template <class T>
inline std::size_t float_hash_impl(T v)
{
typedef BOOST_DEDUCED_TYPENAME select_hash_type<T>::type type;
return float_hash_impl2(static_cast<type>(v));
}
}
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif
@@ -1,56 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// A non-portable hash function form non-zero floats on x86.
//
// Even if you're on an x86 platform, this might not work if their floating
// point isn't set up as this expects. So this should only be used if it's
// absolutely certain that it will work.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_HASH_FLOAT_X86_HEADER
#include <boost/cstdint.hpp>
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
namespace boost
{
namespace hash_detail
{
inline void hash_float_combine(std::size_t& seed, std::size_t value)
{
seed ^= value + (seed<<6) + (seed>>2);
}
inline std::size_t float_hash_impl(float v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr;
return seed;
}
inline std::size_t float_hash_impl(double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr);
return seed;
}
inline std::size_t float_hash_impl(long double v)
{
boost::uint32_t* ptr = (boost::uint32_t*)&v;
std::size_t seed = *ptr++;
hash_float_combine(seed, *ptr++);
hash_float_combine(seed, *(boost::uint16_t*)ptr);
return seed;
}
}
}
#endif
@@ -1,61 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// On some platforms std::limits gives incorrect values for long double.
// This tries to work around them.
#if !defined(BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER)
#define BOOST_FUNCTIONAL_HASH_DETAIL_LIMITS_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/limits.hpp>
// On OpenBSD, numeric_limits is not reliable for long doubles, but
// the macros defined in <float.h> are and support long double when STLport
// doesn't.
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
#include <float.h>
#endif
namespace boost
{
namespace hash_detail
{
template <class T>
struct limits : std::numeric_limits<T> {};
#if defined(__OpenBSD__) || defined(_STLP_NO_LONG_DOUBLE)
template <>
struct limits<long double>
: std::numeric_limits<long double>
{
static long double epsilon() {
return LDBL_EPSILON;
}
static long double (max)() {
return LDBL_MAX;
}
static long double (min)() {
return LDBL_MIN;
}
BOOST_STATIC_CONSTANT(int, digits = LDBL_MANT_DIG);
BOOST_STATIC_CONSTANT(int, max_exponent = LDBL_MAX_EXP);
BOOST_STATIC_CONSTANT(int, min_exponent = LDBL_MIN_EXP);
#if defined(_STLP_NO_LONG_DOUBLE)
BOOST_STATIC_CONSTANT(int, radix = FLT_RADIX);
#endif
};
#endif // __OpenBSD__
}
}
#endif
+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
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
// This implements the extensions to the standard.
// It's undocumented, so you shouldn't use it....
#if !defined(BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP)
#define BOOST_FUNCTIONAL_HASH_EXTENSIONS_HPP
#include <boost/functional/hash/hash.hpp>
#include <boost/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
#include <boost/container_hash/extensions.hpp>
+1 -490
View File
@@ -3,493 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_HASH_HPP)
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
#include <boost/functional/hash/hash_fwd.hpp>
#include <functional>
#include <boost/functional/hash/detail/hash_float.hpp>
#include <string>
#include <boost/limits.hpp>
#if defined(BOOST_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_NO_LONG_LONG)
std::size_t hash_value(boost::long_long_type);
std::size_t hash_value(boost::ulong_long_type);
#endif
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const&);
#else
template <class T> std::size_t hash_value(T*);
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
std::size_t hash_value(const T (&x)[N]);
template< class T, unsigned N >
std::size_t hash_value(T (&x)[N]);
#endif
std::size_t hash_value(float v);
std::size_t hash_value(double v);
std::size_t hash_value(long double v);
template <class Ch, class A>
std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const&);
// Implementation
namespace hash_detail
{
template <class T>
inline std::size_t hash_value_signed(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
T positive = val < 0 ? -1 - val : val;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (positive >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
template <class T>
inline std::size_t hash_value_unsigned(T val)
{
const int size_t_bits = std::numeric_limits<std::size_t>::digits;
// ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
const int length = (std::numeric_limits<T>::digits - 1)
/ size_t_bits;
std::size_t seed = 0;
// Hopefully, this loop can be unrolled.
for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
{
seed ^= (std::size_t) (val >> i) + (seed<<6) + (seed>>2);
}
seed ^= (std::size_t) val + (seed<<6) + (seed>>2);
return seed;
}
}
inline std::size_t hash_value(bool v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(signed char v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned short v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned int v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(long v)
{
return static_cast<std::size_t>(v);
}
inline std::size_t hash_value(unsigned long v)
{
return static_cast<std::size_t>(v);
}
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline std::size_t hash_value(wchar_t v)
{
return static_cast<std::size_t>(v);
}
#endif
#if !defined(BOOST_NO_LONG_LONG)
inline std::size_t hash_value(boost::long_long_type v)
{
return hash_detail::hash_value_signed(v);
}
inline std::size_t hash_value(boost::ulong_long_type v)
{
return hash_detail::hash_value_unsigned(v);
}
#endif
// Implementation by Alberto Barbati and Dave Harris.
#if !BOOST_WORKAROUND(__DMC__, <= 0x848)
template <class T> std::size_t hash_value(T* const& v)
#else
template <class T> std::size_t hash_value(T* v)
#endif
{
std::size_t x = static_cast<std::size_t>(
reinterpret_cast<std::ptrdiff_t>(v));
return x + (x >> 3);
}
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC <= 1400
#pragma warning(disable:4267) // 'argument' : conversion from 'size_t' to
// 'unsigned int', possible loss of data
// A misguided attempt to detect 64-bit
// incompatability.
#endif
#endif
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T>
inline void hash_combine(std::size_t& seed, T& v)
#else
template <class T>
inline void hash_combine(std::size_t& seed, T const& v)
#endif
{
boost::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
template <class It>
inline std::size_t hash_range(It first, It last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
return seed;
}
template <class It>
inline void hash_range(std::size_t& seed, It first, It last)
{
for(; first != last; ++first)
{
hash_combine(seed, *first);
}
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T>
inline std::size_t hash_range(T* first, T* last)
{
std::size_t seed = 0;
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
template <class T>
inline void hash_range(std::size_t& seed, T* first, T* last)
{
for(; first != last; ++first)
{
boost::hash<T> hasher;
seed ^= hasher(*first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
}
#endif
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
template< class T, unsigned N >
inline std::size_t hash_value(const T (&x)[N])
{
return hash_range(x, x + N);
}
template< class T, unsigned N >
inline std::size_t hash_value(T (&x)[N])
{
return hash_range(x, x + N);
}
#endif
template <class Ch, class A>
inline std::size_t hash_value(
std::basic_string<Ch, std::BOOST_HASH_CHAR_TRAITS<Ch>, A> const& v)
{
return hash_range(v.begin(), v.end());
}
inline std::size_t hash_value(float v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(double v)
{
return boost::hash_detail::float_hash_value(v);
}
inline std::size_t hash_value(long double v)
{
return boost::hash_detail::float_hash_value(v);
}
//
// boost::hash
//
// Define the specializations required by the standard. The general purpose
// boost::hash is defined later in extensions.hpp if
// BOOST_HASH_NO_EXTENSIONS is not defined.
// BOOST_HASH_SPECIALIZE - define a specialization for a type which is
// passed by copy.
//
// BOOST_HASH_SPECIALIZE_REF - define a specialization for a type which is
// passed by copy.
//
// These are undefined later.
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#else
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(const type v) const \
{ \
return boost::hash_value(v); \
} \
};
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
}; \
\
template <> struct hash<const type> \
: public std::unary_function<const type, std::size_t> \
{ \
std::size_t operator()(type const& v) const \
{ \
return boost::hash_value(v); \
} \
};
#endif
BOOST_HASH_SPECIALIZE(bool)
BOOST_HASH_SPECIALIZE(char)
BOOST_HASH_SPECIALIZE(signed char)
BOOST_HASH_SPECIALIZE(unsigned char)
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
BOOST_HASH_SPECIALIZE(wchar_t)
#endif
BOOST_HASH_SPECIALIZE(short)
BOOST_HASH_SPECIALIZE(unsigned short)
BOOST_HASH_SPECIALIZE(int)
BOOST_HASH_SPECIALIZE(unsigned int)
BOOST_HASH_SPECIALIZE(long)
BOOST_HASH_SPECIALIZE(unsigned long)
BOOST_HASH_SPECIALIZE(float)
BOOST_HASH_SPECIALIZE(double)
BOOST_HASH_SPECIALIZE(long double)
BOOST_HASH_SPECIALIZE_REF(std::string)
#if !defined(BOOST_NO_STD_WSTRING)
BOOST_HASH_SPECIALIZE_REF(std::wstring)
#endif
#if !defined(BOOST_NO_LONG_LONG)
BOOST_HASH_SPECIALIZE(boost::long_long_type)
BOOST_HASH_SPECIALIZE(boost::ulong_long_type)
#endif
#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
#include <boost/container_hash/hash.hpp>
+1 -35
View File
@@ -3,38 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Based on Peter Dimov's proposal
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
// issue 6.18.
#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/config.hpp>
#include <cstddef>
#include <boost/detail/workaround.hpp>
namespace boost
{
template <class T> struct hash;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <class T> void hash_combine(std::size_t& seed, T& v);
#else
template <class T> void hash_combine(std::size_t& seed, T const& v);
#endif
template <class It> std::size_t hash_range(It, It);
template <class It> void hash_range(std::size_t&, It, It);
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template <class T> inline std::size_t hash_range(T*, T*);
template <class T> inline void hash_range(std::size_t&, T*, T*);
#endif
}
#endif
#include <boost/container_hash/hash_fwd.hpp>
+1 -2
View File
@@ -3,5 +3,4 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/functional/hash/hash_fwd.hpp>
#include <boost/container_hash/hash_fwd.hpp>
+2 -2
View File
@@ -7,10 +7,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/hash.html">
<meta http-equiv="refresh" content="0; URL=doc/html/hash.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../doc/html/hash.html">../../doc/html/hash.html</a>
<a href="doc/html/hash.html">doc/html/hash.html</a>
</body>
</html>
+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>
+21
View File
@@ -0,0 +1,21 @@
[
{
"key": "container_hash",
"boost-version": "1.33.0",
"name": "Container Hash",
"authors": [
"Daniel James"
],
"maintainers": [
"Daniel James <dnljms -at- gmail.com>"
],
"description": "An STL-compatible hash function object that can be extended to hash user defined types.",
"std": [
"tr1"
],
"category": [
"Function-objects"
],
"cxxstd": "03"
}
]
+11
View File
@@ -0,0 +1,11 @@
# Copyright 2018, 2019, 2021 Peter Dimov
# Distributed under the 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(BoostTestJamfile OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST)
if(HAVE_BOOST_TEST)
boost_test_jamfile(FILE Jamfile.v2 LINK_LIBRARIES Boost::container_hash Boost::core Boost::utility)
endif()
+77 -57
View File
@@ -1,68 +1,88 @@
# 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)
# Copyright 2005-2012 Daniel James.
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
import testing ;
local gcc-flags = -Wunused-parameter -Wconversion -Wsign-conversion -Wfloat-equal -Wshadow -Wno-variadic-macros ;
local clang-flags = $(gcc-flags) -Wno-c99-extensions ;
project hash-tests
: requirements
<warnings>all
<warnings>pedantic
<toolset>intel:<warnings>on
<toolset>intel:<cxxflags>-strict-ansi
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
<toolset>gcc:<cxxflags>$(gcc-flags)
<toolset>darwin:<cxxflags>$(gcc-flags)
<toolset>clang:<cxxflags>$(clang-flags)
<toolset>msvc:<warnings-as-errors>on
#<toolset>gcc:<warnings-as-errors>on
#<toolset>darwin:<warnings-as-errors>on
<toolset>gcc:<warnings-as-errors>on
<toolset>clang:<warnings-as-errors>on
;
test-suite functional/hash
:
[ run hash_fwd_test_1.cpp ]
[ run hash_fwd_test_2.cpp ]
[ run hash_number_test.cpp ]
[ run hash_pointer_test.cpp ]
[ run hash_function_pointer_test.cpp ]
[ run hash_float_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_long_double_test.cpp : : : <test-info>always_show_run_output ]
[ run hash_string_test.cpp ]
[ run hash_range_test.cpp ]
[ run hash_custom_test.cpp ]
[ run hash_global_namespace_test.cpp ]
[ run hash_friend_test.cpp ]
[ run hash_built_in_array_test.cpp ]
[ run hash_value_array_test.cpp ]
[ run hash_vector_test.cpp ]
[ run hash_list_test.cpp ]
[ run hash_deque_test.cpp ]
[ run hash_set_test.cpp ]
[ run hash_map_test.cpp ]
[ run hash_complex_test.cpp ]
[ run link_test.cpp link_test_2.cpp ]
[ run link_ext_test.cpp link_no_ext_test.cpp ]
[ run extensions_hpp_test.cpp ]
[ run container_fwd_test.cpp ]
[ run container_fwd_test.cpp : :
: <toolset>gcc:<define>_GLIBCXX_DEBUG
<toolset>darwin:<define>_GLIBCXX_DEBUG
: container_fwd_gcc_debug ]
[ run container_no_fwd_test.cpp ]
[ compile-fail hash_no_ext_fail_test.cpp ]
[ compile-fail namespace_fail_test.cpp ]
[ run hash_no_ext_macro_1.cpp ]
[ run hash_no_ext_macro_2.cpp ]
;
test-suite functional/hash_no_ext
:
[ run hash_number_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_number_test ]
[ run hash_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_pointer_test ]
[ run hash_function_pointer_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_function_pointer_test ]
[ run hash_float_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_float_test ]
[ run hash_long_double_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_long_double_test ]
[ run hash_string_test.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_string_test ]
[ run link_test.cpp link_test_2.cpp : : : <define>BOOST_HASH_NO_EXTENSIONS : no_ext_link_test ]
;
run hash_info.cpp : : : <test-info>always_show_run_output ;
compile check_float_funcs.cpp ;
run hash_fwd_test_1.cpp ;
run hash_fwd_test_2.cpp ;
run hash_number_test.cpp ;
run hash_enum_test.cpp ;
run hash_pointer_test.cpp ;
run hash_function_pointer_test.cpp ;
run hash_float_test.cpp ;
run hash_long_double_test.cpp ;
run hash_string_test.cpp ;
run hash_range_test.cpp ;
run hash_custom_test.cpp ;
run hash_global_namespace_test.cpp ;
run hash_friend_test.cpp ;
run hash_built_in_array_test.cpp ;
run hash_value_array_test.cpp ;
run hash_vector_test.cpp ;
run hash_list_test.cpp ;
run hash_deque_test.cpp ;
run hash_set_test.cpp ;
run hash_map_test.cpp ;
run hash_complex_test.cpp ;
run hash_optional_test.cpp ;
run hash_variant_test.cpp ;
run hash_type_index_test.cpp ;
run hash_system_error_test.cpp ;
run hash_std_array_test.cpp ;
run hash_std_tuple_test.cpp ;
run hash_std_smart_ptr_test.cpp ;
run link_test.cpp link_test_2.cpp ;
run link_ext_test.cpp link_no_ext_test.cpp ;
run extensions_hpp_test.cpp ;
compile-fail namespace_fail_test.cpp ;
run implicit_test.cpp ;
run hash_no_ext_macro_1.cpp ;
run hash_no_ext_macro_2.cpp ;
build-project ../examples ;
run hash_reference_values.cpp ;
run detail_is_range_test.cpp ;
run detail_is_contiguous_range_test.cpp ;
run detail_is_unordered_range_test.cpp ;
run hash_forward_list_test.cpp ;
run quick.cpp ;
run hash_number_test2.cpp ;
run hash_integral_test.cpp ;
run hash_string_test2.cpp ;
# for gcc-4.8
local fs-path-req = "-<toolset>gcc:<cxxflags>-Wshadow" "-<toolset>gcc:<cxxflags>-Wconversion" ;
run hash_fs_path_test.cpp /boost//filesystem/<warnings>off : : : $(fs-path-req) <toolset>msvc-14.0,<cxxstd>latest:<build>no ;
run detail_is_range_test2.cpp : : : $(fs-path-req) ;
run hash_container_test.cpp ;
run hash_vector_test2.cpp ;
run hash_string_test3.cpp ;
run hash_string_test4.cpp ;
+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)
#if defined(__GNUC__)
// in type_traits/is_complete.hpp:47
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cmath>
namespace test
{
template <class T1>
struct check_return_type
{
template <class T2>
static void equals(T2)
{
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
}
template <class T2>
static void equals_ref(T2&)
{
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
}
template <class T2>
static void convertible(T2)
{
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
}
};
}
int main() {
float f = 0;
double d = 0;
long double l = 0;
test::check_return_type<float>::equals(std::ldexp(f, 0));
test::check_return_type<double>::equals(std::ldexp(d, 0));
test::check_return_type<long double>::equals(std::ldexp(l, 0));
int dummy = 0;
test::check_return_type<float>::equals(std::frexp(f, &dummy));
test::check_return_type<double>::equals(std::frexp(d, &dummy));
test::check_return_type<long double>::equals(std::frexp(l, &dummy));
#if BOOST_HASH_USE_FPCLASSIFY
int (*fpc1)(float) = std::fpclassify;
int (*fpc2)(double) = std::fpclassify;
int (*fpc3)(long double) = std::fpclassify;
#endif
}
+17
View File
@@ -0,0 +1,17 @@
# Copyright 2018, 2019, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.20)
project(cmake_install_test LANGUAGES CXX)
find_package(boost_container_hash REQUIRED)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::container_hash)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
+21
View File
@@ -0,0 +1,21 @@
# Copyright 2018, 2019, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt
cmake_minimum_required(VERSION 3.5...3.20)
project(cmake_subdir_test LANGUAGES CXX)
add_subdirectory(../.. boostorg/container_hash)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../type_traits boostorg/type_traits)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::container_hash)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)
+7 -3
View File
@@ -5,12 +5,16 @@
#include <boost/config.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>
void compile_time_tests(T*)
{
BOOST_STATIC_ASSERT((boost::is_base_and_derived<
std::unary_function<T, std::size_t>, HASH_NAMESPACE::hash<T> >::value));
BOOST_STATIC_ASSERT((boost::is_same<T,
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::argument_type
>::value));
BOOST_STATIC_ASSERT((boost::is_same<std::size_t,
typename BOOST_HASH_TEST_NAMESPACE::hash<T>::result_type
>::value));
}
+9 -5
View File
@@ -3,13 +3,13 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if defined(TEST_STD)
# define TEST_STD_INCLUDES
# define HASH_NAMESPACE std
#if defined(BOOST_HASH_TEST_STD)
# define BOOST_HASH_TEST_STD_INCLUDES
# define BOOST_HASH_TEST_NAMESPACE std
#else
# define HASH_NAMESPACE boost
# define BOOST_HASH_TEST_NAMESPACE boost
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define TEST_EXTENSIONS
# define BOOST_HASH_TEST_EXTENSIONS
# endif
#endif
@@ -18,4 +18,8 @@
// 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
-114
View File
@@ -1,114 +0,0 @@
// Copyright 2005-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
#include <boost/functional/detail/container_fwd.hpp>
#if BOOST_WORKAROUND(__GNUC__, < 3) && \
!defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)
template <class charT, class Allocator>
static void test(
std::basic_string<charT, std::string_char_traits<charT>, Allocator> const&)
{
}
#else
template <class charT, class Allocator>
static void test(
std::basic_string<charT, std::char_traits<charT>, Allocator> const&)
{
}
#endif
template <class T, class Allocator>
static void test(std::deque<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::list<T, Allocator> const&)
{
}
template <class T, class Allocator>
static void test(std::vector<T, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::map<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class T, class Compare, class Allocator>
static void test(std::multimap<Key, T, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::set<Key, Compare, Allocator> const&)
{
}
template <class Key, class Compare, class Allocator>
static void test(std::multiset<Key, Compare, Allocator> const&)
{
}
template <std::size_t N>
static void test(std::bitset<N> const&)
{
}
template <class T>
static void test(std::complex<T> const&)
{
}
template <class X, class Y>
static void test(std::pair<X, Y> const&)
{
}
#include <deque>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <complex>
#include <utility>
int main()
{
std::deque<int> x1;
std::list<std::string> x2;
std::vector<float> x3;
std::vector<bool> x4;
std::map<int, int> x5;
std::multimap<float, int*> x6;
std::set<std::string> x7;
std::multiset<std::vector<int> > x8;
std::bitset<10> x9;
std::string x10;
std::complex<double> x11;
std::pair<std::list<int>, char***> x12;
test(x1);
test(x2);
test(x3);
test(x4);
test(x5);
test(x6);
test(x7);
test(x8);
test(x9);
test(x10);
test(x11);
test(x12);
return 0;
}
-14
View File
@@ -1,14 +0,0 @@
// Copyright 2010 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_DETAIL_NO_CONTAINER_FWD
#include <boost/detail/container_fwd.hpp>
int main()
{
std::set<int> x;
std::vector<std::string> y;
}
+101
View File
@@ -0,0 +1,101 @@
// Copyright 2017, 2018 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/detail/is_contiguous_range.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
# include <forward_list>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
# include <unordered_set>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
# include <unordered_map>
#endif
struct X
{
};
int main()
{
using boost::hash_detail::is_contiguous_range;
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<void>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<void const>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<int>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<int const>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<X>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<X const>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<int[2]>));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range<int const[2]>));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range<std::string>));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range<std::string const>));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range<std::wstring>));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range<std::wstring const>));
// std::vector doesn't have data() in C++03
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 40700)
BOOST_TEST_TRAIT_TRUE((is_contiguous_range< std::vector<X> >));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range< std::vector<X> const >));
#endif
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::deque<X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::deque<X> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::set<int> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::set<int> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::multiset<int> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::multiset<int> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::map<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::map<int, X> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::multimap<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::multimap<int, X> const >));
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
BOOST_TEST_TRAIT_TRUE((is_contiguous_range< std::array<X, 2> >));
BOOST_TEST_TRAIT_TRUE((is_contiguous_range< std::array<X, 2> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::forward_list<X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::forward_list<X> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_set<int> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_set<int> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_multiset<int> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_multiset<int> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_map<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_map<int, X> const >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_multimap<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_contiguous_range< std::unordered_multimap<int, X> const >));
#endif
return boost::report_errors();
}
+98
View File
@@ -0,0 +1,98 @@
// Copyright 2017 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/detail/is_range.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
# include <forward_list>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
# include <unordered_set>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
# include <unordered_map>
#endif
struct X
{
};
int main()
{
using boost::hash_detail::is_range;
BOOST_TEST_TRAIT_FALSE((is_range<void>));
BOOST_TEST_TRAIT_FALSE((is_range<void const>));
BOOST_TEST_TRAIT_FALSE((is_range<int>));
BOOST_TEST_TRAIT_FALSE((is_range<int const>));
BOOST_TEST_TRAIT_FALSE((is_range<X>));
BOOST_TEST_TRAIT_FALSE((is_range<X const>));
BOOST_TEST_TRAIT_FALSE((is_range<int[2]>));
BOOST_TEST_TRAIT_FALSE((is_range<int const[2]>));
BOOST_TEST_TRAIT_TRUE((is_range<std::string>));
BOOST_TEST_TRAIT_TRUE((is_range<std::string const>));
BOOST_TEST_TRAIT_TRUE((is_range<std::wstring>));
BOOST_TEST_TRAIT_TRUE((is_range<std::wstring const>));
BOOST_TEST_TRAIT_TRUE((is_range< std::vector<X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::vector<X> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::deque<X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::deque<X> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::set<int> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::set<int> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::multiset<int> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::multiset<int> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::map<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::map<int, X> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::multimap<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::multimap<int, X> const >));
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
BOOST_TEST_TRAIT_TRUE((is_range< std::array<X, 2> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::array<X, 2> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
BOOST_TEST_TRAIT_TRUE((is_range< std::forward_list<X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::forward_list<X> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_set<int> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_set<int> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_multiset<int> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_multiset<int> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_map<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_map<int, X> const >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_multimap<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_range< std::unordered_multimap<int, X> const >));
#endif
return boost::report_errors();
}
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2022 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4714) // forceinline not inlined
#endif
#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <boost/container_hash/detail/is_range.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <boost/filesystem/path.hpp>
#if !defined(BOOST_NO_CXX17_HDR_FILESYSTEM) && !defined(__MINGW32__)
# include <filesystem>
#endif
int main()
{
using boost::hash_detail::is_range;
BOOST_TEST_TRAIT_FALSE((is_range< boost::filesystem::path >));
BOOST_TEST_TRAIT_FALSE((is_range< boost::filesystem::path const >));
#if !defined(BOOST_NO_CXX17_HDR_FILESYSTEM) && !defined(__MINGW32__)
BOOST_TEST_TRAIT_FALSE((is_range< std::filesystem::path >));
BOOST_TEST_TRAIT_FALSE((is_range< std::filesystem::path const >));
#endif
return boost::report_errors();
}
+98
View File
@@ -0,0 +1,98 @@
// Copyright 2017 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/detail/is_unordered_range.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/config.hpp>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
# include <array>
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
# include <forward_list>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
# include <unordered_set>
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
# include <unordered_map>
#endif
struct X
{
};
int main()
{
using boost::hash_detail::is_unordered_range;
BOOST_TEST_TRAIT_FALSE((is_unordered_range<void>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<void const>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<int>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<int const>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<X>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<X const>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<int[2]>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<int const[2]>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<std::string>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<std::string const>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<std::wstring>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range<std::wstring const>));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::vector<X> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::vector<X> const >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::deque<X> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::deque<X> const >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::set<int> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::set<int> const >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::multiset<int> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::multiset<int> const >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::map<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::map<int, X> const >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::multimap<int, X> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::multimap<int, X> const >));
#if !defined(BOOST_NO_CXX11_HDR_ARRAY)
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::array<X, 2> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::array<X, 2> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::forward_list<X> >));
BOOST_TEST_TRAIT_FALSE((is_unordered_range< std::forward_list<X> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_SET)
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_set<int> >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_set<int> const >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_multiset<int> >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_multiset<int> const >));
#endif
#if !defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP)
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_map<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_map<int, X> const >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_multimap<int, X> >));
BOOST_TEST_TRAIT_TRUE((is_unordered_range< std::unordered_multimap<int, X> const >));
#endif
return boost::report_errors();
}
+3 -3
View File
@@ -3,14 +3,14 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// Check that boost/functional/hash/extensions.hpp works okay.
// 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.
#include "./config.hpp"
#include <boost/functional/hash/extensions.hpp>
#include <boost/container_hash/extensions.hpp>
int main() {
int x[2] = { 2, 3 };
+17 -17
View File
@@ -5,17 +5,17 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# 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()
{
@@ -27,47 +27,47 @@ void array_int_test()
8, -12, 23, 65, 45,
-1, 93, -54, 987, 3
};
HASH_NAMESPACE::hash<int[25]> hasher1;
BOOST_HASH_TEST_NAMESPACE::hash<int[25]> hasher1;
const int length2 = 1;
int array2[1] = {3};
HASH_NAMESPACE::hash<int[1]> hasher2;
BOOST_HASH_TEST_NAMESPACE::hash<int[1]> hasher2;
const int length3 = 2;
int array3[2] = {2, 3};
HASH_NAMESPACE::hash<int[2]> hasher3;
BOOST_HASH_TEST_NAMESPACE::hash<int[2]> hasher3;
BOOST_TEST(hasher1(array1)
== HASH_NAMESPACE::hash_range(array1, array1 + length1));
== BOOST_HASH_TEST_NAMESPACE::hash_range(array1, array1 + length1));
BOOST_TEST(hasher2(array2)
== HASH_NAMESPACE::hash_range(array2, array2 + length2));
== BOOST_HASH_TEST_NAMESPACE::hash_range(array2, array2 + length2));
BOOST_TEST(hasher3(array3)
== HASH_NAMESPACE::hash_range(array3, array3 + length3));
== BOOST_HASH_TEST_NAMESPACE::hash_range(array3, array3 + length3));
}
void two_dimensional_array_test()
{
int array[3][2] = {{-5, 6}, {7, -3}, {26, 1}};
HASH_NAMESPACE::hash<int[3][2]> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<int[3][2]> hasher;
std::size_t seed1 = 0;
for(int i = 0; i < 3; ++i)
{
std::size_t seed2 = 0;
for(int j = 0; j < 2; ++j)
HASH_NAMESPACE::hash_combine(seed2, array[i][j]);
HASH_NAMESPACE::hash_combine(seed1, seed2);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, array[i][j]);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, seed2);
}
BOOST_TEST(hasher(array) == seed1);
BOOST_TEST(hasher(array) == HASH_NAMESPACE::hash_range(array, array + 3));
BOOST_TEST(hasher(array) == BOOST_HASH_TEST_NAMESPACE::hash_range(array, array + 3));
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
array_int_test();
two_dimensional_array_test();
#endif
+37 -11
View File
@@ -5,19 +5,19 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS)
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
#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
@@ -29,24 +29,30 @@ int main() {}
// 'const std::complex<float>::_Ty'
#pragma warning(disable:4309) // truncation of constant value
#pragma warning(disable:4512) // assignment operator could not be generated
#pragma warning(disable:4996) // std::complex<Integer> is deprecated
#if BOOST_MSVC < 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data
#endif
#endif
#if ( defined(__GNUC__) || defined(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <boost/limits.hpp>
#include <complex>
#include <sstream>
#include <boost/limits.hpp>
#include <set>
template <class T>
void generic_complex_tests(std::complex<T> v)
{
HASH_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<std::complex<T> > complex_hasher;
BOOST_TEST(complex_hasher(v) == complex_hasher(v));
HASH_NAMESPACE::hash<T> real_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> real_hasher;
T real = v.real();
T imag = v.imag();
@@ -69,7 +75,7 @@ void complex_float_tests(Float*)
generic_complex_tests(complex(0.5,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(25,0));
generic_complex_tests(complex(-67.5324535,56.23578678));
generic_complex_tests(complex(static_cast<Float>(-67.5324535),static_cast<Float>(56.23578678)));
}
template <class Integer>
@@ -80,8 +86,23 @@ void complex_integral_tests(Integer*)
generic_complex_tests(complex(15342,124));
generic_complex_tests(complex(25,54356));
generic_complex_tests(complex(5325,2346));
generic_complex_tests(complex(-243897,-49923874));
generic_complex_tests(complex(-543,763));
generic_complex_tests(complex(Integer(-243897),Integer(-49923874)));
generic_complex_tests(complex(Integer(-543),Integer(763)));
}
template<class T> void complex_grid_test( short N )
{
std::set<std::size_t> hashes;
for( short i = 0; i < N; ++i )
{
for( short j = 0; j < N; ++j )
{
hashes.insert( boost::hash< std::complex<T> >()( std::complex<T>( i, j ) ) );
}
}
BOOST_TEST_EQ( hashes.size(), static_cast<std::size_t>( N * N ) );
}
int main()
@@ -100,7 +121,12 @@ int main()
complex_integral_tests((unsigned int*) 0);
complex_integral_tests((unsigned long*) 0);
complex_grid_test<int>( 16 );
complex_grid_test<float>( 7 );
complex_grid_test<double>( 16 );
complex_grid_test<long double>( 15 );
return boost::report_errors();
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <vector>
#include <deque>
#include <list>
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
# include <forward_list>
#endif
template<class T> std::size_t hv( T const& t )
{
return boost::hash<T>()( t );
}
template<class T> void test()
{
for( std::size_t i = 0; i < 8; ++i )
{
std::vector<T> v( i );
std::size_t h0 = hv( v );
std::deque<T> d( v.begin(), v.end() );
BOOST_TEST_EQ( h0, hv( d ) );
std::list<T> l( v.begin(), v.end() );
BOOST_TEST_EQ( h0, hv( l ) );
#if !defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
std::forward_list<T> f( v.begin(), v.end() );
BOOST_TEST_EQ( h0, hv( f ) );
#endif
}
}
int main()
{
test<char>();
test<unsigned char>();
test<signed char>();
test<int>();
test<float>();
test<double>();
return boost::report_errors();
}
+17 -17
View File
@@ -15,7 +15,7 @@ namespace test
std::size_t hash() const
{
return value_ * 10;
return static_cast<std::size_t>(value_ * 10);
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -41,17 +41,17 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# 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 <string>
@@ -59,13 +59,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<test::custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -75,25 +75,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom(5));
HASH_NAMESPACE::hash_combine(seed, test::custom(25));
HASH_NAMESPACE::hash_combine(seed, test::custom(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();
+7 -7
View File
@@ -5,17 +5,17 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <deque>
@@ -23,11 +23,11 @@ using std::deque;
#define CONTAINER_TYPE deque
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
deque_tests::deque_hash_integer_tests();
#endif
+63
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();
}
+33 -43
View File
@@ -5,18 +5,17 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# 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 <cmath>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/functional/hash/detail/float_functions.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/container_hash/detail/limits.hpp>
#include <boost/config/workaround.hpp>
#include <iostream>
@@ -30,6 +29,10 @@
#endif
#endif
#if ( defined(__GNUC__) || defined(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
char const* float_type(float*) { return "float"; }
char const* float_type(double*) { return "double"; }
char const* float_type(long double*) { return "long double"; }
@@ -39,7 +42,7 @@ void float_tests(char const* name, T* = 0)
{
std::cerr
<< "\n"
<< "Testing " BOOST_STRINGIZE(HASH_NAMESPACE) "::hash<"
<< "Testing " BOOST_STRINGIZE(BOOST_HASH_TEST_NAMESPACE) "::hash<"
<< name
<< ">\n"
<< "\n"
@@ -51,22 +54,9 @@ void float_tests(char const* name, T* = 0)
<< boost::hash_detail::limits<std::size_t>::digits
<< "\n"
<< "\n"
<< "boost::hash_detail::call_ldexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_ldexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::call_frexp<T>::float_type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::call_frexp<T>::float_type*>(0))
<< "\n"
<< "boost::hash_detail::select_hash_type<T>::type = "
<< float_type(static_cast<BOOST_DEDUCED_TYPENAME
boost::hash_detail::select_hash_type<T>::type*>(0))
<< "\n"
<< "\n"
;
HASH_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
T zero = 0;
T minus_zero = (T) -1 * zero;
@@ -74,9 +64,9 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(zero == minus_zero);
BOOST_TEST(x1(zero) == x1(minus_zero));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == HASH_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == HASH_NAMESPACE::hash_value(minus_zero));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(zero));
BOOST_TEST(x1(minus_zero) == BOOST_HASH_TEST_NAMESPACE::hash_value(minus_zero));
#endif
BOOST_TEST(x1(zero) != x1(0.5));
@@ -87,7 +77,7 @@ void float_tests(char const* name, T* = 0)
using namespace std;
// Doing anything with infinity causes borland to crash.
#if defined(__BORLANDC__)
#if defined(BOOST_BORLANDC)
std::cerr
<< "Not running infinity checks on Borland, as it causes it to crash."
"\n";
@@ -102,10 +92,10 @@ void float_tests(char const* name, T* = 0)
T minus_infinity2 = (T) -1. / zero;
T minus_infinity3 = (T) 1. / minus_zero;
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == HASH_NAMESPACE::hash_value(infinity));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(infinity) == BOOST_HASH_TEST_NAMESPACE::hash_value(infinity));
BOOST_TEST(x1(minus_infinity)
== HASH_NAMESPACE::hash_value(minus_infinity));
== BOOST_HASH_TEST_NAMESPACE::hash_value(minus_infinity));
#endif
if(infinity == infinity2)
@@ -187,12 +177,12 @@ void float_tests(char const* name, T* = 0)
BOOST_TEST(three_quarter_max != -three_quarter_max);
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(max) == HASH_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == HASH_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == HASH_NAMESPACE::hash_value(quarter_max));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(max) == BOOST_HASH_TEST_NAMESPACE::hash_value(max));
BOOST_TEST(x1(half_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(half_max));
BOOST_TEST(x1(quarter_max) == BOOST_HASH_TEST_NAMESPACE::hash_value(quarter_max));
BOOST_TEST(x1(three_quarter_max) ==
HASH_NAMESPACE::hash_value(three_quarter_max));
BOOST_HASH_TEST_NAMESPACE::hash_value(three_quarter_max));
#endif
// The '!=' tests could legitimately fail, but with my hash it indicates a
@@ -223,16 +213,16 @@ void float_tests(char const* name, T* = 0)
if(v1 == v2)
BOOST_TEST(x1(v1) == x1(v2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == HASH_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == HASH_NAMESPACE::hash_value(v2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(v1) == BOOST_HASH_TEST_NAMESPACE::hash_value(v1));
BOOST_TEST(x1(v2) == BOOST_HASH_TEST_NAMESPACE::hash_value(v2));
#endif
#endif
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(boost::hash_detail::limits<T>::epsilon()) ==
HASH_NAMESPACE::hash_value(
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::epsilon()));
#endif
@@ -265,12 +255,12 @@ void float_tests(char const* name, T* = 0)
if(x1(boost::hash_detail::limits<T>::denorm_min()) == x1(zero)) {
std::cerr<<"x1(denorm_min) == x1(zero) == "<<x1(zero)<<"\n";
}
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(TEST_EXTENSIONS)
#if !BOOST_WORKAROUND(__DECCXX_VER,<70190006) && defined(BOOST_HASH_TEST_EXTENSIONS)
// The Tru64/CXX standard library prior to 7.1 contains a bug in the
// specialization of boost::hash_detail::limits::denorm_min() for long
// doubles which causes this test to fail.
if(x1(boost::hash_detail::limits<T>::denorm_min()) !=
HASH_NAMESPACE::hash_value(
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min()))
{
std::cerr
@@ -278,7 +268,7 @@ void float_tests(char const* name, T* = 0)
<< x1(boost::hash_detail::limits<T>::denorm_min())
<< "\nhash_value(boost::hash_detail::limits<T>::denorm_min())"
" = "
<< HASH_NAMESPACE::hash_value(
<< BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::denorm_min())
<< "\nx1(0) = "
<< x1(0)
@@ -288,13 +278,13 @@ void float_tests(char const* name, T* = 0)
}
// NaN also causes borland to crash.
#if !defined(__BORLANDC__) && defined(TEST_EXTENSIONS)
#if !defined(BOOST_BORLANDC) && defined(BOOST_HASH_TEST_EXTENSIONS)
if(boost::hash_detail::limits<T>::has_quiet_NaN) {
if(x1(boost::hash_detail::limits<T>::quiet_NaN()) == x1(1.0)) {
std::cerr<<"x1(quiet_NaN) == x1(1.0) == "<<x1(1.0)<<"\n";
}
BOOST_TEST(x1(boost::hash_detail::limits<T>::quiet_NaN()) ==
HASH_NAMESPACE::hash_value(
BOOST_HASH_TEST_NAMESPACE::hash_value(
boost::hash_detail::limits<T>::quiet_NaN()));
}
#endif
+59
View File
@@ -0,0 +1,59 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(__GNUC__) && __GNUC__ == 8
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/pragma_message.hpp>
#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST)
BOOST_PRAGMA_MESSAGE( "Test skipped, BOOST_NO_CXX11_HDR_FORWARD_LIST is defined" )
int main() {}
#else
#include <forward_list>
template<class T> void test()
{
typedef std::forward_list<T> list;
typedef boost::hash<list> hash;
int const N = 32;
std::size_t h[ N ];
list v;
for( int i = 0; i < N; ++i )
{
h[ i ] = hash()( v );
BOOST_TEST_EQ( h[ i ], hash()( v ) );
for( int j = 0; j < i; ++j )
{
BOOST_TEST_NE( h[ j ], h[ i ] );
}
v.push_front( T() );
}
}
int main()
{
test<int>();
test<float>();
test<double>();
test< std::forward_list<int> >();
return boost::report_errors();
}
#endif
+17 -17
View File
@@ -17,7 +17,7 @@ namespace test
std::size_t hash() const
{
return value_ * 10;
return static_cast<std::size_t>(value_ * 10);
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -44,17 +44,17 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# 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 <string>
@@ -62,13 +62,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<test::custom<int> > custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
test::custom<int> x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -78,25 +78,25 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(5));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(25));
HASH_NAMESPACE::hash_combine(seed, test::custom<int>(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, test::custom<int>(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2022 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#if defined(_MSC_VER)
# pragma warning(disable: 4714) // forceinline not inlined
#endif
#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
#include <boost/filesystem/path.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
template<class T> std::size_t hv( T const& t )
{
return boost::hash<T>()( t );
}
int main()
{
boost::filesystem::path p1( "/foo/bar" );
boost::filesystem::path p2( "/foo/baz" );
BOOST_TEST_NE( hv( p1 ), hv( p2 ) );
return boost::report_errors();
}
+8 -12
View File
@@ -5,17 +5,13 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/core/lightweight_test.hpp>
#include "./compile_time.hpp"
void void_func1() { static int x = 1; ++x; }
@@ -28,8 +24,8 @@ void function_pointer_tests()
compile_time_tests((void(**)()) 0);
compile_time_tests((int(**)(int)) 0);
HASH_NAMESPACE::hash<void(*)()> hasher_void;
HASH_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_HASH_TEST_NAMESPACE::hash<void(*)()> hasher_void;
BOOST_HASH_TEST_NAMESPACE::hash<int(*)(int)> hasher_int;
BOOST_TEST(&void_func1 != &void_func2);
BOOST_TEST(&int_func1 != &int_func2);
@@ -42,11 +38,11 @@ void function_pointer_tests()
BOOST_TEST(hasher_int(&int_func1) == hasher_int(&int_func1));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(&int_func2));
BOOST_TEST(hasher_int(&int_func1) != hasher_int(0));
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(hasher_void(&void_func1)
== HASH_NAMESPACE::hash_value(&void_func1));
== BOOST_HASH_TEST_NAMESPACE::hash_value(&void_func1));
BOOST_TEST(hasher_int(&int_func1)
== HASH_NAMESPACE::hash_value(&int_func1));
== BOOST_HASH_TEST_NAMESPACE::hash_value(&int_func1));
// This isn't specified in Peter's proposal:
BOOST_TEST(hasher_void(0) == 0);
+12 -12
View File
@@ -5,8 +5,8 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#include <boost/functional/hash_fwd.hpp>
#if defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
#include <boost/container_hash/hash_fwd.hpp>
#include <boost/config.hpp>
#include <cstddef>
@@ -25,7 +25,7 @@ namespace test {
template <class T>
std::size_t hash_value(test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
#endif
@@ -42,8 +42,8 @@ namespace test {
std::size_t hash_value(test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
#endif
@@ -61,8 +61,8 @@ namespace test {
std::size_t hash_value(test_type3<T> const& x)
{
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
#endif
@@ -76,7 +76,7 @@ namespace boost
template <class T>
std::size_t hash_value(test::test_type1<T> const& x)
{
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
return hasher(x.value);
}
@@ -84,8 +84,8 @@ namespace boost
std::size_t hash_value(test::test_type2<T> const& x)
{
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, x.value1);
HASH_NAMESPACE::hash_combine(seed, x.value2);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value1);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, x.value2);
return seed;
}
@@ -93,8 +93,8 @@ namespace boost
std::size_t hash_value(test::test_type3<T> const& x)
{
std::size_t seed =
HASH_NAMESPACE::hash_range(x.values.begin(), x.values.end());
HASH_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(x.values.begin(), x.values.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.values.begin(), x.values.end());
return seed;
}
}
+20 -20
View File
@@ -9,11 +9,11 @@
#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>
void fwd_test1()
@@ -21,10 +21,10 @@ void fwd_test1()
test::test_type1<int> x(5);
test::test_type1<std::string> y("Test");
HASH_NAMESPACE::hash<int> hasher_int;
HASH_NAMESPACE::hash<std::string> hasher_string;
HASH_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<int> hasher_int;
BOOST_HASH_TEST_NAMESPACE::hash<std::string> hasher_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type1<std::string> > hasher_test_string;
BOOST_TEST(hasher_int(5) == hasher_test_int(x));
BOOST_TEST(hasher_string("Test") == hasher_test_string(y));
@@ -36,15 +36,15 @@ void fwd_test2()
test::test_type2<std::string> y("Test1", "Test2");
std::size_t seed1 = 0;
HASH_NAMESPACE::hash_combine(seed1, 5);
HASH_NAMESPACE::hash_combine(seed1, 10);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 5);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed1, 10);
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, std::string("Test1"));
HASH_NAMESPACE::hash_combine(seed2, std::string("Test2"));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test1"));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, std::string("Test2"));
HASH_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type2<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -69,15 +69,15 @@ void fwd_test3()
test::test_type3<std::string> y(values2.begin(), values2.end());
std::size_t seed1 =
HASH_NAMESPACE::hash_range(values1.begin(), values1.end());
HASH_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed1, values1.begin(), values1.end());
std::size_t seed2 =
HASH_NAMESPACE::hash_range(values2.begin(), values2.end());
HASH_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed2, values2.begin(), values2.end());
HASH_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
HASH_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<int> > hasher_test_int;
BOOST_HASH_TEST_NAMESPACE::hash<test::test_type3<std::string> > hasher_test_string;
BOOST_TEST(seed1 == hasher_test_int(x));
BOOST_TEST(seed2 == hasher_test_string(y));
@@ -87,7 +87,7 @@ void fwd_test3()
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
fwd_test1();
fwd_test2();
fwd_test3();
+3 -3
View File
@@ -8,14 +8,14 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS) || defined(TEST_STD_INCLUDES)
#if !defined(BOOST_HASH_TEST_EXTENSIONS) || defined(BOOST_HASH_TEST_STD_INCLUDES)
int main() {}
#else
#include "./hash_fwd_test.hpp"
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
template <class T> void unused(T const&) {}
@@ -44,4 +44,4 @@ int main()
return boost::report_errors();
}
#endif // defined(TEST_EXTENSIONS) && !defined(TEST_STD_INCLUDES)
#endif // defined(BOOST_HASH_TEST_EXTENSIONS) && !defined(BOOST_HASH_TEST_STD_INCLUDES)
+17 -17
View File
@@ -17,7 +17,7 @@ struct custom
std::size_t hash() const
{
return value_ * 10;
return static_cast<std::size_t>(value_ * 10);
}
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -42,17 +42,17 @@ namespace boost
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# 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 <string>
@@ -60,13 +60,13 @@ namespace boost
void custom_tests()
{
HASH_NAMESPACE::hash<custom> custom_hasher;
BOOST_HASH_TEST_NAMESPACE::hash<custom> custom_hasher;
BOOST_TEST(custom_hasher(10) == 100u);
custom x(55);
BOOST_TEST(custom_hasher(x) == 550u);
{
using namespace HASH_NAMESPACE;
using namespace BOOST_HASH_TEST_NAMESPACE;
BOOST_TEST(custom_hasher(x) == hash_value(x));
}
@@ -76,26 +76,26 @@ void custom_tests()
custom_vector.push_back(35);
std::size_t seed = 0;
HASH_NAMESPACE::hash_combine(seed, custom(5));
HASH_NAMESPACE::hash_combine(seed, custom(25));
HASH_NAMESPACE::hash_combine(seed, custom(35));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(5));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(25));
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed, custom(35));
std::size_t seed2 = 0;
HASH_NAMESPACE::hash_combine(seed2, 50u);
HASH_NAMESPACE::hash_combine(seed2, 250u);
HASH_NAMESPACE::hash_combine(seed2, 350u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 50u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 250u);
BOOST_HASH_TEST_NAMESPACE::hash_combine(seed2, 350u);
BOOST_TEST(seed == HASH_NAMESPACE::hash_range(
BOOST_TEST(seed == BOOST_HASH_TEST_NAMESPACE::hash_range(
custom_vector.begin(), custom_vector.end()));
BOOST_TEST(seed == seed2);
}
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
custom_tests();
#endif
return boost::report_errors();
+124
View File
@@ -0,0 +1,124 @@
// 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>
#include <limits>
#include <climits>
#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.1x, VS2017"},
{1920, "Visual C++ 14.2x, VS2019"},
{1930, "Visual C++ 14.3x, VS2022"},
};
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
#define PRINT(x) std::cout << #x ": " << x << std::endl
int main() {
write_compiler_info();
std::cout << std::endl;
PRINT(__cplusplus);
PRINT(BOOST_CXX_VERSION);
std::cout << std::endl;
#if defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
std::cout << "No <string_view>" << std::endl;
#else
std::cout << "Has <string_view>" << std::endl;
#endif
#if defined(BOOST_NO_CXX17_HDR_OPTIONAL)
std::cout << "No <optional>" << std::endl;
#else
std::cout << "Has <optional>" << std::endl;
#endif
#if defined(BOOST_NO_CXX17_HDR_VARIANT)
std::cout << "No <variant>" << std::endl;
#else
std::cout << "Has <variant>" << std::endl;
#endif
#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
std::cout << "No <typeindex>" << std::endl;
#else
std::cout << "Has <typeindex>" << std::endl;
#endif
#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
std::cout << "No <system_error>" << std::endl;
#else
std::cout << "Has <system_error>" << std::endl;
#endif
std::cout << std::endl;
PRINT(CHAR_BIT);
std::cout << std::endl;
PRINT(sizeof(std::size_t)*CHAR_BIT);
std::cout << std::endl;
PRINT(sizeof(float)*CHAR_BIT);
PRINT(std::numeric_limits<float>::digits);
std::cout << std::endl;
PRINT(sizeof(double)*CHAR_BIT);
PRINT(std::numeric_limits<double>::digits);
std::cout << std::endl;
PRINT(sizeof(long double)*CHAR_BIT);
PRINT(std::numeric_limits<long double>::digits);
}
+75
View File
@@ -0,0 +1,75 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/type_name.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <set>
#if defined(BOOST_MSVC)
#pragma warning(disable: 4127) // conditional expression is constant
#endif
// This test checks that small numbers hash to themselves even if
// their type is wider than size_t
template<class T>
void identity_test()
{
if( boost::is_signed<T>::value )
{
for( int i = -128; i <= 127; ++i )
{
BOOST_TEST_EQ( boost::hash<T>()( static_cast<T>( i ) ), static_cast<std::size_t>( i ) );
}
}
else
{
for( int i = 0; i <= 255; ++i )
{
BOOST_TEST_EQ( boost::hash<T>()( static_cast<T>( i ) ), static_cast<std::size_t>( i ) );
}
}
}
#define TEST(type) std::cerr << "Testing: " #type " (" << boost::core::type_name<type>() << ")\n"; identity_test<type>();
int main()
{
TEST(char)
TEST(signed char)
TEST(unsigned char)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
TEST(wchar_t)
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
TEST(char16_t)
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
TEST(char32_t)
#endif
TEST(short)
TEST(unsigned short)
TEST(int)
TEST(unsigned int)
TEST(long)
TEST(unsigned long)
#if !defined(BOOST_NO_LONG_LONG)
TEST(boost::long_long_type)
TEST(boost::ulong_long_type)
#endif
#if defined(BOOST_HAS_INT128)
TEST(boost::int128_type)
TEST(boost::uint128_type)
#endif
TEST(std::size_t)
TEST(std::ptrdiff_t)
return boost::report_errors();
}
+7 -7
View File
@@ -5,17 +5,17 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
#include <list>
@@ -23,11 +23,11 @@ using std::list;
#define CONTAINER_TYPE list
#include "./hash_sequence_test.hpp"
#endif // TEST_EXTENSIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
list_tests::list_hash_integer_tests();
#endif
+7 -7
View File
@@ -5,19 +5,19 @@
#include "./config.hpp"
#ifdef TEST_EXTENSIONS
# ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_EXTENSIONS
# ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
# else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
# endif
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <map>
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
using std::map;
#define CONTAINER_TYPE map
@@ -27,11 +27,11 @@ using std::multimap;
#define CONTAINER_TYPE multimap
#include "./hash_map_test.hpp"
#endif // TEST_EXTENSTIONS
#endif // BOOST_HASH_TEST_EXTENSIONS
int main()
{
#ifdef TEST_EXTENSIONS
#ifdef BOOST_HASH_TEST_EXTENSIONS
map_tests::map_hash_integer_tests();
multimap_tests::multimap_hash_integer_tests();
#endif
+14 -7
View File
@@ -7,15 +7,18 @@
#error "CONTAINER_TYPE not defined"
#else
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_MSVC)
#pragma warning(push)
#pragma warning(disable:4244) // conversion from 'int' to 'float'
#pragma warning(disable:4245) // signed/unsigned mismatch
#endif
namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
#if defined(__GNUC__) && __GNUC__ == 8
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
namespace HASH_TEST_CAT(CONTAINER_TYPE, _tests)
{
template <class T>
void integer_tests(T* = 0)
@@ -38,16 +41,16 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
containers[9].insert(pair(key(-1),value(3)));
containers[9].insert(pair(key(-1),value(3)));
HASH_NAMESPACE::hash<T> hasher;
BOOST_HASH_TEST_NAMESPACE::hash<T> hasher;
for(int i2 = 0; i2 < number_of_containers; ++i2) {
BOOST_TEST(hasher(containers[i2]) == hasher(containers[i2]));
BOOST_TEST(hasher(containers[i2]) ==
HASH_NAMESPACE::hash_value(containers[i2]));
BOOST_HASH_TEST_NAMESPACE::hash_value(containers[i2]));
BOOST_TEST(hasher(containers[i2])
== HASH_NAMESPACE::hash_range(
== BOOST_HASH_TEST_NAMESPACE::hash_range(
containers[i2].begin(), containers[i2].end()));
for(int j2 = i2 + 1; j2 < number_of_containers; ++j2) {
@@ -59,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, unsigned char>*) 0);
integer_tests((CONTAINER_TYPE<int, float>*) 0);
@@ -68,6 +71,10 @@ namespace BOOST_PP_CAT(CONTAINER_TYPE, _tests)
}
}
#if defined(__GNUC__) && __GNUC__ == 8
# pragma GCC diagnostic pop
#endif
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2006-2009 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "./config.hpp"
// Simple test to make sure BOOST_HASH_NO_EXTENSIONS does disable extensions
// (or at least one of them).
#if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
#endif
#ifdef TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
#endif
template <class T> void ignore(T const&) {}
int main()
{
HASH_NAMESPACE::hash< int[10] > hasher;
ignore(hasher);
return 0;
}
+7 -7
View File
@@ -5,32 +5,32 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# if defined(BOOST_HASH_NO_EXTENSIONS)
# undef BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# 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>
int main()
{
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::deque<int> x;
x.push_back(1);
x.push_back(2);
HASH_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
BOOST_HASH_TEST_NAMESPACE::hash<std::deque<int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();
+7 -7
View File
@@ -5,32 +5,32 @@
#include "./config.hpp"
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
// Include header with BOOST_HASH_NO_EXTENSIONS defined
# if !defined(BOOST_HASH_NO_EXTENSIONS)
# define BOOST_HASH_NO_EXTENSIONS
# endif
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
// Include header without BOOST_HASH_NO_EXTENSIONS defined
# 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>
int main()
{
#if defined(TEST_EXTENSIONS)
#if defined(BOOST_HASH_TEST_EXTENSIONS)
std::map<int, int> x;
x.insert(std::map<int, int>::value_type(53, -42));
x.insert(std::map<int, int>::value_type(14, -75));
HASH_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));
BOOST_HASH_TEST_NAMESPACE::hash<std::map<int, int> > hasher;
BOOST_TEST(hasher(x) == BOOST_HASH_TEST_NAMESPACE::hash_value(x));
#endif
return boost::report_errors();
+69 -41
View File
@@ -5,19 +5,17 @@
#include "./config.hpp"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
#endif
#include <iostream>
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/functional/hash/detail/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/container_hash/detail/limits.hpp>
#include <boost/core/enable_if.hpp>
#include "./compile_time.hpp"
@@ -28,15 +26,41 @@
#pragma warning(disable:4310) // cast truncates constant value
#endif
#if ( defined(__GNUC__) || defined(__clang__) ) && !defined(BOOST_INTEL_CXX_VERSION)
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
template <class T>
void numeric_test(T*)
void numeric_extra_tests(typename
boost::enable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
typedef boost::hash_detail::limits<T> limits;
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
template <class T>
void numeric_extra_tests(typename
boost::disable_if_c<boost::hash_detail::limits<T>::is_integer,
void*>::type = 0)
{
}
template <class T>
void numeric_test(T*)
{
compile_time_tests((T*) 0);
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T v1 = (T) -5;
BOOST_TEST(x1(v1) == x2(v1));
@@ -47,23 +71,13 @@ void numeric_test(T*)
BOOST_TEST(x1(T(5) - T(5)) == x2(T(0)));
BOOST_TEST(x1(T(6) + T(4)) == x2(T(10)));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == HASH_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == HASH_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == HASH_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == HASH_NAMESPACE::hash_value(T(25)));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(T(-5)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(-5)));
BOOST_TEST(x1(T(0)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(0)));
BOOST_TEST(x1(T(10)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(10)));
BOOST_TEST(x1(T(25)) == BOOST_HASH_TEST_NAMESPACE::hash_value(T(25)));
if (limits::is_integer)
{
if(limits::is_signed ||
limits::digits <= boost::hash_detail::limits<std::size_t>::digits)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(T(-5)) == (std::size_t)T(-5));
}
BOOST_TEST(HASH_NAMESPACE::hash_value(T(0)) == (std::size_t)T(0u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(10)) == (std::size_t)T(10u));
BOOST_TEST(HASH_NAMESPACE::hash_value(T(25)) == (std::size_t)T(25u));
}
numeric_extra_tests<T>();
#endif
}
@@ -74,8 +88,8 @@ void limits_test(T*)
if(limits::is_specialized)
{
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
T min_value = (limits::min)();
T max_value = (limits::max)();
@@ -83,16 +97,14 @@ void limits_test(T*)
BOOST_TEST(x1(min_value) == x2((limits::min)()));
BOOST_TEST(x1(max_value) == x2((limits::max)()));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == HASH_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == HASH_NAMESPACE::hash_value(max_value));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(min_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(min_value));
BOOST_TEST(x1(max_value) == BOOST_HASH_TEST_NAMESPACE::hash_value(max_value));
if (limits::is_integer)
{
BOOST_TEST(HASH_NAMESPACE::hash_value(min_value)
== std::size_t(min_value));
BOOST_TEST(HASH_NAMESPACE::hash_value(max_value)
== std::size_t(max_value));
BOOST_TEST_EQ(BOOST_HASH_TEST_NAMESPACE::hash_value(min_value), std::size_t(min_value));
BOOST_TEST_EQ(BOOST_HASH_TEST_NAMESPACE::hash_value(max_value), std::size_t(max_value));
}
#endif
}
@@ -103,8 +115,8 @@ void poor_quality_tests(T*)
{
typedef boost::hash_detail::limits<T> limits;
HASH_NAMESPACE::hash<T> x1;
HASH_NAMESPACE::hash<T> x2;
BOOST_HASH_TEST_NAMESPACE::hash<T> x1;
BOOST_HASH_TEST_NAMESPACE::hash<T> x2;
// A hash function can legally fail these tests, but it'll not be a good
// sign.
@@ -112,14 +124,19 @@ void poor_quality_tests(T*)
BOOST_TEST(x1(T(1)) != x2(T(-1)));
if(T(1) != T(2))
BOOST_TEST(x1(T(1)) != x2(T(2)));
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()
{
HASH_NAMESPACE::hash<bool> x1;
HASH_NAMESPACE::hash<bool> x2;
BOOST_HASH_TEST_NAMESPACE::hash<bool> x1;
BOOST_HASH_TEST_NAMESPACE::hash<bool> x2;
BOOST_TEST(x1(true) == x2(true));
BOOST_TEST(x1(false) == x2(false));
@@ -144,6 +161,12 @@ int main()
NUMERIC_TEST(unsigned char, uchar)
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
NUMERIC_TEST(wchar_t, wchar)
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
NUMERIC_TEST(char16_t, char16)
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
NUMERIC_TEST(char32_t, char32)
#endif
NUMERIC_TEST(short, short)
NUMERIC_TEST(unsigned short, ushort)
@@ -157,6 +180,11 @@ int main()
NUMERIC_TEST_NO_LIMITS(boost::ulong_long_type, ulong_long)
#endif
#if defined(BOOST_HAS_INT128)
NUMERIC_TEST_NO_LIMITS(boost::int128_type, int128)
NUMERIC_TEST_NO_LIMITS(boost::uint128_type, uint128)
#endif
NUMERIC_TEST(float, float)
NUMERIC_TEST(double, double)
+90
View File
@@ -0,0 +1,90 @@
// Copyright 2005-2009 Daniel James.
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/container_hash/hash.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/core/type_name.hpp>
#include <set>
#if defined(BOOST_MSVC)
# pragma warning(disable: 4244) // conversion from int to float
#endif
#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
// This test checks for collisions in a small range of numbers
template<class T, int M>
void collision_test_()
{
std::set<std::size_t> hashes;
for( int i = -128; i <= 127; ++i )
{
hashes.insert( boost::hash<T>()( i * M ) );
}
BOOST_TEST_EQ( hashes.size(), 256u );
}
template <class T>
void collision_test()
{
collision_test_<T, 1>();
collision_test_<T, 2>();
collision_test_<T, 3>();
collision_test_<T, 4>();
collision_test_<T, 5>();
collision_test_<T, 8>();
collision_test_<T, 10>();
collision_test_<T, 16>();
collision_test_<T, 32>();
collision_test_<T, 64>();
collision_test_<T, 100>();
collision_test_<T, 128>();
}
#define TEST(type) std::cerr << "Testing: " #type " (" << boost::core::type_name<type>() << ")\n"; collision_test<type>();
int main()
{
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
TEST(wchar_t)
#endif
#ifndef BOOST_NO_CXX11_CHAR16_T
TEST(char16_t)
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
TEST(char32_t)
#endif
TEST(short)
TEST(unsigned short)
TEST(int)
TEST(unsigned int)
TEST(long)
TEST(unsigned long)
#if !defined(BOOST_NO_LONG_LONG)
TEST(boost::long_long_type)
TEST(boost::ulong_long_type)
#endif
#if defined(BOOST_HAS_INT128)
TEST(boost::int128_type)
TEST(boost::uint128_type)
#endif
TEST(float)
TEST(double)
TEST(long double)
TEST(std::size_t)
TEST(std::ptrdiff_t)
return boost::report_errors();
}
+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 !defined(BOOST_NO_CXX17_HDR_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 !defined(BOOST_NO_CXX17_HDR_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"
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# 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 <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include "./compile_time.hpp"
void pointer_tests()
@@ -24,8 +20,8 @@ void pointer_tests()
compile_time_tests((int**) 0);
compile_time_tests((void**) 0);
HASH_NAMESPACE::hash<int*> x1;
HASH_NAMESPACE::hash<int*> x2;
BOOST_HASH_TEST_NAMESPACE::hash<int*> x1;
BOOST_HASH_TEST_NAMESPACE::hash<int*> x2;
int int1;
int int2;
@@ -33,9 +29,9 @@ void pointer_tests()
BOOST_TEST(x1(0) == x2(0));
BOOST_TEST(x1(&int1) == x2(&int1));
BOOST_TEST(x1(&int2) == x2(&int2));
#if defined(TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == HASH_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == HASH_NAMESPACE::hash_value(&int2));
#if defined(BOOST_HASH_TEST_EXTENSIONS)
BOOST_TEST(x1(&int1) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int1));
BOOST_TEST(x1(&int2) == BOOST_HASH_TEST_NAMESPACE::hash_value(&int2));
// This isn't specified in Peter's proposal:
BOOST_TEST(x1(0) == 0);
+27 -30
View File
@@ -5,23 +5,20 @@
#include "./config.hpp"
#if !defined(TEST_EXTENSIONS)
#if !defined(BOOST_HASH_TEST_EXTENSIONS)
int main() {}
#else
#ifdef TEST_STD_INCLUDES
#ifdef BOOST_HASH_TEST_STD_INCLUDES
# include <functional>
#else
# include <boost/functional/hash.hpp>
# include <boost/container_hash/hash.hpp>
#endif
#include <boost/detail/lightweight_test.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/limits.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <vector>
void hash_range_tests()
@@ -43,39 +40,39 @@ void hash_range_tests()
std::vector<int> x;
std::size_t x_seed = 0;
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(values1.begin(), values1.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(values1.begin(), values1.end()));
x.push_back(10);
HASH_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 10);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
x.push_back(20);
HASH_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_HASH_TEST_NAMESPACE::hash_combine(x_seed, 20);
BOOST_TEST(x_seed == BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(empty.begin(), empty.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values2.begin(), values2.end())
!= HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(HASH_NAMESPACE::hash_range(values3.begin(), values3.end())
== HASH_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(empty.begin(), empty.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values2.begin(), values2.end())
!= BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
BOOST_TEST(BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end())
== BOOST_HASH_TEST_NAMESPACE::hash_range(x.begin(), x.end()));
std::size_t seed =
HASH_NAMESPACE::hash_range(values3.begin(), values3.end());
HASH_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
HASH_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(values3.begin(), values3.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, values4.begin(), values4.end());
BOOST_HASH_TEST_NAMESPACE::hash_range(seed, x.begin(), x.end());
BOOST_TEST(seed ==
HASH_NAMESPACE::hash_range(values5.begin(), values5.end()));
BOOST_HASH_TEST_NAMESPACE::hash_range(values5.begin(), values5.end()));
}
int main()

Some files were not shown because too many files have changed in this diff Show More