Compare commits

...

1351 Commits

Author SHA1 Message Date
016d255851 Rework as esp-idf component 2023-11-23 17:17:05 +01:00
6b87a43162 Update benchmarking diagrams based on new erase(iterator) implementation 2022-07-27 08:29:03 -07:00
a4c6bf90aa Merge pull request #138 from cmazakas/feature/erase-perf
erase(iterator) perf
2022-07-27 14:41:07 +03:00
a31e894411 Update implementation to use erase_node() where applicable 2022-07-25 11:35:38 -07:00
91e78fd746 Add erase_node() function to table, creating an optimizer-friendly function 2022-07-25 11:35:23 -07:00
3abe5de533 Switch from macos-10.15 (deprecated) to macos-11 2022-07-22 20:44:54 +03:00
dfa3c7311f Remove unnecessary RNG 2022-07-22 19:12:39 +03:00
2c5b8577aa Add tsl::robin_map to string.cpp 2022-07-22 19:10:50 +03:00
4e804a9d4d Add tsl::robin_map to uint64.cpp, string_view.cpp 2022-07-22 18:52:47 +03:00
0ca8c5f56f Add tsl::robin_map to uint32.cpp 2022-07-22 18:36:50 +03:00
912798e5cb Change uint64.cpp to use byteswapped indices instead of shifted indices 2022-07-22 18:22:34 +03:00
5bcdd7fdf0 Change uint32.cpp to use byteswapped indices instead of shifted indices 2022-07-22 18:18:35 +03:00
78ffc4c192 Fix tsl allocator 2022-07-01 19:32:19 +03:00
966b76182f Add tsl::hopscotch_map to string_view.cpp 2022-07-01 19:28:57 +03:00
b7101494f2 Add tsl::hopscotch_map to string.cpp 2022-07-01 19:15:28 +03:00
be467b3dc4 Add tsl::hopscotch_map to uint64.cpp 2022-07-01 19:03:52 +03:00
ee70d96c75 Add tsl::hopscotch_map to uint32.cpp 2022-07-01 18:48:10 +03:00
8fbd380879 Merge pull request #136 from cmazakas/feature/prime-fmod-cleanup
`prime_fmod_size` cleanup
2022-07-01 17:58:38 +03:00
7746518c0a Remove conditional usage of #pragma once from fca.hpp and prime_fmod.hpp, reorder config.hpp inclusion to come last 2022-06-30 13:07:11 -07:00
c8a98e27e0 Add boost:: namespace qualification to uint64_t and uint32_t for prime_fmod.hpp 2022-06-30 13:07:11 -07:00
3df902af23 Pull prime_fmod_size into its own dedicated header, update #include list for fca.hpp and prime_fmod_test.hpp 2022-06-30 13:07:11 -07:00
45542e26cb Update ci.yml 2022-06-30 12:29:47 +03:00
49f73b118c Update .appveyor.yml 2022-06-30 05:23:44 +03:00
6e3dcfddb0 Merge branch 'feature/gha' into develop 2022-06-28 14:19:00 +03:00
09088045ac Merge pull request #135 from boostorg/bugfix/gcc-4-6-is_nothrow_swappable
bypassed check in GCC<=4.6 (boost::is_nothrow_swappable not properly …
2022-06-28 10:09:02 +02:00
e466232757 bypassed check in GCC<=4.6 (boost::is_nothrow_swappable not properly supported) 2022-06-28 09:27:15 +02:00
2ccd6654c1 Update ci.yml 2022-06-28 03:29:35 +03:00
7d7a6b881e Merge pull request #134 from boostorg/bugfix/gcc-4-7
Bugfix/gcc 4 7
2022-06-27 21:48:25 +02:00
9661227d00 Merge remote-tracking branch 'remotes/origin/bugfix/gcc-4-7-scoped_allocator' into bugfix/gcc-4-7 2022-06-27 20:39:07 +02:00
5855c67d4d added Drone support to this branch 2022-06-27 20:35:59 +02:00
3edfe2b76f Merge branch 'develop' into bugfix/gcc-4-7-scoped_allocator 2022-06-27 20:35:27 +02:00
f36bfe24f6 added Drone support to this branch 2022-06-27 20:35:01 +02:00
9da4b3a45a Merge branch 'develop' into bugfix/gcc-4-7-ref-qualified_memfuns 2022-06-27 20:34:06 +02:00
95524a6af4 bypassed scoped_allocator test for GCC 4.7 and prior 2022-06-27 19:58:22 +02:00
d4b61541b5 used proper Boost.Config macro 2022-06-27 19:31:47 +02:00
143c378ba6 Update test/Jamfile 2022-06-27 20:24:25 +03:00
dfac93aebb workaround for lack of ref-qualified memfun support in GCC<=4.7 2022-06-27 19:21:34 +02:00
b6daca37d5 Update test/Jamfile 2022-06-27 19:56:22 +03:00
4937619ea0 Update .drone.jsonnet 2022-06-27 19:55:23 +03:00
6d34532301 Add Drone support 2022-06-27 18:53:36 +03:00
fb733483c6 made fast_modulo universally available in 64 bits and never used in 32 bits 2022-06-26 19:13:54 +02:00
2670bb149d added Peter Dimov's portable implementation of get_remainder 2022-06-25 17:35:43 +02:00
d49eda63f8 Merge branch 'feature/prime-fmod-tests' into develop 2022-06-25 04:21:20 +03:00
08e0fee141 Enable fastmod on clang-cl and other pretenders such as Intel 2022-06-25 01:44:14 +03:00
d204b9b408 Remove unnecessary include 2022-06-25 01:17:50 +03:00
c53e0228c5 Check BOOST_UNORDERED_FCA_HAS_64B_SIZE_T in the 32 bit case as well 2022-06-25 01:16:32 +03:00
31cffd8412 Fix reversed condition 2022-06-25 01:06:15 +03:00
0f71fe28a2 Fix typos; do not undefine macros needed for tests 2022-06-25 01:04:22 +03:00
f00a29d3df Add tests for the internal prime_fmod_size policy 2022-06-24 11:09:38 -07:00
e111389d6c Update .appveyor.yml 2022-06-24 01:03:53 +03:00
7079341416 Merge pull request #130 from cmazakas/bugfix/cmake-subdir-dependencies
Update the list of required dependencies for the subdir CML test
2022-06-23 03:53:02 +03:00
7fdbfc0c1a Update the list of required dependencies in for the CMake subdirectory test 2022-06-22 14:42:09 -07:00
e1dff1c931 Merge pull request #128 from cmazakas/feature/iterator-independence
Remove dependencies on Iterator, Detail
2022-06-21 21:45:12 +03:00
90b2536a99 Relace usage of BOOST_FORCEINLINE with plain inline to prevent warnings from certain versions of msvc 2022-06-21 08:42:52 -07:00
97f54318e3 Add Boost::concept_check to CMake test suite dependencies 2022-06-21 08:42:52 -07:00
f1481f0deb Remove dependency on Boost.Detail 2022-06-21 08:42:52 -07:00
b1a9cde690 Remove dependency on Boost.Iterator 2022-06-21 08:42:52 -07:00
1ed2a0a0f1 Merge pull request #127 from cmazakas/doc-updates
1.80 Doc Updates
2022-06-16 12:46:33 -07:00
759645cab6 Merge pull request #126 from cmazakas/img-link-fixes
Fix broken image links for VS benchmarks (successful lookup)
2022-06-16 08:57:49 -07:00
3203251539 Update changelog for 1.80 release 2022-06-16 07:52:37 -07:00
b84b94b4db Update copyright notice for documentation 2022-06-16 07:52:27 -07:00
3dd77edd16 Pull benchmarks into their own file 2022-06-14 08:50:28 -07:00
a24165083f Fix link paths for VS successful lookup benchmarks 2022-06-14 08:16:39 -07:00
8878482ca1 Merge pull request #125 from cmazakas/develop-build-instructions
Add PREVIEW markdown file
2022-06-10 09:06:59 -07:00
19c7bbf97d Add PREVIEW markdown file containing instructions for how to quickly build Boost from the tip of develop 2022-06-10 09:03:18 -07:00
23f15947d3 Merge pull request #122 from Flamefire/readme
Add LICENSE and README
2022-06-09 13:50:20 -07:00
152129bf70 Merge pull request #121 from Flamefire/appveyor_ci
Update Appveyor from Boost.CI
2022-06-09 11:02:38 -07:00
20ac32c34c Merge pull request #114 from Flamefire/ci
Update GithubActions CI from boost-ci
2022-06-09 11:02:32 -07:00
707b40e8c2 Workaround Segfault of Clang 3.8
Clang 3.8 segfaults during name mangling of `make_index_seq`.
Hence replace it by using type aliases.
2022-06-09 11:04:20 +02:00
0d1d9f4634 CI: Test only default (shared) linkage on GHA
As there is no actual compiled library there is no need to test shared
and static linking. This effectively halfes the number of compile jobs.
2022-06-09 11:04:20 +02:00
5a64ca48ad Update CI from boost-ci
Sync with upstream adding improved CMake builds and coverage collection
2022-06-09 11:04:20 +02:00
f4ddf18124 Add LICENSE and README
Show project description and CI badges on the repo site.
2022-06-09 10:40:52 +02:00
657cf68e55 Remove unused download-boost-snapshot.py file
Boost.CI is now used.
2022-06-09 10:19:23 +02:00
f0013a4d65 Split jobs which take over 1h to complete and timeout
See #120
2022-06-08 21:26:15 +02:00
83fe0249b3 Allow MinGW32 and Cygwin-latest jobs to fail
Needs some more work
2022-06-08 21:26:15 +02:00
3701199cfa Update Appveyor from Boost.CI
Adds MinGW, Cygwin and newer compilers
2022-06-08 21:26:15 +02:00
4b56bfac05 Merge pull request #119 from cmazakas/laundry
Fix `-Wmaybe-unitialized` warning in gcc-12
2022-06-07 20:55:32 +03:00
613a997694 Fix -Wmaybe-unitialized warning in gcc-12 by laundering the result of reinterpret_cast<> in functions helper 2022-06-07 09:03:48 -07:00
e690e8910c Merge branch 'feature/gha-gcc12-nosan' into develop 2022-06-03 22:54:39 +03:00
34b9a8d21f Merge pull request #118 from cmazakas/fastmod-cleanup
Rename functions used to efficiently calculate modulo
2022-06-03 20:02:42 +02:00
0106ed3d91 Rename functions used to efficiently calculate modulo, update associated comments 2022-06-03 09:28:17 -07:00
f8342e4b04 Add a GCC 12 job without sanitization 2022-06-03 17:08:51 +03:00
8a74b192b0 Merge pull request #117 from Flamefire/clang3_8_compat
Fix compilation on Clang < 3.8
2022-06-03 16:49:43 +03:00
d0ac539d09 Fix compilation on Clang < 3.8
`val_alloc` is used in the other branch of the #ifdef too.
2022-06-03 11:07:49 +02:00
0be4856144 Add GCC 12, Clang 13, 14 to ci.yml 2022-06-03 05:41:53 +03:00
7503b85f6a Add posix-cmake-subdir, posix-cmake-install jobs to ci.yml 2022-06-03 01:36:57 +03:00
4a9abf20b3 Add test/cmake_install_test, test/cmake_subdir_test 2022-06-03 01:35:32 +03:00
2836bb5c41 Merge branch 'feature/quick-test' into feature/gha-cmake 2022-06-03 01:29:56 +03:00
e2925ba01b Add test/quick.cpp 2022-06-02 22:53:12 +03:00
f2724b745b Regenerate CMakeLists.txt 2022-06-02 21:46:56 +03:00
712d20079a Fix alignment_of include 2022-06-02 21:46:07 +03:00
99a5409b39 Merge branch 'develop' into feature/gha-cmake 2022-06-02 21:41:51 +03:00
72fe06aa00 Remove unused include, removes dependency on Detail 2022-06-02 19:15:12 +03:00
8081a3f9ff Add CMake tests to ci.yml 2022-06-02 18:43:12 +03:00
f218f9b5a2 Add test/CMakeLists.txt 2022-06-02 18:41:31 +03:00
4e38751187 Update test/Jamfile.v2 2022-06-02 18:41:14 +03:00
e36e3bcf96 Merge pull request #112 from boostorg/feature/fca-unordered
Update internal implementation to use FCA
2022-06-01 15:44:05 -07:00
18503e5eb8 Update documentation for new FCA implementation 2022-06-01 11:49:09 -07:00
110c5dcf10 Remove unnecessary test files due to FCA refactor 2022-06-01 11:49:09 -07:00
37f5a462e4 Update reserve_tests to handle the space requirements for new FCA implementation 2022-06-01 11:49:09 -07:00
a1fb756831 Fix bug in rebind semantics for test allocator in reserve_tests 2022-06-01 11:49:09 -07:00
5a456eb295 Refactor internal implementation to use "fast closed-addressing" aka fca 2022-06-01 11:49:09 -07:00
ad639ffb61 Lower version of dinkumware check as msvc-12.0 supports piecewise construction 2022-06-01 11:49:09 -07:00
2ae686c366 Add tests for testing the SCARY-ness of iterators 2022-06-01 11:49:09 -07:00
641c9fba9c Update operator() implementations for predicate classes to properly return a bool 2022-06-01 11:49:09 -07:00
8473d8120f Mark test Hasher and KeyEqual as final to extend test coverage 2022-06-01 11:49:09 -07:00
954db4e246 Extend fancy pointer types used by test allocators to support a wider array of semantic operations 2022-06-01 11:49:09 -07:00
4f43bc5ec7 Add missing #include for usage of BOOST_TEST macro 2022-06-01 11:49:09 -07:00
0bcc79baab Update test allocators to be C++11 compliant by making them templates on the pointer type 2022-06-01 11:49:09 -07:00
e7d34a5ab1 Remove unsupported Windows image from GHA CI 2022-05-20 13:53:40 -07:00
33f81fd490 Add benchmark/string_view.cpp 2022-03-08 02:44:30 +02:00
a1c156cec1 Rearrange and comment out the non-FNV-1a tests in string.cpp 2022-03-08 02:37:13 +02:00
3d62482fe9 Add missing multiplication by sizeof(T) 2022-03-08 02:06:21 +02:00
470c9ffed0 Add memory measurements to string.cpp 2022-03-08 01:31:59 +02:00
49c70046e4 Add memory measurements to uint32.cpp 2022-03-08 01:06:04 +02:00
ff1b01bd10 Add memory measurements to uint64.cpp 2022-03-07 22:14:58 +02:00
5bcb07dc7f Add BOOST_NOINLINE to benchmark test functions 2022-03-07 21:43:36 +02:00
35475a260f Merge pull request #111 from cmazakas/missing-initializer-list-constructors-fixes
Add missing `initializer_list` constructors to reference docs
2022-03-04 08:16:11 +02:00
3d377ec0f3 Add missing initializer_list constructors to reference docs 2022-03-02 15:45:38 -08:00
bca33372c2 Merge pull request #110 from cmazakas/equal-range-reference-docs-fixes
Add missing `std::` qualification to usages of `pair` in the reference
2022-03-02 21:10:38 +02:00
96696b33c4 Merge pull request #109 from cmazakas/unordered-map-reference-doc-fixes
`unordered_map` reference doc fixes
2022-03-02 20:35:55 +02:00
5772941057 Add missing std:: qualification to initializer_list 2022-03-01 11:08:07 -08:00
d676ad814b Add missing std:: qualification to usages of pair in the reference docs 2022-03-01 07:50:29 -08:00
5f9fdb0b15 Add reference docs for map's insert_or_assign 2022-02-28 14:37:57 -08:00
0f44fd0064 Add reference docs for map's try_emplace() 2022-02-28 14:37:57 -08:00
ceba60831c Merge pull request #108 from cmazakas/insert-doc-fixes
`insert()`/`extract()` doc fixes + test improvements
2022-02-26 04:01:30 +02:00
fd90df5d54 Merge pull request #107 from cmazakas/merge-doc-updates
Correct reference docs for `merge()`
2022-02-26 04:00:56 +02:00
3fe2c29204 Update documentation on extract/insert to no longer say that transferring nodes between the corresponding multi- container is not supported 2022-02-25 13:59:00 -08:00
55d4aaeef5 Update node_handle_tests to prove that nodes can be safely transferred between plain maps/sets and their multi- versions 2022-02-25 13:58:09 -08:00
71d3b77668 Correct reference docs for merge() 2022-02-24 14:54:28 -08:00
0d3ece98c1 Merge pull request #106 from cmazakas/missing-nodiscard
Add missing `[[nodiscard]]` qualifiers as outlined by C++20
2022-02-24 18:00:00 +02:00
3dc83e4075 Merge pull request #105 from cmazakas/feature/erase_if
Implement `erase_if`
2022-02-24 17:55:30 +02:00
b57ac04728 Update reference docs to include [[nodiscard]] annotations 2022-02-23 14:43:28 -08:00
3d952d3c0f Add missing [[nodiscard]] qualifiers as outlined by C++20 2022-02-23 14:26:28 -08:00
0897423e69 Update Change Log for erase_if() 2022-02-23 11:56:19 -08:00
b994ddf894 Add reference docs for erase_if() 2022-02-23 11:56:08 -08:00
c322cc5621 Implement erase_if() for Unordered via function template in detail namespace 2022-02-23 11:36:48 -08:00
d943283f80 Add test case for erase_if() 2022-02-23 11:36:48 -08:00
995707a43e Add Abseil+FNV-1a to benchmark/string.cpp 2022-02-20 20:08:27 +02:00
107b5e6ab9 Merge pull request #104 from cmazakas/reference-refactor
Clean Up Reference
2022-02-18 22:11:29 +02:00
2e0fdf7eb4 Update description lists for unordered_multiset 2022-02-18 10:41:46 -08:00
14ecf54d8a Update unordered_multiset refernce to follow new synopsis 2022-02-18 10:41:46 -08:00
c6bdeae570 Update unordered_multiset synopsis to be modelled after the standard 2022-02-18 10:41:46 -08:00
2d539a9b8f Clean up formatting of description lists for unordered_set 2022-02-18 10:41:46 -08:00
8e1f05082e Update unordered_set reference to follow its new synopsis 2022-02-18 10:41:46 -08:00
170d86be9a Update unordered_set synopsis to be consistent with the standard 2022-02-18 10:41:46 -08:00
d810b2d073 Clean up formatting of description lists for unordered_multimap 2022-02-18 10:41:46 -08:00
e948bab4d9 Update unordered_multimap reference to be consistent with new synopsis 2022-02-18 10:41:46 -08:00
7bed1417b9 Update unordered_multimap synopsis to be modelled after the standard 2022-02-18 10:41:46 -08:00
f7eea71b0b Add colons to text in description lists in unordered_map reference 2022-02-18 10:22:14 -08:00
a0eee06c16 Add whitespace to description lists for unordered_map 2022-02-18 10:22:14 -08:00
b7c013c1e8 Update unordered_map descriptions lists to use [horizontal] formatting 2022-02-18 10:22:14 -08:00
1ee2eaf5e9 Reorder unordered_map reference docs to match the order found in the synopsis 2022-02-18 10:22:14 -08:00
fe55012007 Refactor unordered_map synopsis to follow the layout of the standard 2022-02-18 10:22:14 -08:00
42eb31e7e1 Merge pull request #98 from cmazakas/insert-api-doc-fixes
Fix API docs to show the correct return type for emplace/insert
2022-02-14 22:41:02 +02:00
83423adc05 Fix API docs to show the correct return type for emplace/insert for multimap and multiset 2022-02-14 12:30:31 -08:00
b019f17590 Merge pull request #97 from cmazakas/missing-insert-docs
Add missing reference docs for member function template `insert`
2022-02-14 18:42:01 +02:00
e58ba2e044 Add missing reference docs for member function template insert for unordered_map/multimap 2022-02-14 08:27:13 -08:00
79ca8e968c Reenable warnings-as-errors 2022-02-12 03:35:29 +02:00
5a095c3771 Merge pull request #96 from cmazakas/unknown-warning-fix
Refactor tests to disable `-Wself-assign-overloaded` themselves
2022-02-12 03:34:39 +02:00
65094532eb Merge pull request #95 from cmazakas/unitialized-warning-fix
Fix asan unitialized warning
2022-02-12 02:08:27 +02:00
13caa6691c Merge pull request #94 from cmazakas/transparent-test-warning-fixes
Fix signed/unsigned comparison warnings in the transparent test suite
2022-02-12 01:53:44 +02:00
bcd1770a46 Merge pull request #93 from cmazakas/key_eq-shadowing-fix
Fix shadowing warning in early versions of gcc
2022-02-12 01:53:24 +02:00
aa96d87502 Fix shadowing warning in early versions of gcc 2022-02-11 11:33:46 -08:00
d20be2aaf8 Refactor tests to disable -Wself-assign-overloaded themselves instead of in the Jamfile as not all clang versions support the warning 2022-02-11 11:33:11 -08:00
d2ded394f6 Fix asan unitialized warning when default-initialized int is copied as a return type 2022-02-11 11:30:47 -08:00
2b8f458a38 Fix signed/unsigned comparison warnings in the transparent test suite 2022-02-11 11:29:31 -08:00
e3a7ec6aed Merge pull request #92 from cmazakas/reserve-tests-signed-comparison-fixes
Fix signed/unsigned comparison warning in reserve tests
2022-02-11 08:23:24 +02:00
93f9fd7206 Merge pull request #91 from cmazakas/self-assign-warning-fixes
Disable clang-specific warning about self-assignment
2022-02-11 08:10:40 +02:00
28915fdce0 Fix signed/unsigned comparison warning in reserve tests 2022-02-10 14:57:22 -08:00
497455d281 Disable clang-specific warning about self-assignment in tests that explicitly aim to test self-assigment 2022-02-10 12:37:39 -08:00
c758cbda5e Temporarily disable warnings-as-errors 2022-02-10 22:30:22 +02:00
4655133843 Merge branch 'feature/warnings-as-errors' into develop 2022-02-10 22:29:07 +02:00
672a97cb34 Merge pull request #90 from cmazakas/contains-c4800-warning-fixes
Fix C4800 warnings in msvc by manually comparing pointers to 0
2022-02-10 22:28:37 +02:00
0f8cc79c00 Enable warnings-as-errors for clang and msvc 2022-02-10 20:55:47 +02:00
e2b6865938 Fix C4800 warnings in msvc by manually comparing pointers to 0 2022-02-10 08:37:53 -08:00
bf0bc6468a Avoid -Wsign-conversion warning in mix_policy.cpp 2022-02-10 18:22:52 +02:00
526bf15c3c Update test/Jamfile 2022-02-10 03:58:40 +02:00
bdfb0e3e25 Update ci.yml 2022-02-10 01:27:59 +02:00
2d6ebf16d8 Merge pull request #87 from cmazakas/docs-cleanup
Docs Cleanup
2022-02-10 01:20:52 +02:00
13c62043eb Merge pull request #89 from cmazakas/nonnull-warnings-fix
Use `boost::declval` in test metafunctions to avoid `-Wnonnull` warnings
2022-02-10 01:19:14 +02:00
39d60cd91d Update test metafunction to use boost::declval instead of using null pointers 2022-02-09 11:51:23 -08:00
aaf79c5202 Merge pull request #88 from cmazakas/scoped-allocator-test-fixes
Refactor scoped allocator test to use a custom Allocator
2022-02-09 21:29:29 +02:00
884c790009 Disable scoped_allocator test for msvc-14.0 as a stdlib defect in its scoped_allocator_adaptor requires DefaultConstructible for Allocators 2022-02-09 09:53:07 -08:00
5e5dbf5984 Refactor scoped allocator test to use a custom non-default-constructible Allocator instead of Intrerprocess which required a dep on Filesystem 2022-02-09 09:52:56 -08:00
0794cfec9e Avoid -Wlong-long in mix64_policy 2022-02-09 07:13:27 +02:00
a878374d28 Disable warnings when building boost_filesystem 2022-02-09 07:12:54 +02:00
120861bf55 Add change log note about AsciiDoc conversion 2022-02-07 12:51:19 -08:00
b7514e1e04 Clean up wording on Iterator Invalidation to recommend using reserve() 2022-02-07 12:33:56 -08:00
da390e3959 Shorten Change Log section titles to "Release <version>" 2022-02-07 09:29:42 -08:00
3062759ca8 Update docs to refer to the "draft standard" simply as the "standard" 2022-02-07 09:15:01 -08:00
cb4b417f76 Merge pull request #86 from cmazakas/qbk-cleanup
Remove obsoleted documentation files
2022-02-07 17:56:45 +02:00
ef951094b3 Remove obsoleted documentation files 2022-02-07 07:45:28 -08:00
b14aefa1d3 Update index.html 2022-02-01 02:35:29 +02:00
aa7c11a873 Document switch to Fibonacci hashing 2022-02-01 02:29:58 +02:00
b871699103 Merge pull request #84 from boostorg/feature/asciidoc
Convert Docs to AsciiDoc
2022-02-01 02:10:30 +02:00
8b946ec36d Add reference docs for unordered_multiset 2022-01-31 11:38:51 -08:00
da73e1eda9 Add reference docs for unordered_multimap 2022-01-31 11:38:51 -08:00
cd8716400b Add ref docs for unordered_set 2022-01-31 11:38:51 -08:00
854ab0b151 Add reference docs for unordered_map 2022-01-31 11:38:51 -08:00
c1c98e16d3 Add Copyright section to AsciiDoc 2022-01-31 11:38:51 -08:00
1ee99268f1 Add Bibliography section to AsciiDoc 2022-01-31 11:38:51 -08:00
403ed3abaf Add Rationale section to AsciiDoc 2022-01-31 11:38:51 -08:00
de2ae678a9 Add Comparison section to AsciiDoc 2022-01-31 11:38:51 -08:00
45c92568a1 Add section on Pred/Hasher to AsciiDoc 2022-01-31 11:38:51 -08:00
2f455409e2 Add Buckets section to AsciiDoc 2022-01-31 11:38:51 -08:00
55bdde560a Convert intro to AsciiDoc 2022-01-28 14:31:31 -08:00
4e249125eb Update compliance section to AsciiDoc 2022-01-28 14:31:31 -08:00
1f0ba0198b Convert Change Log to AsciiDoc 2022-01-28 14:31:31 -08:00
145ccc77d6 Update Jamfile to build AsciiDoc and add corresponding file stubs 2022-01-28 14:31:31 -08:00
1cb0908961 Change random indices in string.cpp to differ in size; remove shifted consecutive there as not representative 2022-01-20 02:06:00 +02:00
1db7fbad66 Add FNV-1a cases for std::unordered_map, multi_index_map to benchmark/string.cpp 2022-01-19 19:33:34 +02:00
7d79b35f93 Avoid warnings in tests 2022-01-19 18:57:28 +02:00
2f331b7a8b Update mix64_policy to use Fibonacci hashing 2022-01-19 04:11:08 +02:00
d96d5335b4 Update mix32_policy to use Fibonacci hashing 2022-01-19 04:01:46 +02:00
4c2150fb3d Minor updates to benchmark/string.cpp 2022-01-19 03:50:39 +02:00
2751b3515b Add bcount_log2_ to table, pass it to the policy 2022-01-19 02:33:37 +02:00
76b36a81ca Merge branch 'develop' into feature/mix_policy 2022-01-19 02:11:21 +02:00
3eb244898f Add an FNV-1a case to benchmark/string.cpp 2022-01-19 02:10:23 +02:00
7aacf9836c Merge branch 'develop' into feature/mix_policy 2022-01-19 01:42:05 +02:00
24eeb67275 Update reserve_tests to pass for power of two resize policy 2022-01-18 22:12:57 +02:00
bf86730a62 Add mix32_policy 2022-01-18 21:31:53 +02:00
98494420c5 Add a BOOST_ASSERT to mix64_policy to check that the bucket_count is a power of two 2022-01-18 20:52:05 +02:00
7717ff01a1 Use bit_ceil and bit_floor in mix64_policy 2022-01-18 20:40:23 +02:00
5c3576c7c6 Add test/unordered/mix_policy.cpp 2022-01-18 20:17:31 +02:00
d6576ed2f1 Remove the special case in pick_policy for integral types (refs #50) 2022-01-18 19:25:32 +02:00
9a61c8f8dd Add benchmark/string.cpp 2022-01-15 02:58:28 +02:00
d192ec8fae Add benchmark/uint32.cpp 2022-01-15 02:46:47 +02:00
fe913577f6 Merge pull request #83 from cmazakas/contains-doc-updates
`contains()` Doc Updates
2022-01-14 23:56:22 +02:00
312d00cc33 Update reference docs to include contains() 2022-01-14 13:51:47 -08:00
c3ac504c10 Update changelog to include notes on contains() 2022-01-14 10:38:30 -08:00
5d94f0eea6 Merge pull request #82 from cmazakas/multiset-contains
Implement `unordered_multiset::contains()`
2022-01-14 05:34:04 +02:00
97734fd895 Implement unordered_multiset::contains() 2022-01-13 12:51:50 -08:00
596e1ce135 Add tests for unordered_multiset::contains() 2022-01-13 12:51:50 -08:00
e1c58b4584 Merge pull request #81 from cmazakas/set-contains
Implement `unordered_set::contains()`
2022-01-13 21:27:22 +02:00
f5d470c531 Implement unordered_set::contains() 2022-01-13 08:03:54 -08:00
a87277c6e8 Add tests for unordered_set::contains() 2022-01-13 08:03:54 -08:00
6700ecaf43 Merge pull request #80 from cmazakas/multimap-contains
Implement `unordered_multimap::contains()`
2022-01-13 07:29:19 +02:00
ad8a11bb49 Implement unordered_multimap::contains() 2022-01-12 12:57:27 -08:00
ce2051ed39 Add tests for unordered_multimap::contains() 2022-01-12 12:57:27 -08:00
d16989ce55 Merge pull request #79 from cmazakas/map-contains
Implement `unordered_map::contains()`
2022-01-12 22:43:05 +02:00
a26e1c0f41 Implement unordered_map::contains() 2022-01-12 10:36:40 -08:00
510267f6e9 Add tests for unordered_map::contains() 2022-01-12 10:36:36 -08:00
8e6a5e19c2 Merge pull request #78 from cmazakas/feature/test-suite-ub-fixes
Fix integer overflow UB in test suite
2022-01-11 21:11:08 +02:00
21244ab832 Fix UB caused by integer overflow in hash functions by casting int to unsigned 2022-01-11 09:53:38 -08:00
7a64f1634f Update CI to run sanitizers on the latest compilers for posix systems 2022-01-10 13:55:14 -08:00
2d8268d3d0 Merge pull request #77 from cmazakas/changelog-fixes
Revert usage of sub-`[section]`s with `[heading]`s
2022-01-10 21:51:50 +02:00
f6b96e4984 Revert usage of sub-[section]s with [heading]s 2022-01-10 11:49:40 -08:00
7fd972d669 Merge pull request #75 from cmazakas/release-notes-1.79
Release Notes 1.79
2022-01-07 21:07:07 +02:00
42190df874 Update ref.xml 2022-01-07 08:30:34 -08:00
19673e3b1c Update reference docs for erase() to include heterogeneous overloads 2022-01-07 08:30:34 -08:00
b6b334dd16 Update reference docs for extract() to include heterogeneous overload 2022-01-07 08:30:34 -08:00
a8443abe80 Update docs for equal_range() to include heterogeneous overloads 2022-01-07 08:30:34 -08:00
49b630c2d4 Update reference docs for count() to include heterogeneous overloads 2022-01-07 08:30:34 -08:00
cd56cae032 Update reference docs for find() to include heterogeneous overloads 2022-01-07 08:30:34 -08:00
6c74aa0289 Add changelist for 1.79.0 release 2022-01-07 08:30:34 -08:00
8ce147dcbd Update change list to use separate sections for each changelist 2022-01-07 08:30:28 -08:00
7f51c8dba4 Rearrange contents of the changelog so that notes for newer release precede notes for older ones 2022-01-05 12:31:33 -08:00
7c2ba681e9 Merge pull request #74 from cmazakas/multiset-heterogeneous-extract
Multiset Heterogeneous `extract()`
2022-01-05 20:47:51 +02:00
1c459e6ee6 Implement heterogeneous extract() for multiset 2022-01-05 08:14:58 -08:00
f6a077e102 Add transparent test support for multiset's extract() 2022-01-05 08:14:58 -08:00
b797862a91 Merge pull request #73 from cmazakas/set-heterogeneous-extract
Set Heterogeneous `extract()`
2022-01-05 01:53:29 +02:00
abc7327116 Implement heterogeneous extract() for set 2022-01-04 11:50:20 -08:00
7c58a8247c Add transparent test support for set's extract() 2022-01-04 11:50:20 -08:00
263150e599 Rename transparent extract tests to include map in their name 2022-01-04 11:50:20 -08:00
7a177d6ac0 Merge pull request #72 from cmazakas/multiset-heterogeneous-count
Multiset Heterogeneous `count()`
2022-01-04 21:40:31 +02:00
d5e5c08b87 Implement heterogeneous count() for multiset 2022-01-04 09:05:17 -08:00
c485bc975a Add transparent test support for multiset's count() 2022-01-04 09:05:17 -08:00
2dfdaca3eb Merge pull request #71 from cmazakas/set-heterogeneous-count
Set Heterogeneous `count()`
2022-01-04 18:32:29 +02:00
56f11f94d8 Implement heterogeneous count() for set 2022-01-03 15:48:51 -08:00
ccbe691cc8 Add transparent test support for set's count() 2022-01-03 15:48:51 -08:00
f8b53c1cf7 Rename transparent count tests to include map in their name 2022-01-03 15:48:51 -08:00
c920354423 Merge pull request #70 from cmazakas/multiset-heterogeneous-erase
Multiset Heterogeneous `erase()`
2022-01-04 01:40:41 +02:00
1ab8cc4c0f Implement heterogeneous erase() for multiset 2022-01-03 13:54:06 -08:00
3aa62a821a Add transparent test support for multiset's erase() 2022-01-03 13:54:06 -08:00
ecf76830a5 Update transparent erase() tests to delete single elements for the multi-containers 2022-01-03 13:53:55 -08:00
ce6ca0cf9d Merge pull request #69 from cmazakas/multiset-heterogeneous-find
Multiset Heterogeneous `find()`
2022-01-03 19:52:07 +02:00
202a438044 Implement heterogeneous find() for multiset 2022-01-03 07:59:36 -08:00
d7ffd48c67 Add transparent test support for multiset's find() 2022-01-03 07:59:36 -08:00
7440e7f789 Merge pull request #68 from cmazakas/multiset-heterogeneous-equal-range
Multiset Heterogeneous `equal_range()`
2022-01-01 07:23:31 +02:00
f813bbdf86 Implement heterogeneous equal_range() for multiset 2021-12-29 10:36:23 -08:00
2656bfbcac Add transparent test support for multiset's equal_range() 2021-12-29 10:36:23 -08:00
dc95efea1a Update transparent equal_range() tests to check for ranges of length 1 for multi-containers 2021-12-29 10:36:17 -08:00
81e7e4dd81 Merge pull request #67 from cmazakas/set-heterogeneous-equal-range
Set Heterogeneous `equal_range()`
2021-12-29 01:42:39 +02:00
57a2b65488 Implement heterogeneous equal_range() for set 2021-12-27 12:20:52 -08:00
b23e47c478 Add transparent test support for set's equal_range() 2021-12-27 12:20:47 -08:00
ff4ca3098b Rename transparent equal_range() tests to include map in their name 2021-12-27 09:01:07 -08:00
b6f8363023 Merge pull request #66 from cmazakas/set-heterogeneous-erase
Set Heterogeneous `erase()`
2021-12-24 02:28:40 +02:00
9c07cf60a6 Deprecate table::erase_key_unique() 2021-12-23 13:12:52 -08:00
36324af017 Implement heterogeneous erase() for set 2021-12-23 13:03:08 -08:00
31392ce1aa Add transparent test support for set's erase() 2021-12-23 13:03:08 -08:00
6cf039eecc Rename transaparent erase tests to include map in their name 2021-12-23 13:03:07 -08:00
79ab9800c0 Merge pull request #65 from cmazakas/set-heterogeneous-find
Set Heterogeneous `find()`
2021-12-23 21:39:53 +02:00
05373cbb6b Implement heterogeneous find() for set 2021-12-23 09:54:12 -08:00
1b009da4d0 Add transparent test support for set's find() 2021-12-23 09:45:39 -08:00
b39b6b7635 Rename transparent find tests to specify that they're for maps specifically 2021-12-23 09:45:26 -08:00
c2d3713f40 Update key type in transparent tests to be comparable with plain ints 2021-12-23 09:45:17 -08:00
c4345c809e Add ostream support for key type used in transparent tests 2021-12-23 09:39:13 -08:00
c761934868 Merge pull request #64 from cmazakas/multimap-heterogeneous-count
Multimap Heterogeneous `count()`
2021-12-23 01:26:26 +02:00
77c4a09a9b Implement heterogeneous count() for multimap 2021-12-22 12:59:52 -08:00
58326b8fff Add transparent test support for multimap's count() 2021-12-22 12:59:45 -08:00
ee5d4b9e73 Remove unnecessary was_called_ statics from transparent test's key comparators 2021-12-22 11:23:57 -08:00
e667e6dbd9 Merge pull request #63 from cmazakas/multimap-heterogeneous-extract
Multimap Heterogeneous `extract()`
2021-12-22 01:29:48 +02:00
ec288246d0 Implement heterogeneous extract() for multimap 2021-12-21 13:22:18 -08:00
71c332803a Add transparent test support for multimap's extract() 2021-12-21 13:22:18 -08:00
5e30830cb9 Merge pull request #62 from cmazakas/multimap-heterogeneous-erase
Multimap Heterogeneous `erase()`
2021-12-21 20:41:12 +02:00
57054f7451 Implement heterogeneous erase() for multimap 2021-12-21 09:27:00 -08:00
1c6c085127 Update unordered_map to use singular type trait for erase() / extract() SFINAE 2021-12-21 09:27:00 -08:00
ff4d25d454 Add transparent_non_iterable type trait for usage in erase() / extract() SFINAE 2021-12-21 09:27:00 -08:00
85cb09ae6d Add erase_key_equiv_impl() member function 2021-12-21 09:27:00 -08:00
854a5aa3c3 Add transparent test support for multimap's erase() 2021-12-21 09:27:00 -08:00
bde33a1d6a Merge branch 'feature/appveyor' into develop 2021-12-21 01:44:55 +02:00
8d98d8752b Remove msvc-14.2 from Appveyor (in GHA); split clang-win to avoid timeout 2021-12-21 00:47:54 +02:00
cebeb4ea5f Update test/Jamfile 2021-12-21 00:46:45 +02:00
a3a27a9a6c Merge branch 'feature/appveyor' into develop 2021-12-20 22:31:55 +02:00
973c72bdf0 Merge pull request #61 from cmazakas/multimap-heterogeneous-equal-range
Multimap Heterogeneous `equal_range()`
2021-12-20 22:15:56 +02:00
7bdd180c30 Use clang-win from VS2019 on Appveyor 2021-12-20 21:31:28 +02:00
19d2fe8738 Implement heterogeneous equal_range() for multimap 2021-12-20 09:28:04 -08:00
3d5a2d26d1 Add test support for multimap's equal_range() 2021-12-20 09:26:17 -08:00
4e37a14bf8 Update transparent equal_range() tests to use BOOST_TEST_EQ where applicable 2021-12-20 08:41:06 -08:00
91500344d4 Merge pull request #60 from cmazakas/multimap-heterogeneous-find
Multimap heterogeneous `find()`
2021-12-17 21:06:16 +02:00
d8fe1a17cc Replace usage of compound is_transparent type trait with singular usage of are_transparent 2021-12-17 09:53:16 -08:00
9945ce7583 Implement heterogeneous find() for multimap 2021-12-17 09:53:16 -08:00
54d36f89ea Add find() test support for multimap 2021-12-17 09:53:04 -08:00
193cf30780 Update find() tests to use BOOST_TEST_EQ 2021-12-15 14:14:26 -08:00
ab8c09fcb9 Merge pull request #59 from cmazakas/reserve-fixes
Fix behavior of `reserve()` to match the STL implementations
2021-12-15 21:23:32 +02:00
1db53ba155 Update internal table to allocate on construction and when rehashing 2021-12-15 09:42:44 -08:00
b41bb5c595 Add failing test case for issue #12 2021-12-15 09:42:33 -08:00
c7676755ab Merge pull request #58 from cmazakas/deprecate-allocator-traits-macro
Remove unnecessary `allocator_traits` macro
2021-12-09 07:16:04 +02:00
4f88b3865f Remove unnecessary test 2021-12-08 14:15:22 -08:00
089d2db104 Remove traits detection mechanism 2021-12-08 14:04:04 -08:00
fefb6ad4c4 Remove unnecessary expression test mechanisms 2021-12-08 13:59:11 -08:00
05b795bc14 Remove unnecessary macro for determining which allocator_traits implementation is being used 2021-12-08 10:06:01 -08:00
ff3f5067c8 Merge pull request #56 from LeonineKing1199/feature/allocator-traits
Replace internal implementation of `allocation_traits` with Core's
2021-12-08 01:23:02 +02:00
0c54f60e17 Merge pull request #55 from LeonineKing1199/heterogeneous-extract
Heterogeneous Extract
2021-12-08 00:56:26 +02:00
82b33708ba Update allocator_traits test to only check for inherited SOCCC when the C++11 allocator is present 2021-12-07 11:21:43 -08:00
5b8289c05a Remove extraneous include of Boost.Container's allocator_traits 2021-12-07 10:49:39 -08:00
ea5cabb27f Update test to use two implicitly convertible types (const and non-const iterators) and the associated compile-time tests 2021-12-07 10:48:09 -08:00
a6b9fb285c Replace internal implementation of allocation_traits with Core's 2021-12-07 08:35:56 -08:00
4041d06e95 Clean up tests 2021-12-06 15:04:40 -08:00
13cd5aa4ce Implement initial draft of heterogeneous extract() 2021-12-06 13:06:05 -08:00
00b504ebc5 Merge pull request #54 from LeonineKing1199/heterogeneous-erase
Heterogeneous erase
2021-12-06 22:10:06 +02:00
afb83a6cb9 Refactor erase() tests to use BOOST_TEST_EQ where applicable 2021-12-06 08:52:02 -08:00
f5b03fb2e8 Pull out expressions with side-effects from the testing assertions 2021-12-06 08:30:57 -08:00
b8d3aa2a68 Light cleanup of test 2021-12-03 11:19:58 -08:00
52f154ec02 Flesh out test suite for heterogeneous erase() 2021-12-03 10:17:50 -08:00
e4d0693eb9 Fix erroneous placement of heterogeneous erase() from multimap to map 2021-12-03 10:08:30 -08:00
4a42c93897 Fix erroneous usage of table::hash() impl which implicitly copy-constructs the const_key_type 2021-12-03 10:07:57 -08:00
8b438dea76 Use erase_key_unique_impl() directly so that eventually erase_unique() can be deprecated 2021-12-03 08:48:20 -08:00
12977a50bc Add hopefully helpful comment to the source 2021-12-03 08:41:42 -08:00
33f84624ec Add initial draft of heterogeneous erase() 2021-12-02 15:59:12 -08:00
f252480bee Add missing formatting 2021-12-02 15:44:02 -08:00
c9df887c4c Add member function template erase_key_unique_impl for usage in heterogeneous lookups 2021-12-02 15:38:07 -08:00
03edf7f4a8 Add member function template find_previous_node_impl so it can be used in heterogenous contexts 2021-12-02 15:30:17 -08:00
a98a719546 Merge pull request #53 from LeonineKing1199/heterogeneous-equal-range
Implement heterogeneous `equal_range()` for `unordered_map`
2021-12-02 21:19:28 +02:00
a97483b928 Add test cases for empty UnorderedMaps for equal_range() 2021-12-02 09:42:30 -08:00
9955886ef5 Improve heterogeneous equal_range() test suite to check iterator distance and that the correct key was pulled, including when the map contains multiple keys 2021-12-02 09:18:24 -08:00
3646a7143e Add msvc-14.0, msvc-14.3 2021-12-02 18:32:30 +02:00
13f40e4333 Implement heterogeneous equal_range() for unordered_map 2021-12-01 09:39:07 -08:00
6249660e1f Merge pull request #51 from LeonineKing1199/heterogeneous-find
Heterogeneous `find()`
2021-11-30 18:32:24 +02:00
3eb2d3c4b3 Add comments about nature of test 2021-11-29 14:55:18 -08:00
8f1fc75fdf Implement heterogeneous find() 2021-11-29 14:37:04 -08:00
d3c37344f0 Vary top 24 bits of shifted indices instead of top 32 bits 2021-11-29 17:37:26 +02:00
5e8b6a9e55 Add comment describing the origin of mix64_policy::apply_hash 2021-11-29 06:14:20 +02:00
bbd0eedb5f Precompute indices to avoid clever optimizations 2021-11-29 04:54:47 +02:00
ad51b34438 Add benchmark/uint64.cpp 2021-11-29 02:49:12 +02:00
0d4b753409 Merge pull request #45 from LeonineKing1199/transparent-count-unordered_map
Transparent count unordered map
2021-11-24 01:50:28 +02:00
6f5727cbdb Clean up tests by pulling transparent tests into a named function 2021-11-23 14:14:26 -08:00
10e88d07af Merge pull request #41 from LeonineKing1199/deprecated-copy
Fix `-Wdeprecated-copy` warnings in test allocator
2021-11-23 22:34:08 +02:00
3f1e4a703a Clean up tests to be a bit more readable 2021-11-23 12:15:53 -08:00
bc9eca70d0 Remove unnecessary assignment operator for test key 2021-11-23 12:04:00 -08:00
69b882a14b Add defaulted copy assignment operators when supported 2021-11-23 11:10:03 -08:00
6984e6a4f2 Remove unnecessary move support 2021-11-23 10:57:26 -08:00
fd0cab2ab8 Remove out-of-line defintion for transparent count() to hopefully appease msvc-9.0 2021-11-22 15:43:28 -08:00
93216374ef Flesh out test suite to cover all permutations of transparent/non-transparent Hash & KeyEqual pairs 2021-11-22 13:30:10 -08:00
8ba710637a Remove detail::make_dependent in favor of an extra template parameter in is_transparetn 2021-11-22 13:29:41 -08:00
937c3484cf Flesh out test case 2021-11-22 12:27:29 -08:00
59db6cf788 Add SFINAE to transparent count() overload in unordered_map 2021-11-22 11:16:04 -08:00
f41b3e8295 Get initial prototype of transparent count() working 2021-11-19 15:29:57 -08:00
fe439890e8 Remove unneeded macro as Config defines BOOST_NOEXCEPT 2021-11-19 10:10:52 -08:00
e29f762116 Fix warning about using implicitly defined copy constructor/assignment by completing the Rule of 5 for test allocator 2021-11-19 10:10:52 -08:00
c8abaf32ee Merge pull request #40 from LeonineKing1199/sfinae-updates
Update SFINAE expressions to be in the return type
2021-11-19 04:32:06 +02:00
c0a9f638ce Merge pull request #37 from LeonineKing1199/memory-tracker-fixes
Replace `BOOST_TEST` call with `BOOST_ASSERT` to resolve testing woes
2021-11-19 04:26:33 +02:00
4a90ae5b0f Merge pull request #38 from LeonineKing1199/ambiguous-reversed-operator
Ambiguous reversed operator fixes
2021-11-19 04:25:45 +02:00
7ccd62ba98 Update SFINAE expressions to be in the return type instead of a defaulted function parameter 2021-11-18 12:54:17 -08:00
2e1ef850e3 Add const qualification to auto-generated allocator methods in test suite 2021-11-18 10:25:44 -08:00
dbba786a35 Add missing const-qualification for operator== member functions 2021-11-18 10:24:57 -08:00
d0d4be9e35 Add missing operator== overloads for direct list_iterator comparisons 2021-11-18 10:19:46 -08:00
2d69c7a5ca Add missing const-qualification of operator== for internal optional implementation 2021-11-18 10:19:20 -08:00
24a38922bd Replace BOOST_TEST call with BOOST_ASSERT to resolve https://github.com/boostorg/unordered/issues/36 2021-11-18 09:36:04 -08:00
1e553df5b6 Add explicit tests around use of scoped_allocator_adaptor to emulat… (#31)
* Add explicit tests around use of `scoped_allocator_adaptor` to emulate issue https://github.com/boostorg/unordered/issues/22

* Refine test to only run in C++11 mode and later with possibility of re-introducing C++03 support later

* Update test to use `<boost/cstdint.hpp>`

* Refactor test to use `UNORDERED_AUTO_TEST`

* Cleanup how the scoped allocator test is conditionally compiled

* Update test to generate a UUID for the name of the shared memory segment so tests can run safely in parallel

* Update test jamfile to relocate the Filesystem link dependency directly to the test that requires it
2021-11-15 21:22:40 +02:00
0f37f774f1 Merge branch 'develop' of https://github.com/yutakasi634/unordered into feature/pr-14 2021-09-01 04:15:55 +03:00
34c07ea148 Merge branch 'gcc-9-rvalue-ref-try-emplace' of https://github.com/LeonineKing1199/unordered into feature/pr-29 2021-08-31 22:02:10 +03:00
70fca4483e std::equal_to has no first_argument_type in C++20 2021-08-31 21:16:09 +03:00
b2b017accb Disable -Wfloat-equal for clang-cl as well 2021-08-31 21:10:52 +03:00
a97160cf57 Fix bug in has_construct by using std::declval 2021-08-29 12:13:56 -07:00
1d42f5b7b1 Merge pull request #20 from eldiener/develop
[skip ci] Add "cxxstd" json field
2021-08-29 14:50:13 +03:00
70ac0509df Update .appveyor.yml 2021-08-29 02:22:34 +03:00
f1678399af Remove cxxstd=2a from clang-9, 10 2021-08-28 17:00:31 +03:00
bae1f8ca82 Switch 16.04 jobs to 18.04 2021-08-28 16:53:45 +03:00
790c33d6a7 Re-add gcc-9 on 18.04 for contrast 2021-08-21 22:17:34 +03:00
a9f5da7799 Use 20.04 for gcc-9 and above 2021-08-21 21:03:48 +03:00
6a59e6db39 Disable variadic macro warnings from Boost.PP for gcc 2021-08-21 19:15:23 +03:00
76a44cff09 Disable cxxstd=2a for clang-8 2021-08-21 19:09:17 +03:00
e36dce52ba Disable variadic macro warnings from Boost.PP for clang 2021-08-21 19:08:40 +03:00
c31ace5fc8 Add .github/workflows 2021-08-21 19:03:57 +03:00
c494b3db58 Merge branch 'master' into develop 2021-05-29 05:28:09 +03:00
bf0c3c188e Add CMakeLists.txt 2021-03-18 17:29:38 +02:00
0f9f3eba72 [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-20 02:52:08 -05:00
0960f885d5 Merge branch 'develop' 2020-11-01 08:21:59 -05:00
33b28a514e Update .appveyor.yml 2020-08-24 12:41:56 +03:00
2497d663b7 Merge pull request #16 from eldiener/develop
Changes for Embarcadero C++ clang-based compilers, targeting Boost 1.74. Change __BORLANDC__ to BOOST_BORLANDC and __CODEGEARC__ to BOOST_CODE…
2020-08-24 12:39:36 +03:00
887f1dc07c Change __BORLANDC__ to BOOST_BORLANDC and __CODEGEARC__ to BOOST_CODEGEARC, which are3defined in Boost config for the Embarcadero non-clang-based compilers. 2020-03-31 22:47:48 -04:00
0d033679d4 Fix typo 2020-02-03 20:48:35 +09:00
9abce00f24 Merge branch 'develop' 2018-04-16 07:05:46 +01:00
f3649e4ae0 Use boost 1.67.0 in tests 2018-04-15 22:39:33 +01:00
6cf0342322 Stop using -Werror
So that it doesn't fail for warnings in other libraries.
2018-04-15 22:39:33 +01:00
3252ad1f4b Move download-boost-snapshot.py into ci directory
Because __boost_check_library__ is complaining about it.
2018-03-18 15:41:24 +00:00
741a10f5a8 Merge branch 'develop' 2018-03-06 22:27:23 +00:00
c39dd284d2 Boost 1.67.0 changelog 2018-03-05 14:20:14 +00:00
4e5c97f3a3 Merge branch 'develop'
- Various CI improvements, including appveyor support
- Stop using boost::next in tests, because of warnings
- Use std::iterator_traits, to drop dependency on iterator
- Use std::piecewise_construct from dinukumware/Visual C++
- Template deduction guides, just copied from the standard,
  they don't work that well. I think some other implementations
  enhance them
- Some internal changes
- Stop inheriting from std::iterator, deprecated in C++17 (#7)
- Implement allocator_traits::is_always_equal
- Rewrite node handles using a simple class based on std::optional,
  so that it's closer to the standard
- noexcept support for swap, operator=
- Fix some compiler warnings
- Fix some of the tests on Visual C++ 7.1
- Add element_type to iterators, so that pointer_traits will work
- Use boost::to_address internally, instead of own custom implementation
- Stop using BOOST_DEDUCED_TYPENAME - it's for very old compilers that are
  no longer supported, and makes the code look ugly
2018-02-25 14:06:04 +00:00
e10fc0f93b Fix typo 2018-02-25 14:03:11 +00:00
8207ebe381 Use bash to run bootstrap.sh
When using a zipfile it isn't marked as executable.
2018-02-09 09:00:45 +00:00
6491f6c10a Python script to download the latest snapshot for CI testing 2018-02-02 23:37:36 +00:00
cfd4bacc2c Stop using BOOST_DEDUCED_TYPENAME
We no longer support any of the compilers that require it. I'd be very
surprised if anything was working on them.
2018-01-27 09:39:59 +00:00
09be9bae04 Use boost::is_nothrow_swappable, now that it's available everywhere 2018-01-27 09:38:19 +00:00
c01a8c4629 Oops, it's boost::to_address, no boost::to_pointer 2018-01-26 20:25:09 +00:00
cdb0229cf2 Use snapshot to get latest pointer_traits 2018-01-26 20:01:29 +00:00
ddf302fcc2 Use boost::to_pointer instead of pointer<..>::get
To get C++20 style recursive calls to `operator->`.
2018-01-26 18:59:16 +00:00
ca9e9584ba Test on appveyor 2018-01-26 18:03:56 +00:00
0d34053870 Use boost::to_address in node_handle_tests 2018-01-26 17:47:47 +00:00
66533ace80 Add element_type to nodes, so that pointer_traits will work
Might be better to change the template signature of iterators, but that would
be a disruptive change to make at the moment.
2018-01-26 17:43:06 +00:00
ea599a66b7 Disable 'conditional expression is constant' on older Visual C++ 2018-01-23 15:40:58 +00:00
1cc3f680e8 Fix a couple more explicit default constructors for Visual C++ 7.1 2018-01-20 11:49:07 +00:00
f7665a2743 Another attempt to fix insert_exception_tests on Visual C++ 7.1
Try extracting the nested template structs.
2018-01-20 08:57:56 +00:00
dc9faddf22 Try to fix constructor_tests on Visual C++ 7.1
I'm really not sure why it fails to compile, the error message isn't very
helpful.  I assume it might be because allocator1 has an explicit default
constructor, so I tried making it implicit.
2018-01-17 10:40:58 +00:00
e64c5b34df Try to fix insert_exception_tests on Visual C++ 7.1
It doesn't seem to like the nested template structs. If this doesn't work, I'll
try moving them into the top level.
2018-01-17 10:24:07 +00:00
57492c1a94 Make allocator comparison const in allocator_traits test 2018-01-13 20:31:45 +00:00
df8fbca007 Double brackets for BOOST_STATIC_ASSERT 2018-01-13 20:31:45 +00:00
72fb9c7c96 Suppress warnings in noexcept_tests 2018-01-13 20:31:45 +00:00
ce0f16f328 Missing copyright messages 2018-01-10 15:15:09 +00:00
a477d70f32 Add explicit failure for noexcept_tests on gcc + fix description for Visual C++ 7.1 2018-01-10 11:46:13 +00:00
f3476de893 Some explicit casts to avoid warnings on old GCC 2018-01-10 11:35:42 +00:00
dea525b2b7 Suppress msvc waring "conditional expression is constant" 2018-01-10 11:35:22 +00:00
d55c9565ab No template arguments in BOOST_MOVABLE_BUT_NOT_COPYABLE
Was causing errors on Visual C++ 7.1.
2018-01-10 09:58:08 +00:00
00a4185cf1 Reformat 2018-01-08 10:58:09 +00:00
ea28a3f98e Fix conversion to bool warning 2018-01-08 10:57:28 +00:00
c8facc99a7 Run concurrent test processes in travis 2018-01-06 14:25:38 +00:00
d7ec41f4c6 Add final use of CXXSTD in travis 2018-01-06 14:14:59 +00:00
9f2063846b Build b2 from the source snapshot 2018-01-06 13:38:56 +00:00
c05c541216 Use boost build's new cxxstd feature 2018-01-06 13:37:04 +00:00
34e54b35e8 Manually handle assigning hash/equality functions 2018-01-06 12:53:37 +00:00
f12009fc61 operator= noexcept support 2018-01-05 17:54:44 +00:00
5854090dc7 Swap noexcept support
Not properly supported as we don't have is_nothrow_swappable yet.
2018-01-05 17:48:13 +00:00
7e28fdd45a Make the current function_pair public 2018-01-05 17:10:13 +00:00
daeaf5e98b Flexible exception testing hash/equal_to 2018-01-05 17:10:13 +00:00
4bffd7a85d Avoid some warnings 2018-01-04 18:29:31 +00:00
7615fabc80 Rewrite node handles using a lightweight limited optional
Will try to use std::optional when available. Also using
allocator_traits::is_always_equal support.
2018-01-03 23:15:55 +00:00
be0acc575f Implement allocator_traits::is_always_equal 2018-01-03 20:55:40 +00:00
9d558b010d Reformat 2017-12-28 11:44:57 +00:00
32773fb023 Merge pull request #7 from DanielaE/fix/no-iterator-inheritance
Inheriting std::iterator is deprecated in c++17.
2017-12-28 11:31:11 +00:00
64441d2b64 Inheriting std::iterator is deprecated in c++17.
Therefore get rid of all of that and replace inheritance by lifting std::iterator's members into the derived class.

Signed-off-by: Daniela Engert <dani@ngrt.de>
2017-12-28 12:01:41 +01:00
07758b7af8 Catch exceptions by reference 2017-12-22 17:02:13 +00:00
92ce66be64 Rename 'bucket' variable to avoid shadow warning 2017-12-22 16:54:05 +00:00
15befe998e Rename table::get_bucket to get_bucket_pointer
All the other '*_bucket' methods return a bucket index.
2017-12-22 16:44:43 +00:00
b50e0d610f Initial implementation of template deduction guides 2017-12-19 12:56:51 +00:00
f99dee1917 Use predef for detecting piecewise construction
And detect it for recent dinkumware.
2017-12-19 12:11:36 +00:00
6327d174d2 Test C++17 mode in travis 2017-12-19 12:11:35 +00:00
c2b9b22f67 Use 1.66.0 in tests 2017-12-19 12:10:53 +00:00
311e126ac4 Remove dependency on iterator 2017-12-03 18:58:52 +00:00
c037169e1a Update paths for headers moved from detail 2017-12-03 14:24:47 +00:00
9bb861accc Use std::advance in test::next, and use it instead of boost::next
Mainly to avoid warnings from boost::next
2017-12-01 08:35:38 +00:00
ecd5b239a4 Use appropriate snapshot when testing on travis 2017-12-01 07:57:29 +00:00
a600ef6cbb Merge branch 'develop' 2017-11-11 18:38:48 +00:00
b90da4a802 1.66.0 release notes 2017-11-10 15:12:37 +00:00
c50ba694a5 Use quickbook 1.7 2017-11-10 15:12:09 +00:00
8f7b7ca7b3 Update clang format comment for 4.0.0 2017-10-29 16:52:46 +00:00
adfc7f4d5d Generate ref.xml 2017-10-28 22:58:21 +01:00
9e18dc1401 Oops, fix properly 2017-10-28 17:36:25 +01:00
cf76763ab7 Fix node handle description 2017-10-28 17:34:28 +01:00
fb7ef4cf63 Build documentation using consistent ids 2017-10-25 01:16:59 +01:00
04a0909105 Merge branch 'develop' 2017-10-22 16:12:47 +01:00
613f154d47 Improved test formatting 2017-10-09 12:34:47 +01:00
978944fab2 Use same code for move constructing all containers
Copies the data layout from the source, so it doesn't need to hash anything.
2017-10-05 10:56:02 +01:00
705e69aefd Always call set_first_in_group
Probably don't need to, as we're using 0 for the first element in a group, but
it's quick so might as well.
2017-10-05 10:54:23 +01:00
e58081f6dc Drop some TODOs that are okay 2017-10-05 10:54:22 +01:00
4ac8a45a34 The max_load issue was fixed in the standard ages ago 2017-10-05 10:54:22 +01:00
6b5b968b97 Format with clang-format 4.0 2017-10-05 10:54:22 +01:00
2ab82ad653 Merge branch 'develop' 2017-10-02 18:00:09 +01:00
86df284ad4 Add explicit-failures-markup.xml 2017-10-02 17:34:51 +01:00
3521c87e17 Merge branch 'develop'
Documentation fixes.
2017-09-19 11:04:08 +01:00
32533f7325 Merge branch 'develop'
Formatting changes
2017-09-19 11:03:26 +01:00
0e19bdf50a Documentation fixes 2017-09-07 22:56:54 +01:00
f72b0353d4 Shuffle code around for readability
The new indentation made some of the code difficult to read, especially
where macros were concerned, so move things around and add more explicit
namespace declarations.
2017-06-11 20:55:59 +01:00
0676b4f4ca Change clang format indentation + .editorconfig file 2017-06-11 20:55:59 +01:00
929982357a Merge branch 'develop' 2017-06-11 20:54:52 +01:00
5190a5d7f8 Stop dereferencing pointers to uninitialized memory
It's undefined behaviour. Still happens for piecewise construction
emultation for std::pair, I don't think there's anyway to avoid it.
I had considered using offsetof to get a pointer to a member, but that's
also undefined behaviour when a pair member doesn't have standard
layout. Piecewise construction emulation has other problems anyway.

So, this mostly fixes PR #5.

I also stopped using addressof in self-asssignment checks as operator&
is fine.
2017-06-04 08:47:02 +01:00
7775aa83df Decrease the limit for SunOS workaround
We have tests for 12.5 (5,20,0), and 12.5_next (5,21,0), I think both
are good enough to not require workarounds.
2017-05-25 08:53:34 +01:00
fc1604f2c8 Don't use allocator_traits::construct on GCC 4.6
Piecewise construction doesn't work uncopyable types.
2017-05-19 17:24:44 +01:00
5b97fbc292 Make insert from node_handle move only on old GCC 2017-05-19 09:42:56 +01:00
4f5a2dabe9 Try to fix std::tuple on old Sun compilers
In order to use the workaround for both `boost::tuple` and `std::tuple`
the function would need to detect which was being used, in order to
decide whether to use `boost::tuples::length` or `std::tuple_size`.
Probably not difficult, but I don't have any way to test an
implementation.

So instead Just assume that if `std::tuple` is available it will work
without any workaround. Presumably once the compiler was able to support
`std::tuple` it will also support the necessary overloads.

I've left the version check as 5.21 so that failures will still show up
in the tests, but I'm sure it can be 5.20 and probably earlier.  Will
change before release.
2017-05-19 09:03:08 +01:00
e0227618bb Move a few things around to match the order in the standard 2017-05-17 16:47:57 +01:00
ee9a5a2c77 Add a configuration macro for Sun C++ workarounds 2017-05-16 19:01:50 +01:00
6fffc738f7 Require std::tuple for full C++11 construction 2017-05-16 18:15:56 +01:00
dc611fc828 Run fewer test in merge_exception_tests
It's timing out on some platforms because it's too slow. This reduces
the tag combinations for 9 to 3, which should reduce the execution time
by a third. Also slightly reduces the count combinations, but that won't
make much of a difference really - the slowest tests are still there
(when the right hand side is large).
2017-05-14 02:59:22 +01:00
12ee29579d Don't use full construction on Sun C++ w. libstdc++
There's an exception safety issue. Which is a pity as other than that it
seems fine. I'd assumed that support would be pretty good on all C++11
compilers, so I made it an 'all or nothing' feature, partly because
there are issues with pre-C++11 allocators, but this suggests partial
support might be desirable. Not sure I'll be able to (or want to) put
the time in though.
2017-05-12 21:58:52 +01:00
a897843f6c Try to work around an MSVC bug
Although, perhaps I shouldn't be generating over 1000 runs for a test.
2017-05-11 00:36:31 +01:00
80de85f217 Move test state + functions into single class 2017-05-10 19:02:47 +01:00
242e91a9fd "Sub-test" reporting mechanism 2017-05-10 19:02:47 +01:00
ca80237191 Create fewer classes in merge_exception_tests
Will need better error reporting capabilities. Makes RUN_TESTS_QUIET
redundant?
2017-05-10 19:02:47 +01:00
b95ef6de04 Generate less output in merge_exception_tests 2017-05-10 19:02:47 +01:00
76e7322262 Use streams from lightweight test 2017-05-10 19:02:47 +01:00
3c42138e45 Fix testing piecewise_construct and tuple
For when std::piecewise_construct is available, but std::tuple isn't. In
order to test better, just repeat the tests with the four possible
combinations.
2017-05-08 18:42:53 +01:00
1b0b38a519 try_emplace, insert_or_assign exception tests 2017-05-07 18:47:59 +01:00
9119a42b7d Factor insert_exception_tests for better code reuse 2017-05-07 18:47:24 +01:00
8af4b37d14 Rewrite insert exception tests
Not going to do this for all the tests. It's more effort than I
expected.
2017-05-07 17:54:34 +01:00
31c5b5bfa1 Merge exception tests 2017-05-07 17:54:34 +01:00
b6c6bfbe7f Statically handle 'is_unique' in assignments 2017-05-06 04:58:57 +01:00
6e074d7165 Get rid of delete_nodes 2017-05-06 04:58:57 +01:00
0489069419 Use 'limited_range' to catch error in exception tests
This would have caught the error fixed in 3fe259a79e.
2017-05-06 04:47:59 +01:00
597eb5a3fd Repeat the assign/insert exception tests a few times 2017-05-06 04:47:59 +01:00
3fe259a79e Fix creating exception::less from exception::equal_to 2017-05-05 12:58:26 +01:00
6ef17a0f0e Remember to disable exceptions before checking final value 2017-05-05 00:46:07 +01:00
47a8c3fc67 Fix exception handling in rehash_impl
And improve tests so they will catch the error, and other similar errors.
2017-05-04 19:30:18 +01:00
d49d0e90a8 Delete nodes directly instead of through previous node 2017-05-04 00:14:08 +01:00
77bd45b1fa Make second parameter of delete_nodes a node_pointer 2017-05-04 00:14:05 +01:00
622dff50df Fix some code that could be using next_node 2017-05-03 23:36:09 +01:00
41f6a051ef Some more configuration comments 2017-05-03 04:21:53 +01:00
d05619095c Workaround problems with forward_as_tuple in older versions of clang 2017-05-03 04:21:52 +01:00
2f8492d720 Fix libc++ configuration 2017-05-03 04:21:52 +01:00
7911f491f6 Try using own allocator_traits with Sun compiler
The good news is that the old Sun workarounds aren't needed any more.
Unfortunately, there are a lot of exception test errors for
unordered_map and unordered_multimap when using libstdc++, which
probably means that std::pair isn't exception safe, which is a bit odd.
But first try using our allocator_traits implementation instead of the
standard one to see if that makes a difference. If it doesn't then I'll
probably just disable C++11 construction on this compiler, which should
fix the problem but will make allocators less useful.
2017-05-03 04:21:52 +01:00
d84a57441b Use the unordered container for the fake merge in merge test
The merge tests into containers with unique keys are failing on some
platforms. My guess is that because of differences between ordering of
nodes with equivalent keys that different nodes are being 'merged' in
the unordered containers and the tracker containers. So when creating
the fake merge, use the unordered container as a reference. This is a
little less pure, but should be a good enough test.
2017-05-01 22:16:13 +01:00
b8c754d230 Set the high bit in bucket_info_ to false for first node in group
And true for the reset, so that in containers with unique keys
bucket_info_ is always just the bucket index.
2017-05-01 21:03:11 +01:00
338a94e577 Better rvalue emulation support in extractors
Means that inserting rvalues into unordered_set/unordered_map won't
create a node if no insert is required.
2017-05-01 21:03:11 +01:00
2e14c340a8 Reformat 2017-05-01 21:03:11 +01:00
35522d3ee0 Fix merging between containers with different hash/equality
This reverts commit 20b0c0a6d8.
2017-04-30 14:29:05 +01:00
8c139940e7 More merge tests between compatible containers 2017-04-30 14:29:05 +01:00
7b5f73f6c2 Disable all sunpro workarounds on latest version
I have no idea if they're still working. I wasn't able to run the latest
solaris in a virtual machine on my computer, so this is the only way to
test.
2017-04-30 10:44:54 +01:00
e7a3487df4 Remove policy template parameter from local iterators 2017-04-30 10:44:54 +01:00
c243895fc0 Remove odd check that should never be true
I think it was left over from the old grouped node implementation.
2017-04-30 10:44:54 +01:00
451d0f2fc5 Constructing nodes is nothrow, so no need to track 2017-04-30 10:43:06 +01:00
c75b332240 Cleaner create_buckets implementation 2017-04-30 10:43:06 +01:00
899248acbf Avoid shadow warning on older versions off GCC 2017-04-29 09:31:17 +01:00
cae6b121b2 Improve test coverage a little 2017-04-28 21:26:21 +01:00
5f6ee3da9c Use coveralls 2017-04-28 09:53:50 +01:00
bfcdd51b4a Fix try_emplace overload 2017-04-28 09:53:50 +01:00
10b736d407 Remove BOOST_UNORDERED_CALL_CONSTRUCT0 2017-04-28 09:53:50 +01:00
0b61e6defb Stop using allocators to construct/destroy internal types
The standard doesn't allow it. I should have known that.
2017-04-27 19:02:10 +01:00
28f529100d Merge branch 'feature/simpler-data-structure' into develop
C++17 requires that unordered_map has the same type of node as
unordered_multimap, and that unordered_set has the same type of node as
unordered_multiset. This didn't seem particularly useful to me and
contradicts the old implementation which had different nodes, I put a
lot of effort into trying to abstract out the difference and make it
selectable using a macro, so that the old implementation would still by
available for anyone who doesn't care about strict compatibility.

But I think that was a mistake, it was making things too complicated and
for too little gain. The default would still be inefficient containers
for equivalent keys, and using the macro could lead to problems down the
line.

So I've switched to using a much simpler implementation which just marks
the first node in a group of equivalent nodes. This isn't as fast when
there are a lot of elements with equivalent keys - it can't skip to the
end of a group of nodes, but at least it avoids having to do a lot of
potentially expensive comparisons.

It's also a lot closer to the intent of the standard, even if I disagree
with that intent.
2017-04-27 18:22:53 +01:00
6466ce0b51 Make table the same for unique and equivalent keys 2017-04-27 18:22:44 +01:00
03baef8b28 Remove Types::is_unique 2017-04-27 18:22:44 +01:00
f1435d53d4 Remove 'init' method from nodes 2017-04-27 18:22:44 +01:00
20b0c0a6d8 Only consider one node from each group in merge_unique 2017-04-27 18:22:44 +01:00
a1b1df84a0 Store bucket + whether first in group in node
Instead of the hash value.
2017-04-27 18:22:44 +01:00
408ebd0a0a Add node_bucket function 2017-04-27 18:22:44 +01:00
e9c4696544 Get rid of node_algo 2017-04-27 18:22:43 +01:00
ea64f2e46e Remove the grouped node stuff 2017-04-27 18:22:43 +01:00
94a3a9baf9 Fix some quickbook markup 2017-04-25 21:14:11 +01:00
da27ae4de6 Group together similar overloads of try_emplace 2017-04-25 20:20:11 +01:00
ed326e2c87 Expand out more preprocessor repeats 2017-04-25 20:20:11 +01:00
bea4c6e29b undef some macros 2017-04-25 20:20:11 +01:00
61df9479e5 Rename unique_node 2017-04-25 20:20:11 +01:00
e3ab7b5d2e Remove BOOST_UNORDERED_EMPLACE_ARGSn macros
They're not used anywhere now.
2017-04-25 20:20:11 +01:00
679b73098e Option to use grouped nodes everywhere
Seems to work okay, but I'm not happy with and of the options. So I'm
going to look into doing something else before the next release.
2017-04-25 09:54:28 +01:00
cba643fc51 Make setting max_load_ a tad more consistent 2017-04-25 09:54:28 +01:00
1c8edf0298 Remove early exit for empty containers 2017-04-25 09:54:28 +01:00
07b9a7d60e Fix incorrect try_emplace call 2017-04-25 01:39:30 +01:00
9c8980e6a1 Write out epoint that threw an exception after failure 2017-04-25 01:21:44 +01:00
60127d86e0 After 5 failures stop running an exception test 2017-04-25 01:10:53 +01:00
0c3c738614 Better C++ version info 2017-04-25 01:09:07 +01:00
c8bacbcb00 Merge branch 'feature/combine-unique-equiv-tables' into develop
Expanding a lot of the call to the implementation methods. While working
on some recent changes, I felt the call chains in error messages were
too long, this reduces that a little. It also should make debugging a
tad easier and I think it makes the methods a little more informative,
as you can see what they're doing without hunting around the
implementation file. Also reduces the number of symbols when compiling,
although I'm not sure if that will make much of a difference.

Does make the code a little long, and duplicated, but I don't think it's
particularly harmful.
2017-04-24 09:46:05 +01:00
b070bb5e49 Move everything from table_unique/table_equiv into table 2017-04-24 09:46:05 +01:00
e518120104 Rename some copy/assign/move methods
But with a hack so that the static casts will work until there's a
better method.
2017-04-24 09:46:05 +01:00
84f1ef6d2d Move constructor implementation into containers 2017-04-24 09:46:05 +01:00
77bf2b5e33 Rename methods to be different for unique/equiv keys
So that the implementation can be moved into a single class. Still some
other methods to rename. Some methods didn't need to be renamed (e.g.
try_emplace is only used with unique keys), but still renamed for
consistency.
2017-04-24 09:46:05 +01:00
8229aa6b3c Stop throwing exception in allocator copy/assignment
The standard specifies that all of these "shall not exit via an
exception". The containers have been exception safe when these throw,
but the 'noexcept' attribute on 'get_allocator' will terminate if an
exception is thrown in the copy constructor.

The standard doesn't specify a default constructor, so that is allowed
to throw an exception (not just pedantry, this makes sense if an
allocator has shared data that's allocated in the initial constructor).
2017-04-23 11:01:04 +01:00
fc08f62d6a Remove a TODO 2017-04-23 10:51:17 +01:00
1254520438 Merge branch 'feature/expand-calls' into develop
Expanding a lot of the call to the implementation methods. While working
on some recent changes, I felt the call chains in error messages were
too long, this reduces that a little. It also should make debugging a
tad easier and I think it makes the methods a little more informative,
as you can see what they're doing without hunting around the
implementation file. Also reduces the number of symbols when compiling,
although I'm not sure if that will make much of a difference.

Does make the code a little long, and duplicated, but I don't think it's
particularly harmful.
2017-04-23 10:46:27 +01:00
7941771d61 Expand calls to at implementation 2017-04-23 10:09:18 +01:00
4f1c6e1ebf Expand calls to init/move_init 2017-04-23 10:09:18 +01:00
13ff1e7fb1 Expand calls to count and equal_range implementation 2017-04-23 10:09:18 +01:00
25b0b66e52 Expand calls to erase implementation
Doesn't work as well as the previous changes.
2017-04-23 10:09:18 +01:00
da835e88b8 Expand calls to insert_range 2017-04-23 10:09:18 +01:00
b6c229e2bb Expand calls to reserve implementation 2017-04-23 10:09:18 +01:00
19a45e028a Expand calls to generic_find_node 2017-04-23 10:09:18 +01:00
435b7450d4 Expand calls to max_size implementation 2017-04-23 10:09:18 +01:00
a41a0f3a06 Expand calls to load_factor implementation 2017-04-23 10:09:18 +01:00
814926ef31 Expand calls to clear implementation 2017-04-23 10:09:18 +01:00
f6f5ecdc00 Expand calls to emplace implementation
Also manually call the emplace macro up to 9 arguments, nicer error
messages for little effort.

Does it matter that there's no longer a nice backend for
`please_ignore_this_overload`? I don't think so, I was worried that it
would be confusing if triggered, but I'm not really aware of that ever
happening.
2017-04-23 10:09:18 +01:00
42b6b13943 Use the preprocessor to increment emplace limit
So that there's no need to add one.
2017-04-23 10:04:28 +01:00
cfe4c26f99 Explicitly write out boost::tuple template arguments
GCC 4.6 doesn't support using variadic arguments for a fixed length template.
There's a config macro for this, but might as well use the same code
everywhere.
2017-04-23 09:31:18 +01:00
3117611a55 New tuple implementation
Adjusts to use less arguments on Visual C++ 11, which will hopefully fix
it on that compiler. Also changed to be a little less preprocessor
heavy. I'm not sure about the __SUNPRO_CC support, hopefully recent
versions of that compiler will have better support, and can use the
normal implementation. Will check that later.
2017-04-22 18:31:10 +01:00
1e491533fa More consistent std::tuple configuration
Was getting a weird test failure for Visual C++ 11,
BOOST_NO_CXX11_HDR_TUPLE is defined, so the code doesn't support
std::tuple, but BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT was also
true, and so there are functions for constructing using
std::piecewise_construct/std::tuple, which don't work.

So, I'm assuming that if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT is true,
then there must be a std::tuple. I guess it doesn't have full C++11 support,
which is why BOOST_NO_CXX11_HDR_TUPLE is defined, but it appears to be
good enough for us. If not, this will break things.
2017-04-21 20:32:56 +01:00
a119caaa1b Stop travis build after first failure 2017-04-20 23:39:44 +01:00
96f8f85eef Use environment variable to set user-config.jam 2017-04-20 23:39:44 +01:00
2add451d63 Use boost 1.64.0 on travis 2017-04-20 23:11:28 +01:00
3effedb728 Merge branch 'feature/standards-checking-and-cleanup' into develop
Rearrange the definitions to be a closer match to the standard, this
should make it easier to check how standards compliant it is. Also, some
minor code clean-ups that I noticed while doing this.
2017-04-20 23:01:09 +01:00
b067e65731 Clean table forward declarations 2017-04-20 22:59:00 +01:00
f3b179d451 Remove pointless duplication of move constructor 2017-04-20 22:59:00 +01:00
de5373413b Missing rvalue overload of at 2017-04-20 22:59:00 +01:00
fedf533699 Move index functions into place 2017-04-20 22:59:00 +01:00
9cd673c71d Specify clear as noexcept 2017-04-20 22:59:00 +01:00
85a834cf62 Comment on changes needed for C++17 support 2017-04-20 22:59:00 +01:00
5167c970af Swap order of swap/clear to match standard 2017-04-20 22:59:00 +01:00
bf7a65010c Add new erase(iterator) overloads
Not for unordered_set/unordered_multiset as they use the same type for
iterator and const_iterator.
2017-04-20 22:59:00 +01:00
461ac96a2c Reorder insert_or_assign to match standard 2017-04-20 22:59:00 +01:00
5eb10fd0b2 Move extract into place 2017-04-20 22:59:00 +01:00
e2e9959389 Split up emplace and emplace_hint code
Busywork I guess, but I think it's more readable this way. The emplace
macros are still unreadable, but I think they're rarely used.

Btw. a bit weird that clang format has removed the indentation on the
'// emplace' comment, not sure why that is.
2017-04-20 22:59:00 +01:00
d8969c71fc Move 'try_emplace' into same order as draft standard 2017-04-20 22:59:00 +01:00
ab76814aa6 Move 'insert_or_assign' into same order as draft standard 2017-04-20 22:59:00 +01:00
1a18cd2196 Move capacity functions to match order in standard 2017-04-20 22:59:00 +01:00
e4a00980f8 Commented out noexcept for move assignment 2017-04-20 22:59:00 +01:00
af94e6a40e Reorder the constructors to match the draft standard
In order to make it easier to check against the standard.  This includes
collapsing some of the input iterator overloads into one constructor.
2017-04-20 22:59:00 +01:00
ee73a53497 Disable failing tests on gcc 4.6/4.7 c++11 mode
Works fine on later versions of GCC, I suspect it's a bug in their
noexcept support.
2017-04-20 10:11:01 +01:00
6bdf1ba244 Fix a comment 2017-04-19 10:21:13 +01:00
d47754acac Include unordered macro values in test output 2017-04-19 10:21:13 +01:00
cee94e9fcb Fix unused parameter warning 2017-04-19 09:20:31 +01:00
3ae9930979 Merge branch 'feature/better-construction' into develop 2017-04-18 10:14:53 +01:00
2effcfa195 Intro to compliance section
Needs more info on C++17 compliance - particularly `noexecpt`.
2017-04-18 10:14:26 +01:00
8c9080f11f Document changes to allocator use 2017-04-18 10:14:26 +01:00
ef05493c83 Test that construct/destroy aren't used when C++11 isn't available 2017-04-18 10:14:26 +01:00
7a0a598649 Don't track construction when using boost::tuple
Because it doesn't quiet work on C++11 compilers onwards.
2017-04-18 10:14:26 +01:00
cafd236a18 Test more memory tracking 2017-04-18 10:14:26 +01:00
e0054c7dd0 Remove alloc parameter from construct_value 2017-04-18 10:14:26 +01:00
3414e6628a Use allocator to construct/destroy nodes 2017-04-18 10:14:26 +01:00
08ce2c98e0 Rename call_construct to construct_value 2017-04-18 10:14:26 +01:00
6d79a322e2 Use macros to reduce call chain 2017-04-18 10:14:26 +01:00
9e70680044 Bypass construct_value/call_destroy_in a few places 2017-04-18 10:14:26 +01:00
7de8c91301 Remove calls to const_cast_pointer
It was needed because std::allocator_traits::construct doesn't work with
a const pointer (e.g. pointer to the first member of a std::pair). But
now we're only calling construct if BOOST_UNORDERED_CXX11_CONSTRUCTION
is true, so the allocator_traits::construct is no longer used here.
2017-04-18 10:14:26 +01:00
c333a7f9fc Use piecewise construction where possible 2017-04-18 10:14:26 +01:00
bc36a06a2d Comment about call_construct 2017-04-18 10:14:26 +01:00
e62ac22f0b Replace BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT with BOOST_UNORDERED_CXX11_CONSTRUCTION
Require good construct support and piecewise construction. I don't know
if there are any platforms with good construct support, but no piecewise
construction, if there are then they'll no longer use
'allocator_traits::construct'/'allocator_traits::destruct'.
2017-04-18 10:14:26 +01:00
1092c972c9 Use allocator_traits to construct/destruct buckets 2017-04-18 10:14:26 +01:00
7e5520f974 Increase template depth for GCC
This appears to be an unavoidable problem with GCC's tuple
implementation. For example:

http://stackoverflow.com/q/23374953/2434

Appears to be okay in later versions of GCC though.
2017-04-18 10:14:26 +01:00
2b01bdbc25 More general deprecated check
`__has_cpp_attribute(deprecated)` returns true for C++11, but then warns
that it's a C++14 attribute, so only check in C++14 mode.
2017-04-16 16:34:22 +01:00
64a3be7d3e Use aligned_storage's address method to get pointer 2017-04-16 10:37:10 +01:00
c0e03c3640 Add some more details to change log 2017-04-15 20:52:00 +01:00
ed8c0f9ecd Add deprecated attributes to deprecated functions 2017-04-15 17:35:09 +01:00
2bfc59c461 Make node_handler constructor private + additional compile tests 2017-04-15 17:35:09 +01:00
727e36e6a6 Comment about clear_buckets/create_buckets awkwardness.
They both leave the container in an invalid state that needs to be
cleaned up immediately. This confused me slightly.
2017-04-15 17:35:09 +01:00
09bddd8df4 Clear buckets before deleting nodes in clear.
The order shouldn't really matter as nothing throws an exception, but it
seems cleaner to never have any dangling pointers.
2017-04-15 17:35:08 +01:00
f089adc160 Change get_key to have node parameter 2017-04-15 17:35:08 +01:00
97b68ea05e Rename (grouped_)table_impl to table_unique/equiv
The old names don't make sense any more as either style can be used for
containers with equivalent keys, due to the use of node_algo.
2017-04-15 17:35:08 +01:00
972ac220f5 Add missing insert(P&&) methods to unordered_map/unordered_multimap 2017-04-15 17:35:08 +01:00
5d98f3d0f0 Noexcept specs for swap free functions 2017-04-15 17:35:08 +01:00
51cd1cd2af Some more typos 2017-04-12 08:25:14 +01:00
7e940e6e45 Fix some typos 2017-04-12 08:01:10 +01:00
7aa7d8935c Merge branch 'feature/doc-clarification' 2017-04-11 23:50:21 +01:00
2f4d286a51 Merge branch 'feature/doc-clarification' into develop 2017-04-11 23:40:48 +01:00
1bc5d87c5d Clarify the extract and merge don't work between different compatible containers. 2017-04-11 23:40:13 +01:00
c2d2be021a Don't test inserting from initializer list in old clang
There's a problem with it causing an ambiguous overload. I don't think
there's anything we can do to fix that, so just don't test it.

There's another bug where a std::pair doesn't get correctly constructed
from an rvalue when using Clang 3.1 in C++11 mode. But I can't see any
way to easily fix that, and it's a pretty old compiler now.
2017-04-08 06:17:43 +01:00
6b32d6bf09 Merge branch 'develop' 2017-04-04 22:22:33 +01:00
c18f57f62b Add missing copyright/license to a couple of files 2017-04-04 22:06:15 +01:00
e657f75a17 Boost 1.64.0 changelog entry 2017-03-15 11:16:53 +00:00
d060d3a0e5 Fix ironic typo 2017-03-15 11:15:27 +00:00
3c8c360f8c Merge branch 'develop' 2017-03-08 01:53:09 +00:00
0af2c732ab Fix use of BOOST_STATIC_ASSERT for older preprocessors 2017-03-01 16:52:43 +00:00
68fe365f5b Try to avoid Visual C++ warning C4800 2017-03-01 16:50:05 +00:00
91bbd5fcb2 Make emplace_args1 constructor explicit 2017-03-01 16:46:18 +00:00
ac6b6bca48 Merge branch 'develop' 2017-03-01 00:15:41 +00:00
b6e3f2303f Fix call to try_emplace_impl 2017-03-01 00:13:02 +00:00
da370a6a1a Avoid Visual C++ warning C4127 2017-02-27 12:20:37 +00:00
4aa74e5feb Merge between set/multiset and map/multimap 2017-02-27 03:59:02 +00:00
13322fe858 Option to use same node type everywhere.
Will allow me to implement merge and extract fully.
2017-02-27 03:59:02 +00:00
0645700b33 Separate out some of the node manipulation code 2017-02-27 03:59:02 +00:00
d89aadc56c Implement merge 2017-02-27 03:59:02 +00:00
21a24d6cd7 Support node_handle 2017-02-27 03:59:02 +00:00
9c4c3a754a Const methods in value_base. 2017-02-27 03:59:02 +00:00
5f5f8ef1e4 Implement try_emplace 2017-02-27 03:59:02 +00:00
958d206bb6 Implement insert_or_assign. 2017-02-27 03:59:02 +00:00
8fa93cc55b Update some comments for recent versions of standard 2017-02-23 20:14:27 +00:00
79cf0c4bfb pair_traits for getting pair types without instantiating.
I was having some problems in an abandoned prototype with incomplete
types, I'm not sure I will have this problem now, but I'm keeping this
anyway, as it seems useful.
2017-02-23 20:14:27 +00:00
81aefde94e Use const_key_type internally 2017-02-23 20:14:27 +00:00
96602df8a8 Remove const volatile when picking bucket policy
Could possibly do this in a more portable manner by using some sort of
function overload.
2017-02-23 20:14:27 +00:00
c0b72d97b3 Stricter about rebinding the allocator 2017-02-23 20:14:27 +00:00
ddee1b686a Move config and declaration to the start of implementataion.hpp 2017-02-23 20:14:26 +00:00
2231586033 Remove duplicate includes 2017-02-23 20:14:26 +00:00
13063abce5 Move friend function outside of class
The use of std::pair was causing issues with the sun compiler.
2017-02-23 20:10:40 +00:00
570decf00e Merge branch 'develop' 2017-02-23 19:48:31 +00:00
bf5ef9824d Reformat with clang-format 2017-02-19 13:05:17 +00:00
01dcd36c41 Add _clang-format file 2017-02-19 13:05:17 +00:00
b2f2fdc2f3 Prevent clang-format sorting some test includes 2017-02-19 13:05:17 +00:00
f2af10c746 Protect preprocess sequence from clang format 2017-02-19 13:05:17 +00:00
3bf664ad31 Add a missing header 2017-02-19 13:05:17 +00:00
67ab88b064 Combine most of the detail headers into a single header 2017-02-19 13:05:17 +00:00
67f1f65174 Linearise the detail includes
The current organisation of the headers has been making less and less
sense over the years, so to simplify things, I'm just going to combine
them into a single header. This change will make it easier to do that.
2017-02-19 13:05:17 +00:00
b1dff42434 Merge remote-tracking branch 'origin/develop' 2017-02-19 01:21:12 +00:00
57cc6d4bac Fix exception safety when constructing pairs 2017-01-01 18:35:50 +00:00
e416cafd49 Count instances constructed/destructed in exception tests 2017-01-01 18:35:50 +00:00
0aa79ce360 Merge branch 'develop' 2017-01-01 18:26:35 +00:00
0a1c9ad4c5 Use boost 1.63.0 in travis 2017-01-01 16:07:08 +00:00
dd85b16166 Update the snapshot in travis
I've forgotten why I'm not using a stable release, but really should try
to avoid using snapshots for this reason. Or at least port the code for
downloading snapshots for the website.
2016-12-06 10:56:19 +00:00
76127b6e42 Merge branch 'develop' 2016-12-05 22:48:29 +00:00
03a597983e Change log for last few fixes 2016-12-05 22:48:00 +00:00
33f701dd09 Fix assigning hash/key equality functions for empty containers 2016-11-21 10:24:51 +00:00
3db4654b44 Remove unary/binary_function from examples/documentation
They are being removed from the standard in C++17, and were never really
required.
2016-11-06 10:19:17 +00:00
a7546e298e Support 10 arguments in emplace_args
Which was the intent, but only supported up to 9 arguments. I doubt
this will make much of a difference.
2016-11-02 07:30:41 +00:00
8a0592a35d Merge branch 'develop' 2016-10-30 23:17:15 +00:00
98cce956f9 Try to fix a 64-bit powerpc g++ 7 warning
Warning is:

allocate.hpp:335:19: warning: conversion to ???unsigned int??? from
???long unsigned int??? may alter its value [-Wconversion]

I'm not sure, but I think it's because the sizeof is a long unsigned
int, and the template parameter is an unsigned int. The sizeof isn't
even used, it's just there to get a value for expression SFINAE.
2016-10-28 09:06:53 +01:00
a34785fa0d Don't 'sink' uncopyable container
Calling sink was causing older versions of gcc to copy the container,
resulting in a compile error. So instead just disambiguate by putting
brackets around the expression.
2016-10-25 18:04:34 +01:00
14ccdbc7b6 Add guards against exceptions that shouldn't happen
I'm getting a couple of "terminate called after throwing an instance of
'test::lightweight::test_exception'" errors on the sun platform. Not
sure where they're happening, so I've made the code a tad more resilient
against exceptions that should not really be thrown.
2016-10-24 09:46:13 +01:00
5b5b46ea1c Disable Visual C++ __declspec(allocator) warning
Visual C++ is warning that memory can't be tracked for allocators whose
pointer types aren't actually pointers, which is a correct warning but
not relevant for our concerns, and is caused by the unit tests, not the
container implementation.
2016-10-23 13:51:58 +01:00
e3f534a148 Allocator aware constructors 2016-10-23 13:33:25 +01:00
1bcd5b0003 Make no argument constructor implicit 2016-10-23 13:32:52 +01:00
0d1cfba823 Rename functions in allocate.hpp 2016-10-22 10:28:53 +01:00
e986b70981 Stricter iterator types 2016-10-22 10:04:36 +01:00
9b7b485c33 Use node_pointer in equality. 2016-10-22 10:04:36 +01:00
c680fa7418 Remove find_matching_node.
FWIW the standard says that equality is undefined behaviour if the Hash
and Pred function objects behave differently. But I think we should
support different hash functions, e.g. so that randomized hash functions
will work.
2016-10-22 10:04:36 +01:00
9772c01161 Replace several uses of iterators with node pointers.
Which is to some extent going in circles, as this is how the containers
were originally implemented. But I think this is cleaner. It also fixes
a minor problem where the internal and external iterator types are
different for some containers, as the external iterators are all const.
2016-10-22 10:04:36 +01:00
6071f9a08b Stop testing no arg emplace when not available 2016-10-22 09:49:14 +01:00
ad2256b13c Add const cast for piecewise construction 2016-10-22 09:42:56 +01:00
dad0d48c9c Support containers with const value type
Currently just storing the value without a const. Can do better with
C++11 constructors, so maybe should do that, and cast away const on
compilers without support.

Another problem is that std::allocator<const int> doesn't compile for
libstdc++ (and potentially other standard libraries), so
boost::unordered_set<const int> can't compile. I'm not sure if I should
work around that, as it means changing the type of the container
(i.e. to boost::unordered_set<const int,... , std::allocator<int>>).
2016-10-17 08:06:19 +01:00
e03a8732a6 Use static_cast for allocator_traits::construct
std::allocator::construct uses a C-style cast to void pointer, so it can
accept const pointers, but allocator_traits::construct uses a static_cast
by default, so const pointers don't work. This means the implementation
needs to cast away const when constructing members of a std::pair. This
wouldn't happen if piecewise construction was used, as the members could
be constructed normally.
2016-10-17 07:54:06 +01:00
7da307c696 Supply explicit test::cxx11_allocator::rebind for old GCC
The rebind mechanism doesn't work for templates with multiple template
parameters on old versions of GCC. But allocators written for that
compiler will have an explicit rebind, so that should be acceptable.
2016-10-17 07:54:06 +01:00
82438a513b Fix allocator traits macro 2016-10-17 07:54:06 +01:00
b5205e58aa Change log for allocator support. 2016-10-14 09:29:38 +01:00
b907cee691 Use std::allocator_traits where available.
Might have to revert this when implementing C++17 features.
2016-10-14 09:27:40 +01:00
da6e8e8041 Better allocator rebind support 2016-10-14 09:27:40 +01:00
3fd4495b2f Merge branch 'develop' 2016-10-14 09:26:19 +01:00
04607dc9f3 Fix for clang. 2016-10-13 17:03:31 +01:00
ece4116329 Try to fix another warning 2016-10-13 10:00:26 +01:00
74abdd6973 Replace boost::next with a simpler version
Less optimized, but hopefully it won't cause any warnings.
2016-10-11 13:36:41 +01:00
a316d3fa46 Fix more warnings 2016-10-11 10:07:07 +01:00
70ce6b4ae7 Add, and update, documentation build targets. 2016-10-10 11:39:54 -05:00
ade302f0a0 Add, and update, documentation build targets. 2016-10-07 23:07:37 -05:00
147885fec4 Add another random generation style.
This time for a more limited range of values so that equal values turn
up more often.  This is a bit shoddy, but seems like the best way to
improve the existing tests without too much effort.
2016-10-06 21:52:19 +01:00
65aaf27380 Fix accidental fallthrough in switch cases.
This was causing the hash function to be different to the equality
function. For some reason this resulted in a lot of windows test
failures, but none on linux or os x. I'm a bit confused and worried
about that.
2016-10-06 10:53:10 +01:00
b1588929cc Fix another sign conversion warning. 2016-10-05 13:52:33 +01:00
094fa38360 Remove -Wsign-conversion, old gcc doesn't support it. 2016-10-05 13:52:17 +01:00
71d19820ac Fix signed conversion warnings. 2016-10-05 09:45:53 +01:00
a0dc86ecbc Use the boost snapshot for travis testing. 2016-10-05 09:35:46 +01:00
982685d3a0 Adjust order of variables to see if intel failure changes.
So currently on one intel tester find_tests is failing the 'pos !=
x.end()' test, but not the 'const_pos != x_const.end()' test for
unordered_set (and possibly others, the test results are truncated). I'm
a bit stumped as to why this should be, as for unordered_set the const
and non-const versions are basically the exact same code. See if
changing the order makes any difference to what fails.
2016-10-05 00:57:58 +01:00
dadb4486ee Fix calls to std::rand in tests 2016-10-04 15:52:47 +01:00
d14c1dec59 Revert "Allocator aware constructors."
This reverts commit b00bc15c3e.

I messed that up a bit, will get back to it later.
2016-10-03 20:58:15 +01:00
21d6d7bc21 Fix detection of is_nothrow_move_constructible support.
I should possibly also check how it handles `throw()`?
2016-10-03 10:49:49 +01:00
ff0228e752 Support for std::piecewise_construct. 2016-10-02 17:56:01 +01:00
b00bc15c3e Allocator aware constructors. 2016-10-02 17:56:01 +01:00
50c4cbe06c Try to fix the failures in noxcept_tests 2016-10-02 13:04:25 +01:00
573e10665c Use standard boost move style in noexcept_tests. 2016-10-02 13:04:25 +01:00
d0acb81f2e Release notes for latest changes. 2016-10-02 13:04:25 +01:00
e7b20d2877 Fix exception bug in asssignment.
The hash and key equality functions were assigned before allocating new
buckets. If that allocation failed, then the existing elements would be
left in place - so if accessed after the exception they could be in the
wrong buckets or equivalent elements could be incorrectly grouped
together.
2016-10-02 13:04:25 +01:00
588ad6e69f Travis tests in 32 and 64 bit. 2016-10-01 14:04:01 +01:00
98462fbcc3 Avoid conversion warning. 2016-10-01 13:53:05 +01:00
a93331dd96 Fix new emplace tests. 2016-10-01 13:51:25 +01:00
e174af2286 Try not using boost::forward in emplace_args constructor.
AFAICT it's not needed since the construct arguments and the members are
the same reference type. Maybe it was for older compilers? And it appears
to be causing issues with string literals in older versions of Visual
C++.
2016-09-30 00:32:19 +01:00
9decbe0cbd Manually write out emplace_args for small numbers.
Still need some macros to handle rvalue reference support.
2016-09-30 00:32:19 +01:00
021817f2b4 Fix Visual C++ version number + use BOOST_WORKAROUND. 2016-09-18 22:56:23 +01:00
13ff69efbf Make 'ordered' container independent. 2016-09-18 12:22:48 +01:00
8fda9113b8 Make 'has_unique_keys' container independent. 2016-09-18 12:22:48 +01:00
b881bcfee3 More insert and erase tests 2016-09-18 12:22:48 +01:00
1c606980ec Update tests for standard changes involving bucket count.
It seems my defect report was accepted at some point, and they tweaked
the requirements involving bucket counts. This also makes it possible to
have a bucket count of 0, which I think wasn't allowed in the past. I
don't think I'll change this implementation to do so, but I'd like to be
able to run these tests against standard implementations, so I'm
starting to take that into account.

I believe these changes were made after the C++14 standard, but I've
always been tracking the draft standards, so that doesn't really matter.
2016-09-18 12:22:48 +01:00
0d6e58d9fd Write out some compiler info before test results. 2016-09-18 12:22:48 +01:00
95e477902e Special case for Visual C++ 12 test failure.
Plus some extra tests while I'm at it.
2016-09-18 10:28:21 +01:00
cc32bfb96f Pointless change to extract_key. 2016-09-07 09:26:25 +01:00
7c2f11f8e1 Fix signed/unsigned comparisons. 2016-09-07 09:26:25 +01:00
d08dcb7465 Run xmllint over reference docs in travis. 2016-09-07 09:26:25 +01:00
2d1d6ccd75 Try using boost 1.61.0 in travis 2016-09-04 10:38:13 +01:00
7f380028cc Hint iterator support was too late for 1.62.0 2016-09-04 10:38:13 +01:00
827f77729f Merge branch 'fixes' into develop 2016-09-04 10:37:38 +01:00
6c81de37f5 Fix closing tag. 2016-09-04 10:37:15 +01:00
86a8a0429a Merge branch 'fixes' into develop 2016-09-04 08:23:52 +01:00
4b00548138 Test+document insertion from initializer lists. 2016-09-04 08:23:32 +01:00
8bb9473443 Document assignment from initializer list. 2016-09-04 08:23:31 +01:00
da7a5bf269 Fix insert from range documentation.
Was the same for containers with unique and equivalent keys.
2016-09-04 08:23:31 +01:00
7434e116a7 Try using boost::long_long_type to avoid warning. 2016-08-29 23:03:06 +01:00
8f51dc6082 Fix some test warnings.
And turn on warnings as errors in Travis.
2016-08-19 11:41:19 +01:00
79deac97dd Merge branch 'develop' 2016-08-17 12:11:13 +01:00
9debeadee7 Fix some test warnings.
And turn on warnings as errors in Travis.
2016-08-17 12:08:16 +01:00
cae72eec2f Insert/emplace with hint. 2016-08-17 12:08:15 +01:00
e58370b4ff Move emplace before emplace_impl in equivalent.hpp 2016-08-17 12:08:15 +01:00
e92f7d86c1 Remove array_constructor.
I was using SFINAE for everything because some old compilers had issues.
But that's hopefully in the distant past now.
2016-08-14 20:55:40 +01:00
93a33ba15f Remove a couple of unneeded includes. 2016-08-14 20:55:40 +01:00
ad353c8e3d Move some of the includes up into allocate.hpp 2016-08-14 20:55:40 +01:00
09717ffca4 Remove a few unnecessary internal includes. 2016-08-14 20:55:40 +01:00
ce4b840299 Map/set details types in individual headers. 2016-08-14 20:55:40 +01:00
5a8df0ebe4 Hopefully a bit more readable. 2016-08-14 20:55:40 +01:00
6029d1cfd0 Trim down node_tmp code. 2016-08-14 20:55:40 +01:00
3fe46a1769 Cleaner emplace_impl in equivalent. 2016-08-14 20:55:40 +01:00
5490bcfe95 Remove node_tmp overload of add_node. 2016-08-14 20:55:40 +01:00
078c562b6c Pull some common code into a function. 2016-08-14 20:55:40 +01:00
88612a8be4 Less faffing around with node_constructor. 2016-08-14 20:55:40 +01:00
37a6903831 Move node construction into allocate.hpp 2016-08-14 20:55:40 +01:00
8017d9e684 Change how node construction works.
Split node_constructor into two classes, one for constructing a node
without a value, and then another for holding it once the value is
constructed.

Do the work of constructing values in convenience functions in
allocate.hpp (construct_value_generic, construct_value, construct_pair).
2016-08-14 20:55:40 +01:00
609ae6cb4e Expand out fill_buckets. 2016-08-14 20:55:40 +01:00
603f785739 Merge branch 'develop' 2016-08-14 20:51:44 +01:00
992f9ccf21 Turn off memory sanitizer on travis.
It's not working at all.
2016-08-14 20:39:46 +01:00
e250fb44f6 Merge local develop branch develop
Oops, I merged the wrong 'develop' branch into master. Luckily, there's
not much of a difference, so I'm resolving the merge here, and will
merge into master soon.
2016-08-14 20:02:13 +01:00
9767d86d97 Merge branch 'develop' 2016-08-14 19:59:22 +01:00
7687c99708 Disable clang c++03 memory sanitizer tests. 2016-08-04 13:35:48 +01:00
81cc773013 Try to fix mem/std11 toolset. 2016-08-04 13:35:48 +01:00
cdb887e880 Clean up a memory leak in a test. 2016-08-04 13:35:47 +01:00
041fee64df Don't stop Boost.Build on error. 2016-08-04 13:35:46 +01:00
e3dd1f276e Use clang and gcc's sanitizers in travis. 2016-08-03 14:24:52 +01:00
0769ecd70d Some more checks.
The intel-linux failures I'm getting now are odd. This find test is
failing for iterator, but not const_iterator. So maybe it's a problem
with the iterator object. The failures I was getting before have
disappeared, so I'm not sure about that.
2016-07-29 12:19:50 +01:00
2be69b3eb9 A little more information in the find_tests.
Now the intel-linux tester that was failing for erase_tests is passing,
but has started failing for find_tests instead. Oddly the test for
non-const find is failing, but the const find is fine - this doesn't
make much sense as they should be the same. Not sure, but it suggests
the problem might be in the way iterators are handled, rather than the
data structure?

Checking the iterators before checking that the keys are equal in order
to tell which part of the test is failing.
2016-07-27 06:51:05 +01:00
bc601e34d2 More info on test failure on intel-linux.
The count check is reporting errors, but everything else appears to work
okay.
2016-07-25 15:03:39 +01:00
79e39d9d43 Copy build changes from the develop branch. 2016-07-03 21:36:14 +01:00
6bc57bd398 Typo 2016-07-03 08:46:40 +01:00
1bca2df642 Always explicitly specify standard for travis. 2016-07-03 08:42:25 +01:00
59cbe3d483 Also move exception tests into test/Jamfile.v2
Moving the tests successfully restored the test results, so do it for
the exception tests as well.
2016-07-03 08:42:17 +01:00
21f2522695 Try running the tests from unordered/test. 2016-07-02 22:11:43 +01:00
3720b0be58 Try creating a project for test.
For some reason the unordered test results are not showing up any more.
This is odd, as when I try locally they do run. I don't know why this
is, but it's possible that it's because there isn't an actual project in
the test directory, so try adding one.
2016-07-01 11:12:29 +01:00
413b45a62e Merge remote-tracking branch 'origin/develop' 2016-06-03 00:00:58 +01:00
7b8e3d01de Use argument SFINAE instead of return SFINAE 2016-06-03 00:00:51 +01:00
b4a3c6f460 Fix exception safety in assignment for multimap/multiset.
The assignment code seemed like a bit of a premature optimization, I
replaced it with a slightly slower but much simpler implementation.
2016-05-30 15:02:04 +01:00
1d4845d6b8 Stop using predef in test. 2016-05-26 22:39:47 +01:00
c26acdba15 Travis 2016-05-26 22:31:43 +01:00
3f42a56bae Remove old deprecated warning. 2016-05-26 09:25:10 +01:00
144a0c1791 Remove BOOST_NO_STD_DISTANCE workaround. 2016-05-26 09:24:25 +01:00
cc2b1a1ef1 Stop using deprecated boost::iterator. 2016-05-26 09:24:21 +01:00
84dd473a5d Merge remote-tracking branch 'origin/develop' 2015-02-22 15:12:28 +00:00
f014802eb6 Release note for pull request #4. 2015-02-22 15:08:46 +00:00
68eb654e7a Merge pull request #4 from tempoz/patch-2
Bounds-check after arithmetic is complete
2014-12-09 01:04:30 +00:00
3a507b4e39 Bounds-check after arithmetic is complete
double_to_size can return std::numeric_limits<size_t>max(), so we cannot add 1 to the return value of double_to_size. That addition should be done while still working with a double, as can be seen being done on line 850 of this file.
This was uncovered by Coverity, and addresses Coverity issues CID13443 and CID12664
2014-12-08 16:38:38 -05:00
0273ec59d7 Fix Visual C++ 9.0 workaround. 2014-12-03 18:28:40 +00:00
9090d87725 Restore ampersand workaround for Visual C++ 9 2014-11-16 10:01:29 +00:00
8ccde2e5a1 Move the allocators after copying the hash functions.
Just in case the hash functions throw.
2014-11-09 23:44:16 +00:00
31211a607f Remove assertion that used moved allocator. Fixes #10777. 2014-11-09 23:35:35 +00:00
56ab93d296 Merge pull request #3 from awulkiew/fix/iterators
Remove template patameters from friend declarations in interator.
2014-11-09 15:14:02 +00:00
1d8855da27 Remove template patameters from friend declarations in interator<>. 2014-11-09 13:36:27 +01:00
df5a7538b1 Changelog 2014-11-08 22:22:12 +00:00
0cedaf7ad6 Rename iterator typedef to n_iterator. 2014-11-08 22:22:11 +00:00
b4795f414d Remove unneeded ConstNodePointer template parameters. 2014-11-08 22:22:11 +00:00
2c9d209eef Remove incorrect changelog note.
A minor change that is not actually in this release, will be in the next one.
Probably too late to rebuild the documenation.
2014-11-02 17:35:05 +00:00
a81c86a90e Remove use of operator&.
Also reactivate operator& for minimal test classes. Apparently I
disabled them because of a problem in a type trait, but I'm not seeing
that now. Maybe it will appear on other compilers.
2014-10-26 22:21:12 +00:00
bf0f90ff03 Merge branch 'develop' 2014-10-26 12:18:38 +00:00
7c6f1ef227 Changelog 2014-10-26 12:17:58 +00:00
99985bb1b2 Fix pointer types in iterators.
https://svn.boost.org/trac/boost/ticket/10672
2014-10-22 22:03:32 +01:00
8c5aa5086d Initialize data_ in value_base default constructor
This means data_ should get initialized in the default constructor for boost::unordered::detail::unique_node (and any other inheritors), as this constructor will be called there.

This uninitialized data member was reported by Coverity (CID 49445), which unfortunately does not seem to have any convenient way to publicly, globally address issues.
2014-10-22 21:27:27 +01:00
b1232d8061 Revert some changes so that I can merge to master.
Revert "Rename iterator typedef to n_iterator." and "Combine some of the
headers."

This reverts commits: 2f6b81d8c1 and
e1b39bbbfb.
2014-10-22 21:24:36 +01:00
2f6b81d8c1 Rename iterator typedef to n_iterator. 2014-08-19 16:41:10 +01:00
e1b39bbbfb Combine some of the headers. 2014-08-19 16:41:10 +01:00
6b7cecb9d3 Workaround initialiser list bug in gcc 4.4. 2014-08-02 03:11:44 +01:00
79dcf7cbe8 Merge branch 'develop' 2014-07-28 23:33:28 +01:00
d4702754b7 The correct release notes.
The ones I entered were for hash.
2014-07-27 18:01:00 +01:00
98d90f26d7 Merge branch 'develop' 2014-07-27 12:20:58 +01:00
b97ceb6442 Release notes. 2014-07-27 12:20:56 +01:00
c18c645b92 Merge remote-tracking branch 'origin/develop' 2014-07-27 11:59:55 +01:00
15cb6d7d1b Tweak warning flags in tests. 2014-07-14 21:49:58 +01:00
2f5d98a0cd Don't use allocator to construct/destroy anything other than elements.
As specified in 23.2.1.3.
2014-07-12 19:12:46 +01:00
2216c987a0 Fixed direct use of allocator. 2014-07-11 09:13:47 +01:00
86d4d21250 Make value_base a member of pointer nodes. 2014-07-11 08:40:07 +01:00
3eb2355182 Merge branch 'develop' 2014-06-30 10:43:47 +01:00
9440395330 Fix swap link. 2014-06-16 22:45:04 +01:00
034f2c3779 Update metadata. 2014-06-16 22:43:54 +01:00
e93f5b0971 Update link to swap. 2014-06-08 15:33:40 +01:00
8c6f3e910b Merge branch 'develop' 2014-03-25 22:05:25 +00:00
78bd2c0736 Fix map allocators in introduction. Fixes trac #9719. 2014-03-11 03:48:26 +00:00
4e6ce91dd0 Regenerate libraries.json with latest script. 2014-02-27 22:46:07 +00:00
850d69738b Switch to latest meta/libraries.json 2014-02-27 22:30:01 +00:00
9c62f83e74 Add maintainers to metadata. 2014-02-24 22:22:09 +00:00
99fdce0b4d Fix policy typedefs. 2014-02-24 16:54:12 +00:00
06b6418044 Add metadata 2014-02-23 14:30:21 +00:00
57819d1dd9 Always use prime policy for integers. Fixes trac #9282. 2014-02-23 10:16:14 +00:00
80f3376894 Merge branch 'develop' - clean up warnings. 2014-02-11 08:10:13 +00:00
94071cc6e8 Clean up warnings. Fixes trac #9377. 2014-01-26 22:57:24 +00:00
038550a9df Fix some issues tests, and git tweak.
Merge branch 'develop'
2014-01-26 15:40:01 +00:00
9ca8c691ac Ignore html build files. 2014-01-26 13:44:38 +00:00
a4881436d2 Disable forward_as_tuple test for older Visual C++. 2014-01-23 22:49:05 +00:00
70190b3aa2 Disable test for compilers that emulate old Visual C++. 2014-01-15 00:04:13 +00:00
8ae166a2c3 Tweak compiler checks in unnecessary_copy_tests.
I'm running these tests by default now, which will probably break
several compilers, so I'll need to add extra conditions later.
2014-01-15 00:00:01 +00:00
7d0c6d2425 Unused typedef. 2013-12-15 17:11:26 +00:00
5995e5521f Account for extra moves/copies when using Visual Age. 2013-12-15 17:11:26 +00:00
59c83ab942 Reintroduce std::move test.
There used to be a std::move test here, but it was changed to
boost::test for a wider range of testing, but I'd quite like to test
with std::move regardless.
2013-12-15 17:11:25 +00:00
0a552a47cb Disable test for Visual C++ 12. 2013-12-15 17:11:25 +00:00
3b5cf359e7 Merge branch 'master' into develop
Using 'ours' strategy, so nothing actually changed.
2013-12-07 19:10:39 +00:00
239453bead Fix unordered on Sun 5.12 compiler. Refs #9424.
[SVN r86792]
2013-11-23 11:43:19 +00:00
bea92e8842 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
ddab816ed7 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
007ddb9a5a Update the unordered rationale.
I just noticed that it wan't updated for the changes on 64 bit platforms.
Not very good, but I don't want to spend too long on this.  I'm tempted to just
delete it.

[SVN r86608]
2013-11-10 23:26:21 +00:00
6b1a4bfeb7 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
6ca8d5e0d9 Merge Visual C++ 12 fix for Unordered.
[SVN r86551]
2013-11-03 19:20:09 +00:00
6f3dee13a8 Extend the Visual C++ workaround to 3 parameters.
To avoid collision with piecewise construction.

[SVN r86506]
2013-10-28 20:32:52 +00:00
7f14796ba4 Try to work around Visual C++'s variadic overload bug.
Possibly too late for the release.

[SVN r86482]
2013-10-27 17:58:09 +00:00
cfb4a9d254 Revert attempted work around for Visual C++.
[SVN r86478]
2013-10-27 13:14:12 +00:00
621c1523c0 Fix potential msvc 12 workaround.
[SVN r86433]
2013-10-25 22:21:51 +00:00
b4d62e4670 Attempt to work around Visual C++ initializer list overload bug.
I'm hoping that these templated initializer lists will be considered a better
overload than the others. I have no idea if it will actually work, this is a
real shot in the dark.

The enable_if checks should probably be for implicit conversion, there might
be a chance this could override a valid call when there's an explicit
conversion.

[SVN r86419]
2013-10-24 18:11:35 +00:00
3922d1bb63 This special case doesn't seem to apply to the latest Visual C++.
[SVN r86365]
2013-10-19 16:53:37 +00:00
9b9a1d21a6 Merge release notes + float hash fix. Ref #8822.
[SVN r86210]
2013-10-08 21:26:30 +00:00
033a611f71 Change log.
[SVN r86173]
2013-10-06 08:03:12 +00:00
3aa91346ea 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
a7c0ddb5b3 Merge unordered to release. Fixes #8851, #8874
Avoid some warnings, and move detail functions into a sub-namespace to avoid
exposing them via. ADL.


[SVN r85388]
2013-08-18 09:44:14 +00:00
de0366105c Avoid Visual C++ warning.
Avoiding:

    warning C4127: conditional expression is constant

[SVN r85281]
2013-08-10 13:09:28 +00:00
3508ceaa58 Avoid exposing functions via ADL.
I'd put the iterators in their own namespace so that they wouldn't pick
up functions in detail via ADL, but I forgot that their template
parameters would cause that to happen anyway. The simplest way to fix
that for now is just to stuff the problematic functions into a
sub-namespace, so that they're no longer exposed.

[SVN r85280]
2013-08-10 13:09:08 +00:00
29660f9c4d Remove unused typedef. Refs #8874.
[SVN r85245]
2013-08-08 20:28:53 +00:00
52b42b4e48 Fix unused variable warning. Refs #8851.
Bit annoying that `boost::ignore_unused_variable_warning` is in
`<boost/concept_check.hpp>`.

[SVN r85244]
2013-08-08 20:27:40 +00:00
c88126e1d2 Merge unordered from trunk.
Add `BOOST_NOEXPECT` to:

- Move constructors (when appropriate)
- Destructors
- Iterators

Also, fix some misleading documentation about the containers' move support.


[SVN r85048]
2013-07-15 21:32:45 +00:00
e6a6fe92d7 Fix misleading documentation about move support.
[SVN r84985]
2013-07-08 22:11:54 +00:00
0c7c7cc6ad Merge some change log entries to release.
[SVN r84497]
2013-05-25 15:53:49 +00:00
fb93c8cb86 Change log entries for 1.54.0
[SVN r84496]
2013-05-25 15:45:51 +00:00
8f0126a13a Revert siphash example.
Since I'm not going to release it.


[SVN r84434]
2013-05-22 21:48:29 +00:00
0f080552fa Remove 'private' definition that I used for debugging.
[SVN r84408]
2013-05-21 22:50:19 +00:00
f8a6ea40a1 Add noexcept annotations to iterators.
I couldn't find any sepecification in the standard, but I'd assume that since
`begin` and `end` are both `noexcept`, the iterator copy constructors must be.

To justify adding `noexcept` to these members, see 17.6.3.5 (part of the
allocator requirements) of n3485, which says about allocator's pointer types,
"No constructor, comparison operator, copy operation, move operation, or swap
operation on these types shall exit via an exception."

Not relevant in this case but allocator pointers also need to model
NullablePointer. From 17.6.3.3, "No operation which is part of the
NullablePointer requirements shall exit via an exception."

[SVN r84374]
2013-05-19 15:00:40 +00:00
1a067034c1 Add conditional noexcept for move constructors.
Also added `noexcept` for destructors because of a gcc bug, see:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56191

Found via:

http://stackoverflow.com/questions/15721544/destructors-and-noexcept

[SVN r84373]
2013-05-19 14:30:12 +00:00
bd10a8b5aa Merge initial unordered use of noexcept + friends.
Still more to come, hopefully in time for the release.


[SVN r84304]
2013-05-16 22:15:42 +00:00
d603e75d03 Use nothrow move construction for function objects, when available.
[SVN r84277]
2013-05-13 23:13:04 +00:00
a422b40041 Use nothrow move assignment for function objects, when available.
Originally I was going to use two different versions of `hash_functions`, but
the recent discussion on binary compatibility persuaded me not to.

[SVN r84276]
2013-05-13 23:12:46 +00:00
44f61e5878 Add BOOST_NOEXCEPT to unordered container methods.
I haven't done the iterators yet.

[SVN r84253]
2013-05-12 14:34:45 +00:00
27c4e90374 Add trailing newlines to siphash examples.
I'm not sure if I'll actually release this example. I don't think it does a
good job of demonstrating what I wanted.

[SVN r84249]
2013-05-12 14:33:15 +00:00
0221f1a9bd Unordered: Merge assign fix.
[SVN r82651]
2013-01-27 23:10:29 +00:00
6b21eeccab Unordered: Fix move assignment with unequal allocators.
[SVN r82614]
2013-01-25 21:22:03 +00:00
bf1f24ab04 Unordered: Initial stab at siphash example.
[SVN r81973]
2012-12-15 16:42:44 +00:00
34b69e67ee Unordered: Merge test tweaks + inspect fixes from trunk.
[SVN r81922]
2012-12-13 22:39:44 +00:00
64994d76dd Unordered: Detab.
[SVN r81762]
2012-12-07 17:06:11 +00:00
10049f8325 Unordered: Missing final newlines.
[SVN r81761]
2012-12-07 17:05:36 +00:00
654fed166a Unordered: Remove and update various deprecated things.
[SVN r81727]
2012-12-05 22:06:57 +00:00
1bd3b029fa Removed usage of deprecated macros
[SVN r81563]
2012-11-26 17:47:12 +00:00
3305caf40c Unordered: Changelog notes.
[SVN r81474]
2012-11-22 08:59:27 +00:00
85d2657ac1 Remove usage of deprecated macros
[SVN r81449]
2012-11-21 01:21:54 +00:00
8fb85cbb8d Unordered: Fix overload edge case for piecewise construction.
[SVN r81393]
2012-11-17 12:03:55 +00:00
da455124d2 Unordered: Try to make the piecewise_construct emulation a little more readable.
[SVN r81392]
2012-11-17 12:03:32 +00:00
ef4d33ce89 Unordered: Remove the deprecated equality implementation.
[SVN r81385]
2012-11-17 10:30:19 +00:00
7eefe62efe Unordered: Remove deprecated variadic pair constructors.
This was emulating them as specified in older standard drafts.

[SVN r81384]
2012-11-17 10:28:35 +00:00
981f1e2acb Unordered: Merge code clean up.
[SVN r81358]
2012-11-15 13:43:37 +00:00
73c0d85ae6 Unorderd: Stop deriving from hash policy.
[SVN r81209]
2012-11-05 18:33:29 +00:00
d495cbd7e6 Unordered: Clean up the pointer silliness.
[SVN r81208]
2012-11-05 18:33:15 +00:00
ccc3d1c83d Unordered: Simpler erase implementation.
[SVN r81207]
2012-11-05 18:32:59 +00:00
38d8d052d1 Unordered: Simplify pointer use.
[SVN r81206]
2012-11-05 18:32:45 +00:00
2e26534659 Unordered: Improved exception test thing.
Allows repetition of exception tests + separate running the tests so that
different tests types or configurations can be mixed up.

[SVN r81030]
2012-10-21 00:20:07 +00:00
d1a6e948e3 Unordered: bcp friendly macros.
[SVN r81029]
2012-10-21 00:17:40 +00:00
81897a6469 Unordered: Fix erasing ranges, and some tests. Fixes #7471
[SVN r80958]
2012-10-11 17:29:19 +00:00
8f8ea09ce8 Unordered: Fix bug when erasing a range, refs #7471.
[SVN r80894]
2012-10-07 08:19:01 +00:00
ced2139eea Unordered/Hash: Merge change log.
[SVN r80778]
2012-09-30 11:58:06 +00:00
9b398ba0c9 Unordered: Update change log.
[SVN r80776]
2012-09-30 11:55:58 +00:00
556adc1de1 Unordered: Fix the Visual C++ 11 version number.
[SVN r80768]
2012-09-30 08:29:26 +00:00
3f060a70d1 Unordered: Fix unnecessary_copy_tests + extra tests.
It looks the odd result in unnecessary_copy_tests on Visual C++ 11 is not a
bug, but add some extra tests just to make sure. Also some extra rehash and
reserve testing thrown in.

[SVN r80705]
2012-09-26 08:09:26 +00:00
d6322718f3 Unordered: A bit more feedback from unnecessary_copy_tests
[SVN r80635]
2012-09-22 18:32:22 +00:00
0a8037243b Unordered: Merge slightly simpler implementation.
[SVN r80632]
2012-09-22 17:28:55 +00:00
94ef1ac391 Unordered: Support empty containers in node_holder.
[SVN r80562]
2012-09-17 18:59:29 +00:00
53f278312f Unordered: Get rid of get_start.
[SVN r80561]
2012-09-17 18:59:03 +00:00
549b93e629 Unordered: delete_buckets works when buckets_ is null.
[SVN r80560]
2012-09-17 18:58:28 +00:00
c2e7221bf9 Unordered: Set max_load_ to 0 when there are no buckets.
[SVN r80559]
2012-09-17 18:57:58 +00:00
a0ceefc91a Unordered: Merge from trunk.
Faster assign, plus simplified some of the implementation.


[SVN r80558]
2012-09-17 18:53:30 +00:00
37d58e84e3 Unordered: Fix creating extra node when resizing.
[SVN r80518]
2012-09-13 19:50:31 +00:00
ec6219fe13 Unordered: Fix incorrect assertion.
[SVN r80508]
2012-09-12 21:09:39 +00:00
05f7c37f54 Unordered: Merge tests to release
[SVN r80435]
2012-09-07 19:51:10 +00:00
e68f0c341e Unordered: Fix object counts in tests.
[SVN r80417]
2012-09-06 08:49:43 +00:00
f47f0f8d16 Unordered: Fix some issues with the tests.
[SVN r80416]
2012-09-05 23:33:22 +00:00
ed369d6374 Unordered: Move MSVC warning suppression to correct location.
[SVN r80412]
2012-09-05 19:02:29 +00:00
b6b54610c6 Unordered: Repeat assign tests several times.
[SVN r80411]
2012-09-05 19:02:04 +00:00
1d03bbe213 Unordered: Re-initialise reused nodes.
[SVN r80410]
2012-09-05 19:01:17 +00:00
32ab636fe8 Unordered: delete/destroy/clear cleanup.
[SVN r80390]
2012-09-03 20:06:00 +00:00
8e5ffbbe6c Unordered: Clean up swap.
[SVN r80389]
2012-09-03 20:05:39 +00:00
e7f495c094 Unordered: Cleaning up a bit.
[SVN r80388]
2012-09-03 20:05:15 +00:00
1e07edc1ad Unordered: No need for value_allocator.
[SVN r80387]
2012-09-03 20:04:55 +00:00
2f09079d3f Unordered: Remove the now unnecessary uses of ->.
[SVN r80386]
2012-09-03 20:04:35 +00:00
a1bdd82bd5 Unordered: Get rid of buckets.
[SVN r80385]
2012-09-03 20:04:15 +00:00
45b6340a98 Unordered: Avoid allocating nodes in table constructor.
[SVN r80384]
2012-09-03 20:03:55 +00:00
22e6daac6c Unordered: Use node_holder for move.
[SVN r80383]
2012-09-03 20:03:35 +00:00
9ea735c975 Unordered: Move iterators to top of buckets.hpp
[SVN r80382]
2012-09-03 20:03:15 +00:00
31f3a10d33 Unordered: Tweak node_construct functions.
[SVN r80381]
2012-09-03 20:02:53 +00:00
d9f49f2b44 Unordered: Faster assign implementation
[SVN r80380]
2012-09-03 20:02:31 +00:00
73c269398a Unordered: Generic copy/move implementation.
[SVN r80379]
2012-09-03 20:02:10 +00:00
7a4930f1a1 Unordered: Avoid unnecessary swapping in rehash and move.
[SVN r80378]
2012-09-03 20:01:50 +00:00
d5971171da Unordered: Merge from trunk.
- Some changes to the internals, including reverting some of the
  recent changes to constructing values which turned out to be
  more bother than it was worth.
- On C++11 compilers, better use of `construct` and `destroy`.
- Better testing.


[SVN r80350]
2012-09-01 15:50:36 +00:00
035396e89f Unordered: Merge reference documentation update.
[SVN r80294]
2012-08-28 21:56:18 +00:00
c0faf59a86 Unordered: De-template constructor for allocator2 from allocator.
Sun is failing one of the tests because it isn't using it implicitly.


[SVN r80276]
2012-08-28 08:04:51 +00:00
a822b27efc Unordered: Weaken requirements in compile tests.
Assigning a container requires that its elements can be assignable. Could split
the tests up so that other tests aren't assignable, but it doesn't seem worth
the hassle.

[SVN r80228]
2012-08-25 21:56:16 +00:00
f1e716d897 Unordered: Stronger assign testing.
[SVN r80227]
2012-08-25 21:55:46 +00:00
612d68eecd Unordered: More invariant testing.
In case there are elements in buckets that aren't in the element list. Required
because the data structure has changed since the original implementation.

[SVN r80226]
2012-08-25 21:55:18 +00:00
aefea862c2 Unordered: Two exception testing allocators.
For different C++11 properties.

[SVN r80225]
2012-08-25 21:54:50 +00:00
f8968ab022 Unordered: Better swap assertion.
[SVN r80224]
2012-08-25 21:54:18 +00:00
8f86c2464e Unordered: Rename *_impl to *_value_impl.
To make it clear that they should only be used to construct and destroy
the value, and not nodes or buckets.

[SVN r80223]
2012-08-25 21:53:53 +00:00
cd57bf5000 Unordered: And use allocator traits to destroy values.
[SVN r80222]
2012-08-25 21:53:25 +00:00
a7125259d8 Unordered: When full construct is available, use it for value.
[SVN r80221]
2012-08-25 21:52:57 +00:00
3a163b5449 Unordered: Move some things around.
- Move `allocator_traits` before `construct_impl` so the
  `construct_impl` can be changed to use `allocator_traits`.
- Moved some move utilities out of `allocate.hpp` because they're
  really nothing to do with allocation and construction.

[SVN r80220]
2012-08-25 21:52:28 +00:00
ff31c73970 Unordered: Go back to the old method for constructing nodes.
Reverts much of [78349]. Keeps the variadic construct.

[SVN r80219]
2012-08-25 21:51:24 +00:00
2e11fd8a86 Unordered: Test number of copies and moves for moves on all compilers.
Mainly because I want to get more info on the odd test failure for Visual C++
11. I expect that with move emulation these results could vary considerably,
and since I've only tested with gcc and clang so far, it's quite likely that
this test will now fail for other compilers.

[SVN r80200]
2012-08-25 12:52:31 +00:00
09c546f63a Unordered: Document more fine grained requirements.
[SVN r79879]
2012-08-05 18:26:02 +00:00
8683332b2c Unordered: Merge from trunk
- Avoid an incorrect MSVC unused variable warning in the tests.
- Remove a `try..catch`.
- Adjust SFINAE use to try to supprt g++ 3.4. Fixes #7175.
- Fix some use of rvalues.
- Extra info in `at_tests`.



[SVN r79868]
2012-08-05 08:34:44 +00:00
5be71a0e90 Unordered: Output stages in at_tests.
Getting a memory deallocation error from Sandia's linux c++11 clang. Add some
trace output to see if it gives a clue where it's going wrong.

[SVN r79793]
2012-07-29 07:18:35 +00:00
27f5496a65 Unordered: Fix some uses of rvalues refs/move.
[SVN r79792]
2012-07-29 07:17:57 +00:00
918b3da91d Unordered: Use a SFINAE parameter rather than return type for C++03 compilers.
Seems that g++ 3.4 has problems with overloads that are only distinguished by
SFINAE return types.

[SVN r79762]
2012-07-26 22:23:09 +00:00
61516be1db Unordered: Remove use of try..catch.
So that it'll work when exceptions are disabled.

[SVN r79679]
2012-07-22 20:14:20 +00:00
7c968fd38d Unordered: Avoid an MSVC warning.
[SVN r79651]
2012-07-22 07:14:42 +00:00
d77453b7ad Unordered: Merge allocator fix + improved tests. Fixes #7100.
[SVN r79547]
2012-07-15 23:58:02 +00:00
cf9930fe20 Unordered: Merge updated c++11 config macros.
[SVN r79546]
2012-07-15 23:47:12 +00:00
e30a99d2fc Unordered: Merge some of the older changes from trunk.
Code reorganization, simpler tests, better use of Boost.Move.


[SVN r79545]
2012-07-15 23:44:41 +00:00
4a066e4b18 Unordered: Fix unnecessary_copy_tests for MSVC10
Compilers with rvalue references can avoid creating a node, as they can use the
value from the rvalue reference to check if the value is already in the
container (in this case it is) before creating the node. Could possibly do the
same for compilers without rvalue references, if it can get a value out of
Boost.Move's rvalue reference emulation.

[SVN r79503]
2012-07-14 16:45:54 +00:00
0fccd93e29 Switch from deprecated macros to new shiny ones; no functionality change
[SVN r79396]
2012-07-09 22:08:01 +00:00
6932a2d571 Unordered: Fix using a C++03 allocator with C++11 compiler.
Because the nodes had an implicit constructor, the `has_construct` traits was
detecting that the nodes could be constructed by construction then copy, which
really wasn't wanted. Also add a check that nodes aren't been copy constructed
to make sure this doesn't happen again. Refs #7100.

[SVN r79358]
2012-07-08 11:55:57 +00:00
f387994422 Unordered: Test with more allocators.
Causes some C++11 failures....

[SVN r79357]
2012-07-08 11:55:35 +00:00
958b1d468f Unordered: Reduce the amount of meta-stuff in the tests.
Some of this was there for older compilers, some is just premature
generalization. There's still too much metaprogramming, but these are things
that are relatively easy to remove.

[SVN r79356]
2012-07-08 11:55:10 +00:00
f5292fd9f7 Unordered: Simplify the object count stuff.
[SVN r79355]
2012-07-08 11:54:47 +00:00
ada08d9459 Unordered: Turn off warnings-as-errors.
Getting spurious failures for gcc 4.0 and 4.8. It's more hassle than it's
worth.

[SVN r79354]
2012-07-08 11:54:21 +00:00
9a284b4106 Unordered: Remove some junk from the end of memory.hpp
[SVN r79353]
2012-07-08 11:54:01 +00:00
98083078a3 Unordered: Remove malloc_allocator.
It was originally introduced because of some issues with Boost.Test and older
compilers, neither of which I'm using now. Simplifies a few things.

[SVN r79352]
2012-07-08 11:53:39 +00:00
b8d96be8f7 Unordered: Macro to simplifiy variadic/emplace_args creation.
[SVN r79351]
2012-07-08 11:53:16 +00:00
68edec9f97 Unordered: Remove old, unused function.
[SVN r79350]
2012-07-08 11:52:38 +00:00
39bafd7b10 Unordered: Reapply changes reverted in r78788.
[SVN r79163]
2012-06-28 20:58:56 +00:00
0acb4ee3e6 Unordered: Document move insert.
Just a quick copy and paste for tonight's documentation build. May edit a bit
before release.

[SVN r78810]
2012-06-04 22:53:43 +00:00
893ebc5adb Unordered: Don't use std::allocator_traits on Visual C++ 11.
[SVN r78789]
2012-06-01 11:06:03 +00:00
7158700502 Unordered: Revert unmerged changes in trunk.
So that I can fix issues in the beta.


[SVN r78788]
2012-06-01 11:03:22 +00:00
1eac47a275 Unordered: Use Boost.Move in a few more places.
Should be better for compilers with variadic parameters, but no rvalue
references. If such a thing ever exists.

[SVN r78536]
2012-05-21 22:15:33 +00:00
c6f0175c79 Unordered: Combine emplace_args + allocator_helpers.
[SVN r78535]
2012-05-21 22:14:59 +00:00
6031b66f99 Unordered: Fix namespaces for renaming in bcp. Refs #6905.
[SVN r78491]
2012-05-17 06:20:55 +00:00
d863f17673 Unordered: Try to fix Sun compile error.
The Sun compile tests have started failing, I'm not sure what triggered this,
but it seems to be confused by the various uses of the identifier `node`, so
try renaming the class and see if that improves things.

[SVN r78413]
2012-05-10 21:37:44 +00:00
24c08646f4 Unordered: Fix macros for picking construct/destroy.
[SVN r78378]
2012-05-08 11:02:29 +00:00
6604abe600 Unordered: allocator_helpers cleanup.
[SVN r78370]
2012-05-07 18:10:27 +00:00
39aed02e32 Unordered: Check that reserve works for both range and single element insert.
[SVN r78369]
2012-05-07 18:10:04 +00:00
6b44f3b887 Unordered: Fix destroy to match construct in last commit.
[SVN r78368]
2012-05-07 18:09:25 +00:00
cd88cb4a30 Unordered: 'full construct' requires SFINAE expressions.
[SVN r78367]
2012-05-07 12:22:24 +00:00
32dc45b7bd Unordered: Implement reserve. Refs #6857.
[SVN r78365]
2012-05-07 10:58:32 +00:00
275b03e76b Unordered: Avoid -Wshadow warnings. Refs #6190.
[SVN r78364]
2012-05-07 10:57:35 +00:00
995ef1efdb Unordered: Use std::allocator_trait's variadic construct.
[SVN r78349]
2012-05-06 12:29:24 +00:00
8cb85937c4 Unordered: Reactivate std::allocator_traits for gcc 4.7, and try for Visual C++ 11
[SVN r78348]
2012-05-06 12:28:57 +00:00
e615ac67c2 Unordered: allocator_helpers.hpp was moved.
[SVN r78347]
2012-05-06 12:28:05 +00:00
401df0f2fb Unordered/Hash: Release notes.
[SVN r78318]
2012-05-03 21:35:51 +00:00
531f6804ad Unordered: Disable std::allocator_traits on gcc for now.
[SVN r78166]
2012-04-23 20:52:08 +00:00
d5230a874b Unordered: Rejig some of the emplace_args macro code. Refs #6784
This is a bit cleaner and will hopefully fix the Sun problems.

[SVN r77972]
2012-04-14 17:32:28 +00:00
030fd55d02 Unordered: Pull forward declarations out of detail/fwd.hpp
[SVN r77835]
2012-04-08 15:30:35 +00:00
626bb48013 Unordered: Use iterators in more of the implementation methods.
[SVN r77834]
2012-04-08 15:30:14 +00:00
e64f82ed03 Unordered: Fix equality for multimap/multiset.
[SVN r77833]
2012-04-08 15:29:49 +00:00
c8c71d0ad1 Unordered/hash: Avoid a gcc warning. Refs #6771
[SVN r77832]
2012-04-08 15:29:15 +00:00
4e759b4444 Unordered: Call policy functions as static functions.
[SVN r77831]
2012-04-08 15:28:26 +00:00
9f199eaa23 Updated Boost.Unordered to use BOOST_NO_0X_HDR_INITIALIZER_LIST instead of (soon to be deprecated) BOOST_NO_INITIALIZER_LISTS
[SVN r77154]
2012-03-02 16:43:58 +00:00
2fed2fbd9e Unordered: Hashing policy for 64 bit computers.
[SVN r77066]
2012-02-18 15:47:59 +00:00
29d63e378b Unordered: Remove unnecessary typename.
Oddly, newer versions of gcc don't complain about it.

[SVN r77043]
2012-02-16 20:53:45 +00:00
8a1a475c58 Unordered: Use container's allocator_traits for old Visual C++.
[SVN r77017]
2012-02-14 23:55:09 +00:00
08230efb44 Unordered: Use C++11 allocator_traits with gcc 4.7.
[SVN r76970]
2012-02-11 12:33:25 +00:00
2aee3add16 Unordered: Remove some of the smaller primes.
There's quite a high chance of collisions for these values.

[SVN r76969]
2012-02-11 12:33:02 +00:00
f6b8d3957d Unordered: Remove unnecessary typename.
[SVN r76906]
2012-02-05 23:21:45 +00:00
992cc0b077 Unordered: Some C++11 allocator_traits fixes.
Can now be used with g++ 4.7. Not activating by default yet.

[SVN r76893]
2012-02-05 08:45:52 +00:00
2f92b12205 Unordered: Missing include in test header.
[SVN r76892]
2012-02-05 08:45:31 +00:00
2e80a82554 Unordered: Fix undefined macro warnings. Refs #6522.
Just removing the rv reference stuff in extract_keys. I don't it's
needed anyway.

[SVN r76891]
2012-02-05 08:44:22 +00:00
51d2e2564e Unordered: Add tests for when Boost.Move is activated.
[SVN r76415]
2012-01-11 22:23:49 +00:00
2665090568 Unordered: Use Boost.Move for variadic forwarding.
[SVN r76331]
2012-01-06 08:36:43 +00:00
d70fcb8c25 Unordered: Make using Boost.Move optional.
[SVN r76330]
2012-01-06 08:35:51 +00:00
ac0a2fe6c9 Fix 'occurred' in iostreams and unordered. Refs #6003
[SVN r76144]
2011-12-24 19:00:08 +00:00
6c09b89d0c Unordered: Change log for fairly minor changes.
[SVN r75907]
2011-12-11 21:36:26 +00:00
8f982c8b27 Unordered: Fix forwarding from emplace.
[SVN r75856]
2011-12-07 19:18:11 +00:00
a61e876300 Unordered: emplace cleanup.
- Always construct iterator in detail for consistency.
- Move 0-argument emplace to start of overloads.

[SVN r75744]
2011-11-30 08:21:58 +00:00
684e40464f Unordered: Manually write out some overloads for emplace.
Clang creates horrific error messages for Boost.Preprocessor based code,
so for small number of arguments manually write out a few important
functions. Not doing this everywhere.

[SVN r75743]
2011-11-30 08:21:38 +00:00
2507fd78e3 Unordered: Move rebind into 'types' classes.
Makes the types in error messages a tad bit nicer.

[SVN r75742]
2011-11-30 08:21:04 +00:00
21f1fe8185 Unordered: Try to avoid warning from boost/cstdint.hpp.
[SVN r75607]
2011-11-22 22:13:12 +00:00
aeea8e05ad Unordered: Fix gcc warning and re-enable warnings-as-errors for gcc.
[SVN r75599]
2011-11-21 23:21:11 +00:00
11c9955902 Unordered: Remove support for TR1 tuples. Refs #6111.
[SVN r75432]
2011-11-10 15:16:06 +00:00
9cb361f35e Unordered: construct_from_tuple for old versions of sun.
Not properly tested, as I haven't got the compiler fully working on my
machine.

[SVN r75341]
2011-11-06 09:34:54 +00:00
c3477b2624 Unordered: Don't use SFINAE expression hack on Visual C++.
Sometimes it doesn't work. This means I can clean up the implementation
for other compilers, but I'll leave that for now.


[SVN r75167]
2011-10-29 16:31:40 +00:00
a5dcc9dab0 Unordered: Return iterators in pairs instead of node_pointers.
It looks like the current version doesn't work with a correct
implementation of C++11 pairs since they don't use explicit conversions.
So just return the correct type in the first place.

Should probably be using iterators in other places as well. I was using
node_pointers everywhere due to some legacy from older versions.

[SVN r75158]
2011-10-28 17:42:51 +00:00
6ebc2e72ff Unordered: Rename B0, B1 etc. to avoid macro clash. Refs #6062.
[SVN r75123]
2011-10-26 21:31:27 +00:00
d2a6ad8c72 Unordered: Documentation update.
[SVN r74962]
2011-10-16 10:31:25 +00:00
087962c16e Unordered: Fix move tests where moving returned values is not supported.
The propagate on move tests were failing because the values were being
copied not moved - so the container was check propagate on copy instead.
Because those tests are now weaker, and some new ones that will
hopefully work.

[SVN r74914]
2011-10-11 08:37:06 +00:00
4471e056f4 Unordered: Avoid passing UDTs through ....
[SVN r74913]
2011-10-11 08:36:23 +00:00
b56a5ead66 Unordered: Some inspect fixes.
[SVN r74908]
2011-10-11 00:31:19 +00:00
e3befdba7f Unordered: Update comparison between unordered and ordered containers.
[SVN r74907]
2011-10-11 00:30:59 +00:00
0cf8de5222 Unordered: Fix documentation markup error.
[SVN r74846]
2011-10-09 11:54:10 +00:00
b6a6f530c0 Unordered: Only pair reference test where it's known to be okay.
[SVN r74845]
2011-10-09 11:53:38 +00:00
03245c80ff Unordered: Turn off warnings as errors and debug libs.
I'm getting a warning from another library. I don't really need to check
debug libs anymore - that was for container_fwd which is now tested in
details.

[SVN r74840]
2011-10-09 07:56:28 +00:00
2775ae2f2e Unordered: Correct fix for old gcc.
[SVN r74836]
2011-10-09 01:23:25 +00:00
8557a30592 Unordered: Fix dependent type.
[SVN r74832]
2011-10-09 00:47:08 +00:00
fd530b87f6 Unordered: Remove use of BOOST_PP_ENUM_SHIFTED.
Doesn't seem to work on Intel's preprocessor.

[SVN r74813]
2011-10-08 17:39:54 +00:00
674d635024 Unordered: Move has_member into nested struct for sun.
[SVN r74812]
2011-10-08 17:39:36 +00:00
f304e56818 Unordered: Stop using void_pointer.
Was breaking for allocators that don't have good enough support for
void_pointer. Which I suspect is pretty common.

[SVN r74800]
2011-10-08 12:17:27 +00:00
5a2bf64a65 Unordered: Just do member detection on older compilers.
[SVN r74799]
2011-10-08 12:17:09 +00:00
f1b78931d1 Unordered: More misc. cleanup.
Including removing node.hpp.

[SVN r74775]
2011-10-07 08:19:53 +00:00
3d7b6c64b5 Unordered: some more formatting + namespaces
[SVN r74767]
2011-10-06 21:31:25 +00:00
597d93537d Unordered: More cleaning up.
Fix deprecated construct_impl and explicit namespaces in a few places.

[SVN r74766]
2011-10-06 21:06:35 +00:00
3a909c8747 Unordered: Better emplace_args implementation.
And some misc. cleanup.

[SVN r74750]
2011-10-06 08:03:25 +00:00
ad38ecf6d8 Unordered: Remove some std::cout debugging. Oops.
[SVN r74746]
2011-10-05 22:05:52 +00:00
dac1dc5837 Unordered: Reorganization to use void pointers and other things.
Helps allocators which can't use incomplete pointers, and avoid using
base pointers where that might not be possible.  And some other
reorganization. Storing arguments to emplace in a structure when
variadic template parameters aren't available. Changed some of the odd
design for working with older compilers.

[SVN r74742]
2011-10-05 19:45:14 +00:00
c0aaf908c0 Unordered: Tweak member detection for sun.
Detect using a member pointer, rather than a member function pointer.
Sun seems to be happier with that.

[SVN r74605]
2011-09-28 23:50:27 +00:00
b1d782285c Unordered: Remove void cast.
I don't think it's needed.

[SVN r74542]
2011-09-23 20:27:39 +00:00
b0620a46ff Unordered: Don't use BOOST_UNORDERED_HAS_FUNCTION with Sun.
Something is causing the sun compiler to crash. I don't know if it's the
member detection or testing if the member if callable, so try disabling
the callable test to see if that works better.

[SVN r74541]
2011-09-23 20:27:22 +00:00
340c98d89a Unordered: New member function detection.
Based on Ion's `has_member_function_callable_with`.

[SVN r74532]
2011-09-22 23:56:49 +00:00
78241de393 Unordered: at is in the standard.
[SVN r74531]
2011-09-22 23:56:28 +00:00
dbf7c9d6aa Unordered: Note about backwards compatability in emplace.
[SVN r74383]
2011-09-15 08:22:29 +00:00
983ad956e0 Unordered: Change log note about new emplace.
[SVN r74379]
2011-09-14 21:06:38 +00:00
45273ea6a5 Unordered: Remove more parts of rationale made unnecessary by C++11.
[SVN r74378]
2011-09-14 21:05:53 +00:00
9b82dcde10 Unordered: Update equality documentation.
[SVN r74377]
2011-09-14 21:05:13 +00:00
b496bc3fa2 Unordered: fix swap documentation.
[SVN r74376]
2011-09-14 21:04:23 +00:00
f8abb9633a Unordered: Revert [74315].
I checked it in due to some clumsy rebasing.


[SVN r74326]
2011-09-09 10:42:56 +00:00
76c37f7805 Unordered: Sunpro doesn't have nullary emplace().
[SVN r74319]
2011-09-08 21:11:16 +00:00
7d441864ec Unordered: Remove use of allocator utilities.
[SVN r74317]
2011-09-08 21:10:39 +00:00
ccd895a356 Unordered: Extra check for vacpp's odd failure.
VACPP 11.0 appears to be detecting a move for nothing more than a
default initialised value.

[SVN r74316]
2011-09-08 21:10:18 +00:00
8ecdee5a93 Unordered: Try to fix vacpp's issue with select_on_container_copy_construction
[SVN r74315]
2011-09-08 21:09:56 +00:00
70c39ad5ea Unordered: Revert [74236].
On vacpp `has_select_on_container_copy_construction` was incorrectly returning
positive for a non-const `select_on_container_copy_construction`. This resulted
in a compile error as it tried to call it for a const allocator. The workaround
seemed to have just made things worse so I'm reverting it. It's actually not
that bad a problem as a non-const `select_on_container_copy_construction` is
probably a mistake.


[SVN r74294]
2011-09-07 10:01:25 +00:00
96fc0fa3c2 Unordered: Try to fix vacpp's issue with select_on_container_copy_construction
[SVN r74236]
2011-09-05 08:06:17 +00:00
c101aec06c Unordered: Use destroy workaround for allocator_traits.
[SVN r74235]
2011-09-04 19:49:11 +00:00
bd79d02049 Unordered: Remove unreachable code.
[SVN r74218]
2011-09-04 11:58:56 +00:00
0ea847a64e Unordered: Documentation changes.
[SVN r74194]
2011-09-02 08:29:23 +00:00
965e25c989 Unordered: Try to fix issues with moving non-class types.
[SVN r74193]
2011-09-02 08:28:52 +00:00
a3ffd4a7c9 Unordered: Remove BOOST_DEDUCED_TYPENAME
[SVN r74192]
2011-09-02 08:28:19 +00:00
41b9b8d841 Unordered: Remove pair cast.
[SVN r74191]
2011-09-02 08:27:27 +00:00
26a47d33c1 Unordered: Use return type SFINAE, seems to be more portable.
[SVN r74182]
2011-09-01 08:26:36 +00:00
1154b5729a Unordered: Deprecate variadic pair construction emulation.
[SVN r74181]
2011-08-31 22:57:57 +00:00
fd1aec2998 Unordered: Add option to use old equality implementation for backwards compatability.
[SVN r74180]
2011-08-31 22:23:01 +00:00
659b6fe8ba Unordered: Another attempt at member detection.
Another stab in the dark. Doing SFINAE in the return type appears to
work well, apart for Visual C++ 8.0. Will have to see how the test
results go for some compilers.

[SVN r74173]
2011-08-30 22:02:27 +00:00
ceef4d6521 Unordered: Explicitly pick construct_impl overloads.
Still getting ambiguous call errors for some older compilers, so use SFINAE to
only enable a single overload for each arity.

[SVN r74171]
2011-08-30 22:01:54 +00:00
86b077b9a1 Unordered: Use quickbook 1.5
[SVN r74143]
2011-08-29 17:14:28 +00:00
28cdebe7a4 Unordered: Update erase reference.
[SVN r74142]
2011-08-29 17:14:09 +00:00
d4087f64d9 Unordered: Fix boostbook errors.
[SVN r74141]
2011-08-29 17:13:27 +00:00
4ec5a0eebd Unordered: updating reference documentation.
[SVN r74137]
2011-08-29 15:23:32 +00:00
f58a3fc3eb Unordered: Another breaking change.
[SVN r74136]
2011-08-29 15:22:00 +00:00
11562b3285 Unordered: Update docs since it's now based on C++11
[SVN r74135]
2011-08-29 15:21:04 +00:00
568fd1758d Unordered: More info on C++11 compliance.
[SVN r74134]
2011-08-29 15:20:27 +00:00
f64b5ba3f8 Unordered: Account for cost of creating tuple.
[SVN r74133]
2011-08-29 15:19:40 +00:00
395c744d6f Unordered: More portability changes.
[SVN r74122]
2011-08-29 11:10:09 +00:00
155077cba0 Unordered: Support piecewise pair construction.
Will need to deprecate the old variadic style pair construction, also
should look into extract_key, was written for compatibility with older
compilers that are no longer supported.

[SVN r74119]
2011-08-29 09:40:41 +00:00
4dcf34c264 Unordered: Restore at_tests.
[SVN r74108]
2011-08-28 15:43:08 +00:00
4bf3b1bfc5 Unordered: Support optional allocator methods.
Only for compilers with SFINAE expressions and recent versions of Visual
C++. Also fix Visual C++ 8, and use BOOST_UNORDERED_ prefix for all
macros.

[SVN r74106]
2011-08-28 15:36:58 +00:00
6bc99ac0c2 Unordered: Hopefully vacpp will like this more.
[SVN r74103]
2011-08-28 11:31:43 +00:00
09e856562a Unordered: Try to avoid warning on sun.
[SVN r74102]
2011-08-28 11:31:23 +00:00
5dd13dbfb3 Unordered: Try to avoid std::size_t to double warnings.
Maybe I should use long double?

[SVN r74087]
2011-08-27 11:53:48 +00:00
9ae19a64d7 Unordered: Fix more calls to std::forward.
[SVN r74086]
2011-08-27 11:29:04 +00:00
bd13f2b1ad Unordered: Fix some calls to std::forward.
[SVN r74074]
2011-08-26 15:28:56 +00:00
d09bbba6c1 Unordered: Missing limits header in tests.
[SVN r74073]
2011-08-26 15:24:47 +00:00
3f4d031c43 Unordered: Remove extra ';'.
[SVN r74072]
2011-08-26 15:24:16 +00:00
674b39243f Unordered: More robust construct_impl.
[SVN r74068]
2011-08-26 08:12:08 +00:00
099a893678 Unordered: More portable allocator_traits.
[SVN r74067]
2011-08-26 08:11:46 +00:00
cfd52c8f38 Unordered: Fix compiler check in unnecessary_copy_tests.
[SVN r74066]
2011-08-26 08:11:12 +00:00
e295541dae Unordered: Try to make VC++ 8 happy.
[SVN r73973]
2011-08-20 23:34:59 +00:00
785a6def3b Unordered: Remove another use of BOOST_RV_REF for sun.
[SVN r73972]
2011-08-20 23:34:38 +00:00
53bdec8aab Unordered: More unnecessary_copy_tests tweaks.
[SVN r73971]
2011-08-20 23:34:14 +00:00
5191897696 Unordered: Compliance TODO note
[SVN r73895]
2011-08-18 19:29:22 +00:00
2ecfa0e08c Unordered: Fix unnecessary_copy_tests failures.
[SVN r73894]
2011-08-18 19:29:02 +00:00
c001139465 Unordered: detab
[SVN r73893]
2011-08-18 19:28:41 +00:00
e3353a445a Unordered: Fix some test failures.
[SVN r73856]
2011-08-17 21:29:41 +00:00
ce779452ba Unordered: Fix gcc error + warning.
[SVN r73839]
2011-08-17 07:43:43 +00:00
eb8b8295a1 Unordered: Fix an xml error in the docs.
[SVN r73830]
2011-08-16 22:19:00 +00:00
94c9c61142 Unordered: Document new changes and C++11 compliance.
[SVN r73829]
2011-08-16 22:18:09 +00:00
11e390bf42 Unordered: Use Boost.Move in minimal tests.
[SVN r73828]
2011-08-16 22:17:11 +00:00
a8fdf19c91 Unordered: Test types that are only destructible.
[SVN r73820]
2011-08-16 18:08:23 +00:00
08bca9a35f Unordered: Support moving allocators.
[SVN r73805]
2011-08-15 21:34:01 +00:00
1db630d5c9 Unordered: Enable the better select_on_container_copy_construction detection for recent Visual C++.
[SVN r73799]
2011-08-15 20:24:12 +00:00
bbad921022 Unordered: Fix some portability issues in tests.
- Simplify mechanism for detecting traits of test allocators. There were
  some portability issues, but rather than fix them I've just gone for a
  simpler mechanism. Does mean that the relevant tests can't be run for
  other allocators.
- Fix a couple of unnecessary_copy_tests, whose results were the wrong
  way round.
- It appears that Visual C++ only implements RVO for implicitly defined
  copy constructors in debug mode, so adjust a move_test to account for
  the extra copies now that the copy constructors are explicitly
  defined.

[SVN r73798]
2011-08-15 20:23:29 +00:00
f64cf03e1d Unordered: Implement select_on_container_copy_construction support.
[SVN r73772]
2011-08-15 07:48:53 +00:00
559122f67a Unordered: Small improvements for windows.
[SVN r73760]
2011-08-14 21:03:18 +00:00
431f2abfee Unordered: Alternative member detection.
Hopefully the Sun compiler will like this.

[SVN r73757]
2011-08-14 18:53:50 +00:00
5f622027cd Unordered: Implement allocator propagation on assignment.
It's pretty messy because I'm trying to avoid swapping allocators in
these cases. I'm also not sure of the exception requirements of
allocator swap and assignment.

[SVN r73756]
2011-08-14 18:53:29 +00:00
fa97494cc8 Unordered: Move some of the unordered implementation.
[SVN r73755]
2011-08-14 18:53:03 +00:00
f4d4975077 Unordered: Count instances in some tests.
[SVN r73754]
2011-08-14 18:52:43 +00:00
f030480e44 Unordered: detab.
[SVN r73753]
2011-08-14 18:52:20 +00:00
435c21c155 Unordered: Qualify calls to addressof.
Hopefully this will fix C++0x compilers. Although I don't have one at
hand to test.

[SVN r73690]
2011-08-12 06:26:25 +00:00
7438d7a02f Unordered: Move around assignment stuff.
[SVN r73681]
2011-08-11 21:19:05 +00:00
0e5930b8dc Unordred: Implement propagate_on_container_swap.
[SVN r73680]
2011-08-11 21:18:43 +00:00
eacca89d4e Unordered: Starting to implement allocator propagation.
[SVN r73679]
2011-08-11 21:18:19 +00:00
99e6bef4ef Unordered: Starting to support allocator_traits.
[SVN r73678]
2011-08-11 21:17:57 +00:00
3d5314b5f5 Unordered: Don't use BOOST_RV_REF with Sun compilers.
[SVN r73593]
2011-08-07 10:22:41 +00:00
f0517463a5 Unordered: Better std::forward/move configuration.
[SVN r73592]
2011-08-07 08:55:28 +00:00
c9e0fb9730 Unordered: Update unnecessary_copy_tests for Boost.Move.
Seems to be better in some cases. For example, better forwarding if
rvalue references are supported but variadic template parameters aren't.
Also can use `boost::move` when inserting.

Older versions of gcc still fail this test. They perform more moves than
expected. It might be a limitation of Boost.Move, or maybe just poor
copy optimization.

[SVN r73539]
2011-08-04 22:54:26 +00:00
d86a4b0c2f Unordered: Use Boost.Move for emplace and insert.
[SVN r73520]
2011-08-03 23:52:37 +00:00
eced4266c2 Unordered: Copy and assign using Boost.Move.
[SVN r73503]
2011-08-03 08:34:33 +00:00
fc483e60bc Unordered: Fix link to swap issue.
[SVN r73502]
2011-08-03 08:34:11 +00:00
910cd41c47 Unordered: Generate ref docs using php.
[SVN r73501]
2011-08-03 08:33:37 +00:00
b4e1d32e85 Unordered: detab.
[SVN r72906]
2011-07-04 21:55:40 +00:00
ff66f79721 Unordered: Import functions into boost namespace.
[SVN r72905]
2011-07-04 21:52:17 +00:00
8b610a6d34 Unordered: Work around for compilers which don't support template friend members.
[SVN r72523]
2011-06-09 19:48:34 +00:00
20e923ba0d Unordered: Move the implementation into a namespace.
Although it typically won't prevent ADL, because of boost::hash.

[SVN r72391]
2011-06-04 16:17:07 +00:00
4777eaf367 Unordered: remove some dead, bad code.
[SVN r72390]
2011-06-04 16:15:27 +00:00
a40422fada Unordered: remove use of the 'or' keyword.
[SVN r71602]
2011-04-29 11:03:29 +00:00
b1912055a9 Unordered: Fix some errors in the equality tests.
[SVN r71363]
2011-04-17 21:27:38 +00:00
e8714d79b2 Unordered: Implement C++0x equality.
[SVN r71354]
2011-04-17 16:23:25 +00:00
f8e2a917f9 Unordered: 2 phase lookup fix for clang.
[SVN r71352]
2011-04-17 14:27:08 +00:00
140e8852e8 Unordered: fix some gcc issues.
[SVN r71346]
2011-04-17 00:31:35 +00:00
547e141166 Unordered: Overhaul the implementation.
Store nodes in a single linked list, with hash values so that their
buckets can be found when needed. Iterators now only have to store a
pointer to the node and don't have to iterate over empty buckets to
reach the next node. This allows the container to meet the iterator
requirements - fixing the speed issues with `equal_range` and `erase`.

Also, define iterators in their own namespace, so that they don't
accidentally pull in detail functions via ADL.

I've simplified the code slightly by removing some of the special
cases for empty containers. Renamed a few things as well and other
minor changes that were made as I went along.

[SVN r71327]
2011-04-16 18:47:33 +00:00
d9c49a6cde Don't require explicit conversion in pairs in unordered's insert tests.
In the draft standard the std::pair constructor from another pair is
only considered when overloading if both members are implicitly
constructible to their corresponding members. This breaks one of the
unordered tests which required an explicit conversion, so change it to
only require an implicit conversion.

[SVN r70028]
2011-03-16 21:34:08 +00:00
8ade57b9e3 Remove workaround for ancient gcc verisons.
[SVN r70027]
2011-03-16 21:33:41 +00:00
a4750fbdba Make unnecessary_copy_tests a bit more lenient.
I'm not sure if those extra moves are avoidable, but I'll allow them for
now. They shouldn't hurt much.

[SVN r68446]
2011-01-25 20:15:27 +00:00
a33949a0a5 Add copy constructors and assignment operators when using rvalue references. Refs #5119.
[SVN r68445]
2011-01-25 20:13:43 +00:00
4d57147c3d Fix tabs and files without copyright.
[SVN r67612]
2011-01-03 12:43:34 +00:00
3d7abd9cbe Avoid -Wconversion warnings in unordered & hash.
[SVN r67170]
2010-12-11 14:43:00 +00:00
5a81ca6ffe Import boostbook/quickbook in unordered and hash docs.
[SVN r67091]
2010-12-07 20:45:08 +00:00
b9188caf7d Fix [66556] - Remove clang workaround.
I accidentaly removed the good code and left the workaround in. Also, a
correction to the comment: I think bug was only in a unreleased version
of clang.

[SVN r66567]
2010-11-14 11:43:49 +00:00
df726c038f Remove some 'always_show_run_output' flags.
[SVN r66566]
2010-11-14 11:42:58 +00:00
14e0e1afc2 Less use of the ampersand operator in unordered.
[SVN r66557]
2010-11-13 12:31:54 +00:00
2c1a8894cb Remove clang workaround.
Clang from llvm 2.8 doesn't need it. Clang form llvm 2.7 isn't
supported.

[SVN r66556]
2010-11-13 12:30:45 +00:00
a49c76c69c More comments describing the unordered internals.
And fix a couple of small mistakes in the existing comments.

[SVN r66555]
2010-11-13 12:30:06 +00:00
eb04f68351 Call forward declared functions from templates in unordered tests.
Borland is having some issues with the existing tests, since they call
inline functions before they're defined. It might be right to, although
all the other compilers are fine with it. But the test isn't really what
the forward headers are intended for. Try to make the tests better
represent the intent, and possibly work on Borland.

[SVN r66428]
2010-11-07 14:43:50 +00:00
77bd36d038 Declare inline functions as inline.
[SVN r66193]
2010-10-25 21:59:52 +00:00
1b85f812af Missing copy_iterator methods.
[SVN r66137]
2010-10-21 20:34:39 +00:00
daad24388c Fix iterator insert bug in unordered_set/unordered_map.
[SVN r66136]
2010-10-21 20:23:37 +00:00
0cbd02d3cc Fix images in standalone unordered documentation.
[SVN r63451]
2010-06-30 12:05:36 +00:00
3a13ddb4a3 Don't use _GLIBCXX_DEBUG on darwin.
It isn't supported by Apple's gcc 4.2.

[SVN r63449]
2010-06-30 12:04:41 +00:00
7b272c85d5 Missing bracket.
[SVN r63392]
2010-06-27 16:58:48 +00:00
5edc45349f Revert changes for sun 5.9.
Nobody seems to be running the tests now.


[SVN r62117]
2010-05-21 07:06:33 +00:00
dfaa61b666 Another inline.
[SVN r61872]
2010-05-09 07:24:47 +00:00
076e195cac Define several methods inline.
Sun 5.9 was having some issues.

[SVN r61831]
2010-05-06 20:13:25 +00:00
71a8e56ae3 Move equivalent and unique hash tables into their own headers.
[SVN r61830]
2010-05-06 20:12:40 +00:00
ef79fea0b7 The clang workaround broke some compilers, so only use it for clang.
[SVN r61529]
2010-04-24 12:59:35 +00:00
ea33b5d134 Fix clang warnings in unordered tests.
[SVN r61505]
2010-04-23 07:26:43 +00:00
5bab4d4360 Work around friend bug in clang.
[SVN r61504]
2010-04-23 07:25:53 +00:00
10e24f93c4 Unordered/hash release notes.
[SVN r61356]
2010-04-18 13:20:45 +00:00
00cebc3dfb Use boost::throw_exception in unordered.
[SVN r60983]
2010-03-31 21:42:08 +00:00
ee034e23bb Add quick_erase to the unordered containers. Refs #3966.
[SVN r60754]
2010-03-22 00:42:07 +00:00
1d02663275 Try to avoid a warning.
[SVN r59956]
2010-02-26 20:50:21 +00:00
e594f1eda7 Remove deprecated macros for hash and unordered's tests.
[SVN r59708]
2010-02-16 22:33:10 +00:00
1bcb5f8b6f Take advantage of the simplified parameters.
[SVN r59707]
2010-02-16 22:32:49 +00:00
06f63fdc0d Stop using the deprecated BOOST_HAS_ macros in unordered and hash.
[SVN r59697]
2010-02-15 23:01:06 +00:00
7efcf9ccff Set length of primes inside template on Sun C++. Refs #3854
[SVN r59200]
2010-01-21 18:01:53 +00:00
6649b4df3c Update changelogs and slightly improved reference documentation for new release.
[SVN r58805]
2010-01-08 06:43:57 +00:00
71096f4d26 Formatting changes, mostly to fit within 80 characters.
Also, some C casts converted to static_cast.

[SVN r58692]
2010-01-04 22:49:39 +00:00
0f0161a5a2 Add codegear compatibility to the changes.
[SVN r58406]
2009-12-15 22:53:54 +00:00
b99382b551 Add templated find overload for compatible keys.
[SVN r58405]
2009-12-15 22:53:33 +00:00
493f905598 Fix the return type of find in the unordered reference documentation.
[SVN r58404]
2009-12-15 22:53:08 +00:00
4e6292b439 Implement an alternative erase function that doesn't return an iterator.
Ref #3693

[SVN r58403]
2009-12-15 22:52:52 +00:00
2f0a94bcfd Add missing std:: qualifier to ptrdiff_t. Refs #3773.
[SVN r58402]
2009-12-15 22:42:04 +00:00
618a51df13 Turn off warnings as errors on gcc/darwin because the integer library currently causes some warnings.
[SVN r58394]
2009-12-15 13:16:32 +00:00
18a5010436 Remove use of iterator_adaptor in unordered tests.
[SVN r58144]
2009-12-04 19:44:34 +00:00
c8b893cb77 Workaround codegear ICE.
It seems that the problem is calling sizeof on a dependent type when the
containers have only been used by reference. So by putting in these
dummy structures with the containers as members, it helps the compiler
instantiate the class to the level where sizeof works. I hope.

[SVN r58130]
2009-12-04 00:51:50 +00:00
a1252fcc0e Use consistent names for template parameters.
I'm trying to fix the codegear ICEs, but it's hard to tell the cause.
Since the error happens operator== I suspect it's either to do
with defining friend functions with different template names or
something to do with friend functions in general. This is the first stab
in the dark at fixing this.

[SVN r58062]
2009-11-30 18:25:26 +00:00
ef67d9ae12 Document the unordered changes.
[SVN r58004]
2009-11-28 11:46:24 +00:00
3e638049ec Try to support incomplete types for Sun - at the expense of zero argument emplace.
[SVN r58002]
2009-11-28 11:46:05 +00:00
7f59e8e058 Better testing of incomplete types.
[SVN r57975]
2009-11-27 19:43:06 +00:00
7023460394 Suppress a warning that's in the windows mobile system headers.
[SVN r57963]
2009-11-26 23:15:30 +00:00
0dcf1b5cd2 Fix the version check when suppressing warnings.
[SVN r57962]
2009-11-26 23:14:53 +00:00
7b2c5189b3 Suppress some warnings on visual c++ 7.1.
[SVN r57921]
2009-11-25 09:14:16 +00:00
d3fe62a646 Try to avoid an odd warning from Visual C++
[SVN r57919]
2009-11-25 09:09:25 +00:00
1f17294cd3 Use remove_const again.
[SVN r57840]
2009-11-21 20:37:50 +00:00
3882a61065 Inspect fixes.
[SVN r57838]
2009-11-21 19:40:28 +00:00
df72c4886f Support incomplete template parameters to unordered containers.
[SVN r57798]
2009-11-20 08:03:26 +00:00
26c72f9860 Use 'E' for key extractor, freeing 'K' for key.
[SVN r57797]
2009-11-20 08:02:48 +00:00
55957bbab5 Some more warning fixes for Visual C++ 7.1
[SVN r57719]
2009-11-16 23:56:37 +00:00
ab843eb587 Fix a warning on Visual C++ 7.1. Although, I don't think I'm going to be warning free on the compiler.
[SVN r57617]
2009-11-12 21:36:27 +00:00
4438b8e017 Fix a warning that only shows up in release builds.
[SVN r57556]
2009-11-10 20:07:50 +00:00
5747836754 Change unordered move tests to be more lenient on compilers without NRVO. Will probably need to reintroduce some of the failure markup later.
[SVN r57550]
2009-11-10 18:17:53 +00:00
ba5c383877 Stricter warnings for unordered and hash.
There are still warnings in hash_complex_test.

[SVN r57537]
2009-11-10 08:15:55 +00:00
b4f08db391 Remove 'grouped' from hash_table as it isn't used and is a bit confusing.
[SVN r57153]
2009-10-25 10:55:27 +00:00
060acb3f25 Slightly rearrange the unordered container headers so that prev_prime is defined before it's used.
[SVN r57152]
2009-10-25 10:55:08 +00:00
8727de1a1b Remove insert empty initializer lists, as there's a bug in gcc.
[SVN r57151]
2009-10-25 10:54:53 +00:00
8cde8d1252 Fix the intel strict flag.
[SVN r57150]
2009-10-25 10:54:28 +00:00
6bac25221a Fix unordered for intel strict.
[SVN r57139]
2009-10-24 17:53:03 +00:00
5bedbde746 Update the intel compile flags.
[SVN r57126]
2009-10-24 11:56:30 +00:00
2fdd33381c Fix allocator for construct from initializer list.
[SVN r57006]
2009-10-19 19:32:09 +00:00
8d4b503e56 Use normal emplace implementation for emplace_hint and insert with hint.
There's a bug in the emplace_hint implementation for unordered
containers with equivalent keys. Since my tests missed it, I'm just
going to use the normal emplace implementation until I write better
tests.

[SVN r57005]
2009-10-19 19:24:33 +00:00
6c24cccf96 Add release notes for unordered.
[SVN r56988]
2009-10-18 20:18:28 +00:00
51fdfa7ac7 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
3dff89c240 Correct macro checks for initializer lists.
[SVN r56844]
2009-10-14 20:30:48 +00:00
4e07c94502 Copy the unordered and hash CMake files from release.
[SVN r56704]
2009-10-10 15:09:02 +00:00
854dc0b353 Various inspect fixes.
[SVN r56603]
2009-10-05 21:29:39 +00:00
373791d0b2 Detab.
[SVN r56571]
2009-10-04 10:37:56 +00:00
fe3d612fe0 Clean up some unordered TODOs.
[SVN r56570]
2009-10-04 10:37:36 +00:00
ae0c97a77a Make sure inserting from a range of types other than the value type is better tested.
[SVN r56562]
2009-10-03 16:42:20 +00:00
788a3661a2 Update the unordered rationale.
[SVN r56561]
2009-10-03 16:42:00 +00:00
1e24f85fbc Insert using initializer lists.
[SVN r56560]
2009-10-03 16:41:32 +00:00
4601f5c51f Stricter insert exception tests.
[SVN r56559]
2009-10-03 16:41:11 +00:00
55eafdf0ee Update reference docs to latest version of draft standard and fill in
some missing details.

[SVN r56558]
2009-10-03 16:40:53 +00:00
63e04cfb60 Fix the iterator category.
[SVN r56557]
2009-10-03 16:40:26 +00:00
d0a3efab6a Just remove the test since the test itself doesn't work on most compilers.
[SVN r56468]
2009-09-29 07:46:44 +00:00
2b8680d2c4 Remove the optimization for std::pair with a key reference. It'll be too much hassle to get a very unusual use case to work on all compilers.
[SVN r56461]
2009-09-28 23:06:03 +00:00
31cd8f4e16 Try supporting reference parameters in pairs. Probably not required.
[SVN r56441]
2009-09-27 19:12:04 +00:00
b75b7dd5ac Remove temporary test.
[SVN r56374]
2009-09-24 20:42:19 +00:00
437a35feaa Remove the emplace_hint implementation for unique containers as it isn't really used and seems to be causing sun 5.7 problems.
[SVN r56363]
2009-09-22 22:39:17 +00:00
f76af2d0c8 Another std::max.
[SVN r56362]
2009-09-22 22:39:00 +00:00
efbf13685e Use std::max.
[SVN r56349]
2009-09-21 21:18:21 +00:00
08d533cb88 Fix a bug that was causing unnecessary rehahes.
[SVN r56348]
2009-09-21 21:18:01 +00:00
ff6e457651 Fix bug where container was reducing the number of buckets.
[SVN r56347]
2009-09-21 21:17:40 +00:00
965c2ae89c Slightly more consistent variable names. In detail 'n' is now always a node pointer.
[SVN r56346]
2009-09-21 21:17:19 +00:00
78b078f41d Since all the compilers support out of line template members use them
and lots of other things.

[SVN r56329]
2009-09-20 21:55:15 +00:00
491fa330f6 Move size_ and cached_begin_bucket_ into table, rename hash_table_manager hash_buckets.
[SVN r56010]
2009-09-04 07:03:04 +00:00
9ec148aec5 Fix link to n2691.
[SVN r56009]
2009-09-04 07:02:28 +00:00
7598d0d49b Add a small test to see if the tested compilers support out of line template methods.
[SVN r55992]
2009-09-03 07:37:30 +00:00
6a8506d959 Remove some old Visual C++ workarounds.
[SVN r55991]
2009-09-03 07:37:14 +00:00
7fe53ef5a3 Combine hash_structure and hash_table_manager.
[SVN r55990]
2009-09-03 07:36:21 +00:00
1743ed118d Remove 'static' from next_node and node_count. Will hopefully make vacpp happy.
[SVN r55922]
2009-08-31 15:33:49 +00:00
848b73f99f Remove a few unused parameters.
[SVN r55921]
2009-08-31 15:33:28 +00:00
ccc88ecf0a Remove unnecessary BOOST_DEDUCED_TYPENAMEs
[SVN r55902]
2009-08-31 10:39:40 +00:00
c40cb50fe5 Detab.
[SVN r55901]
2009-08-31 10:39:25 +00:00
386d9f28d7 Initial checkin of new version of Boost.Unordered.
- More template use, less preprocessor use.
 - Removed some of the Visual C++ 6 workarounds.
 - Reduced memory use of the main object.
 - Split into smaller headers.

[SVN r55878]
2009-08-30 16:42:28 +00:00
4350660626 Remove allocator_constructor since it's never used.
[SVN r55877]
2009-08-30 16:33:42 +00:00
1632522967 Update the reference documentation to mention that emplace is now emulated.
[SVN r55185]
2009-07-26 19:00:40 +00:00
178154082f Some extra changelog notes.
[SVN r55184]
2009-07-26 18:59:33 +00:00
d5dac9bdae Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
cf363355df Try to work around an odd Visual C++ 8 bug.
[SVN r55138]
2009-07-23 22:17:20 +00:00
ca018bfba6 Remove the emulation of single argument C++0x std::pair constructor.
[SVN r55132]
2009-07-23 17:53:59 +00:00
3c48fa3818 Adjust the unordered defaults so that emplace takes more parameters and less buckets are created by default.
[SVN r55100]
2009-07-22 22:38:08 +00:00
7bc588d8df Fix the insert tests when there is a small number of buckets.
[SVN r55099]
2009-07-22 22:37:52 +00:00
6d1aece43a Add constructors to the methods for controlling bucket size in unordered containers.
[SVN r54914]
2009-07-12 18:03:35 +00:00
7e1dbc4cb7 Fix the unordered_map declaration in the tutorial. Fixes #3119.
[SVN r53552]
2009-06-01 19:22:27 +00:00
2b09a34467 Get the type of the initializer_list right.
[SVN r53550]
2009-06-01 19:17:49 +00:00
78ea3024b5 Fix tests for when the library has support for initializer lists but the compiler doesn't.
[SVN r53525]
2009-06-01 06:50:37 +00:00
cec1891586 Disable incorrect Visual C++ 64-bit warnings. Ref #3082.
[SVN r53505]
2009-05-31 15:50:56 +00:00
6d8ce11934 Remove a couple of old uses of BOOST_NO_INITIALIZER_LISTS.
[SVN r53367]
2009-05-28 22:06:42 +00:00
b83a73ab40 Remove an unused function.
[SVN r53318]
2009-05-27 18:32:38 +00:00
caa0b7cdf6 Fix a change accidentally included in the last commit.
[SVN r53317]
2009-05-27 18:32:22 +00:00
46caec7d77 Some workarounds for old versions of Borland.
[SVN r53316]
2009-05-27 18:19:32 +00:00
04234cecee Use lightweight_test for unordered.
[SVN r53314]
2009-05-27 17:44:09 +00:00
84ff0c3227 Remove obsolete comment.
[SVN r53312]
2009-05-27 17:43:22 +00:00
35a3894a88 Missing changelog entry.
[SVN r53311]
2009-05-27 17:42:01 +00:00
bde5df043c Unordered change log for explicit destructors.
[SVN r53256]
2009-05-25 19:45:23 +00:00
8f70ddf4ef Unordered change log.
[SVN r53255]
2009-05-25 19:45:06 +00:00
cfc134b871 Add explicit destructors to the unordered containers. Refs #2908.
Isn't really needed but it doesn't hurt.

[SVN r53253]
2009-05-25 19:14:07 +00:00
20c9360528 Better configuration for boost.unordered.
[SVN r53127]
2009-05-20 06:43:38 +00:00
09b239ed28 Merge emplace support for sandbox - but without move support.
[SVN r52885]
2009-05-10 21:25:09 +00:00
294d58d2fe Cherrypick some unordered container changes from sandbox. Not including
anything which depends on the new move library.

------------------------------------------------------------------------
r52746 | danieljames | 2009-05-03 11:12:30 +0100 (Sun, 03 May 2009) | 1 line

Merge latest unordered container changes.
------------------------------------------------------------------------
r52747 | danieljames | 2009-05-03 11:15:35 +0100 (Sun, 03 May 2009) | 4 lines

Put the C++0x emplace implementations before the non-C++0x versions.

I'm going to change the non-C++0x to be macro heavy emulations of the
C++0x versions, so this will put the readable version first.
------------------------------------------------------------------------
r52748 | danieljames | 2009-05-03 11:15:44 +0100 (Sun, 03 May 2009) | 1 line

Refactor the unordered implementation a tad, to make implementing emplace less painful.
------------------------------------------------------------------------

[SVN r52884]
2009-05-10 21:24:41 +00:00
3e70155100 Use a preprocessor sequence for the primes.
This feels like overkill but it seems to be the most reliable way to ensure
that the length is correct. I obviously can't be trusted to get it right, and
the template hack seems to prevent Boost.Range from working.

[SVN r52711]
2009-05-01 20:50:32 +00:00
ce379f7bb5 Fix the prime number list length in unordered.
[SVN r52674]
2009-04-30 05:10:57 +00:00
f8e1ec8d2b Revert changes to unordered, as the test fails on most compilers.
[SVN r52673]
2009-04-30 05:08:40 +00:00
24091f8bd8 Don't test prime_list::length on Visual C++.
Checking the array size doesn't seem to work on it.

[SVN r52669]
2009-04-29 21:43:41 +00:00
4c3c18467c Fix the length of the prime number list. Refs #2975
[SVN r52658]
2009-04-29 10:05:17 +00:00
3f0e2b478b Add stream output to the count test helper for unordered.
[SVN r52397]
2009-04-14 17:51:34 +00:00
ac2409627a Use emplace instead of insert in the backend as it's more appropriate.
[SVN r52394]
2009-04-14 17:23:51 +00:00
a07e4c5810 Implement full extract_key for compilers without SFINAE and variadic
templates.

[SVN r52393]
2009-04-14 17:23:37 +00:00
5a86d08271 Note change to operator[] in the unordered release notes.
[SVN r52350]
2009-04-12 10:50:57 +00:00
4ac0a12a83 Avoid an unnecessary copy in 'operator[]'
[SVN r52224]
2009-04-06 22:51:36 +00:00
290c7566ff Changelog for unordered and hash.
[SVN r52084]
2009-03-31 19:43:58 +00:00
6ccc68b15c Give up and use another macro to destruct values.
[SVN r51995]
2009-03-26 21:09:51 +00:00
188bcafdec Try to destruct values in a way that all compilers might like.
[SVN r51983]
2009-03-26 07:00:46 +00:00
3a8739cd60 Revert [51409]
It isn't working on Borland.

[SVN r51982]
2009-03-26 07:00:21 +00:00
2bc986ecbc Use paragraphs inside purpose tags.
[SVN r51802]
2009-03-16 20:21:05 +00:00
638accbec4 Update copyright dates in hash and unordered.
[SVN r51667]
2009-03-09 20:56:23 +00:00
d8fb4f4c38 Detab.
[SVN r51644]
2009-03-08 09:44:51 +00:00
3e55934381 Make the sort stable.
Doesn't really matter, but it might as well be.

[SVN r51505]
2009-03-01 14:15:39 +00:00
40a89ac649 Add missing return for operator=.
[SVN r51504]
2009-03-01 14:15:09 +00:00
d442f20bf8 Move some of the data structure classes out of hash table data.
[SVN r51409]
2009-02-22 23:50:20 +00:00
d36fc98c15 Make copy_buckets and move_buckets member functions - so that calling them is a bit simpler.
[SVN r51408]
2009-02-22 23:50:04 +00:00
700c4717d6 Add PDF generation options to fix external links to point to the web site.
Added a few more Boostbook based libs that were missed first time around.
Fixed PDF naming issues.

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

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

[SVN r51104]
2009-02-08 16:59:14 +00:00
77021c5bbb Remove a tab.
[SVN r50452]
2009-01-03 23:26:00 +00:00
fe3873b28f Add support for initializer lists to config and the unordered containers.
[SVN r50118]
2008-12-04 21:30:19 +00:00
c1e9a6ac59 Workaround another in-place destruction.
[SVN r50029]
2008-11-29 21:47:55 +00:00
c2425106ea Wild stab at getting destruction working on more compilers.
[SVN r49955]
2008-11-27 11:42:13 +00:00
c8e7874534 Use aligned storage for the value.
[SVN r49927]
2008-11-24 23:15:55 +00:00
601daa0e5d Use a larger prime number list. Fixes #1710
[SVN r49926]
2008-11-24 22:56:04 +00:00
d022cc48ad Document operator==/operator!= as undefined if the equality predicates aren't equivalent. Fixes #2237.
[SVN r49925]
2008-11-24 22:55:47 +00:00
527a72860d Extra tests for equality with different hash functions.
[SVN r49924]
2008-11-24 22:55:14 +00:00
f0bb74a530 Use the new swap library.
[SVN r49770]
2008-11-15 13:07:29 +00:00
b75f06d935 Use pragmas to suppress a Visual C++ warning.
[SVN r49756]
2008-11-14 16:11:16 +00:00
e2d1d75955 Explicitly specify the template parameters in the unordered container friend, in order to avoid some warnings.
[SVN r49735]
2008-11-14 12:51:00 +00:00
80dc7b5e6a Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
1f4d8e7c21 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
366c09f199 Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
d98f72c4e1 Change includes of <cmath> to <boost/config/no_tr1/config.hpp>.
Previously if Boost.TR1 was in the include path then including <cmath> pulls in all the new TR1 math functions, which in turn also requires linking to an external library.  With auto-linking support this requires that library to have been built and be present in the library search path, even if the actual library under use is header only.

Fixes #2392.


[SVN r49254]
2008-10-10 16:10:00 +00:00
e6417fe652 Update unordered changelog.
[SVN r48853]
2008-09-18 11:23:12 +00:00
f5d52cc9b2 Move the unordered headers into the unordered directory.
[SVN r48803]
2008-09-16 21:49:41 +00:00
62427c8287 Forward headers for the unordered containers.
[SVN r48802]
2008-09-16 21:45:53 +00:00
ab588fe872 Fix a workaround macro.
[SVN r48791]
2008-09-15 21:48:46 +00:00
fe1385ab34 More recent version of the working draft.
[SVN r48082]
2008-08-11 07:53:05 +00:00
d6f513be52 Rename 'emplace' with hint to 'emplace_hint'.
[SVN r48081]
2008-08-11 07:52:37 +00:00
d8fa4cef60 Fix a link and a header.
[SVN r47881]
2008-07-30 09:44:26 +00:00
506f478ec7 Fix a typo.
[SVN r47813]
2008-07-25 21:25:58 +00:00
f2c420e289 Remove some old information that's no longer true.
[SVN r47750]
2008-07-24 10:14:15 +00:00
eae2a90463 Remove a mention of the hash functions which I missed before.
[SVN r47522]
2008-07-17 23:08:32 +00:00
4305d10264 On second thoughts, I'll just completely remove hash_value for ordered
containers. It's low quality and not very generic (it uses boost::hash for
mapped values). Should be a painless change.


[SVN r47465]
2008-07-15 22:03:15 +00:00
d5b38b01fc Better hash function for unordered containers. Still a bit rubbish.
[SVN r47463]
2008-07-15 21:26:54 +00:00
c49dbd782d Update the implementation details.
[SVN r47403]
2008-07-13 20:07:45 +00:00
c7bde21be7 Note that emplace is only available on a few compilers.
[SVN r47402]
2008-07-13 19:42:56 +00:00
d5fdc0b47e Update the docs for the new location of FNV-1.
[SVN r47146]
2008-07-06 21:29:47 +00:00
c3d97bd613 I've only got one hash function for release, so no need for its own directory.
[SVN r47144]
2008-07-06 21:07:31 +00:00
2960390f79 Clean up the FNV-1 comments.
[SVN r47143]
2008-07-06 21:06:52 +00:00
f723f857e4 'Bias' should be 'basis'.
[SVN r47132]
2008-07-06 12:41:09 +00:00
d66936a640 Require explicit conversion from allocators.
(Not what it says in the draft standard, but I think that might be a defect).


[SVN r47085]
2008-07-04 22:57:20 +00:00
3640e1e96c Workaround for some template syntax not supported in old versions of Visual C++ 6.5
[SVN r47040]
2008-07-03 14:34:56 +00:00
ec1e809fc3 Extract the hash and equality functions from hash_table_data_*.
As these are extensions and add extra requirements to the container elements,
they shouldn't be part of hash_table_data_* so that they won't get instantiated
if an unordered container is explicitly instantiated.

Merged revisions 46594-46604 via svnmerge from 
https://svn.boost.org/svn/boost/branches/unordered/trunk


[SVN r46607]
2008-06-22 13:54:45 +00:00
8868fa4687 Merge inspect fixes for the unordered library.
Merged revisions 46470-46592 via svnmerge from 
https://svn.boost.org/svn/boost/branches/unordered/trunk

................
  r46589 | danieljames | 2008-06-21 21:37:42 +0100 (Sat, 21 Jun 2008) | 2 lines
  
  Fix some inspect errors (tabs and missing copyright/license).
................
  r46591 | danieljames | 2008-06-21 21:47:51 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Move memory.hpp into the helpers subdirectory.
................
  r46592 | danieljames | 2008-06-21 22:08:53 +0100 (Sat, 21 Jun 2008) | 1 line
  
  Prevent inspect errors for unnamed namespaces in some of the test header files.
................


[SVN r46594]
2008-06-21 22:02:15 +00:00
ebd75b4010 Get the test to pass when pair's default constructor creates two instances of
the member classes.

With some standard libraries I was getting two copies of the object after
creating a default pair, probably because it was creating an instance for its
default parameter. So only test after creating the pair object - since it isn't
our concern how many instances that creates.


[SVN r46587]
2008-06-21 19:58:39 +00:00
9bd3f498a7 Define unordered containers' friend functions outside of the class.
On some compilers, friend functions are being instantiated when the main class
is explicitly instantiated. This is slightly problematic because the equality
functions (which are an extension) put extra requirements on the types used. So
I'm going to try defining the functions outside of the class, in the hope that
they won't get instantiated. If someone wants non-member functions to be
instantiated, I think it's reasonable to expect them to explicitly instantiate
them, especially as compilers don't seem to be consistent about this.


[SVN r46579]
2008-06-21 15:32:11 +00:00
659a014976 Fix in an error in the unordered containers' emulated move constructors. These
aren't actually used, so I could probalby just remove 'move_from' for now (it's
used in the full move library).


[SVN r46410]
2008-06-15 17:03:37 +00:00
885574e1bf Fix typo. Thanks to Thorsten.
Merged revisions 46112 via svnmerge from 
https://svn.boost.org/svn/boost/branches/unordered/trunk

........
  r46112 | danieljames | 2008-06-04 13:34:29 +0100 (Wed, 04 Jun 2008) | 1 line
  
  Fix copy and paste error in the max_load_factor documentation.
........


[SVN r46340]
2008-06-11 22:06:52 +00:00
209 changed files with 35775 additions and 21344 deletions

114
.appveyor.yml Normal file
View File

@ -0,0 +1,114 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2017 - 2019 James E. King III
# Copyright 2019 - 2021 Alexander Grund
# 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
- /bugfix\/.*/
- /feature\/.*/
- /fix\/.*/
- /pr\/.*/
matrix:
fast_finish: false
# Adding MAYFAIL to any matrix job allows it to fail but the build stays green:
allow_failures:
- MAYFAIL: true
environment:
global:
B2_CI_VERSION: 1
GIT_FETCH_JOBS: 4
B2_ADDRESS_MODEL: 32,64
B2_VARIANT: debug,release
matrix:
- FLAVOR: Visual Studio 2008, 2010, 2012
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0
B2_ADDRESS_MODEL: 32 # No 64bit support
- FLAVOR: Visual Studio 2013, 2015
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
B2_TOOLSET: msvc-12.0,msvc-14.0
- FLAVOR: Visual Studio 2017
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXSTD: 14,17,latest
B2_TOOLSET: msvc-14.1
- FLAVOR: cygwin (32-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin\bin;
B2_ADDRESS_MODEL: 32
B2_CXXSTD: 03,11,14,1z
B2_TOOLSET: gcc
- FLAVOR: cygwin (64-bit)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 03,11,14,1z
B2_TOOLSET: gcc
- FLAVOR: cygwin (64-bit, latest)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 03,11
B2_TOOLSET: gcc
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
- FLAVOR: cygwin (64-bit, latest)
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 14,1z
B2_TOOLSET: gcc
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
- FLAVOR: mingw-w64, 32 bit
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
B2_CXXSTD: 03,11,14,17,2a
B2_TOOLSET: gcc
B2_ADDRESS_MODEL: 32
- FLAVOR: mingw-w64, 64 bit
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
B2_CXXSTD: 03,11,14,17,2a
B2_TOOLSET: gcc
B2_ADDRESS_MODEL: 64
#- FLAVOR: CodeCov (VS 2019)
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
# B2_CXXFLAGS: -permissive-
# B2_CXXSTD: 14
# B2_TOOLSET: msvc-14.2
# COVERAGE: true
install:
- git clone --depth 1 https://github.com/boostorg/boost-ci.git C:\boost-ci-cloned
# Copy ci folder if not testing Boost.CI
- if NOT "%APPVEYOR_PROJECT_NAME%" == "boost-ci" xcopy /s /e /q /i /y C:\boost-ci-cloned\ci .\ci
- rmdir /s /q C:\boost-ci-cloned
- ci\appveyor\install.bat
build: off
test_script: ci\build.bat
for:
# CodeCov coverage build
- matrix:
only: [COVERAGE: true]
test_script: [ps: ci\codecov.ps1]

23
.codecov.yml Normal file
View File

@ -0,0 +1,23 @@
# Copyright 2019 - 2021 Alexander Grund
# 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)
#
# Sample codecov configuration file. Edit as required
codecov:
max_report_age: off
require_ci_to_pass: yes
notify:
# Increase this if you have multiple coverage collection jobs
after_n_builds: 1
wait_for_ci: yes
# Change how pull request comments look
comment:
layout: "reach,diff,flags,files,footer"
# Ignore specific files or folders. Glob patterns are supported.
# See https://docs.codecov.com/docs/ignoring-paths
ignore:
- extra/**/*
# - test/**/*

180
.drone.jsonnet Normal file
View File

@ -0,0 +1,180 @@
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
local library = "unordered";
local triggers =
{
branch: [ "master", "develop", "feature/*", "bugfix/*" ]
};
local ubsan = { UBSAN: '1', UBSAN_OPTIONS: 'print_stacktrace=1' };
local asan = { ASAN: '1' };
local linux_pipeline(name, image, environment, packages = "", sources = [], arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "linux",
arch: arch
},
steps:
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'set -e',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
(if packages != "" then [ 'apt-get update', 'apt-get -y install ' + packages ] else []) +
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "catalina", arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "exec",
trigger: triggers,
platform: {
"os": "darwin",
"arch": arch
},
node: {
"os": osx_version
},
steps: [
{
name: "everything",
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
}
]
};
local windows_pipeline(name, image, environment, arch = "amd64") =
{
name: name,
kind: "pipeline",
type: "docker",
trigger: triggers,
platform:
{
os: "windows",
arch: arch
},
"steps":
[
{
name: "everything",
image: image,
environment: environment,
commands:
[
'cmd /C .drone\\\\drone.bat ' + library,
]
}
]
};
[
linux_pipeline(
"Linux 14.04 GCC 4.4 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.4', CXXSTD: '98,0x', ADDRMD: '32,64' },
"g++-4.4-multilib",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.6 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.6', CXXSTD: '98,0x', ADDRMD: '32,64' },
"g++-4.6-multilib",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.7 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.7', CXXSTD: '98,0x', ADDRMD: '32,64' },
"g++-4.7-multilib",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 14.04 GCC 4.8* 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11', ADDRMD: '32,64' },
),
linux_pipeline(
"Linux 14.04 GCC 4.9 32/64",
"cppalliance/droneubuntu1404:1",
{ TOOLSET: 'gcc', COMPILER: 'g++-4.9', CXXSTD: '03,11', ADDRMD: '32,64' },
"g++-4.9-multilib",
[ "ppa:ubuntu-toolchain-r/test" ],
),
linux_pipeline(
"Linux 20.04 GCC 9* ARM64 32",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 9* ARM64 64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '64' },
arch="arm64",
),
linux_pipeline(
"Linux 20.04 GCC 9* S390x 32",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '32' },
arch="s390x",
),
linux_pipeline(
"Linux 20.04 GCC 9* S390x 64",
"cppalliance/droneubuntu2004:multiarch",
{ TOOLSET: 'gcc', COMPILER: 'g++', CXXSTD: '03,11,14,17,2a', ADDRMD: '64' },
arch="s390x",
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 UBSAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
),
macos_pipeline(
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
),
windows_pipeline(
"Windows VS2017 msvc-14.1",
"cppalliance/dronevs2017",
{ TOOLSET: 'msvc-14.1', CXXSTD: '14,17,latest' },
),
]

23
.drone/drone.bat Normal file
View File

@ -0,0 +1,23 @@
@REM Copyright 2022 Peter Dimov
@REM Distributed under the Boost Software License, Version 1.0.
@REM https://www.boost.org/LICENSE_1_0.txt
@ECHO ON
set LIBRARY=%1
set DRONE_BUILD_DIR=%CD%
set BOOST_BRANCH=develop
if "%DRONE_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 %DRONE_BUILD_DIR% libs\%LIBRARY%\
python tools/boostdep/depinst/depinst.py %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
b2 -j3 libs/%LIBRARY%/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release embed-manifest-via=linker

24
.drone/drone.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/bash
# Copyright 2022 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
set -ex
DRONE_BUILD_DIR=$(pwd)
BOOST_BRANCH=develop
if [ "$DRONE_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi
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
cp -r $DRONE_BUILD_DIR/* libs/$LIBRARY
python tools/boostdep/depinst/depinst.py $LIBRARY
./bootstrap.sh
./b2 -d0 headers
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
./b2 -j3 libs/$LIBRARY/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${ADDRMD:+address-model=$ADDRMD} ${UBSAN:+undefined-sanitizer=norecover debug-symbols=on} ${ASAN:+address-sanitizer=norecover debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS}

7
.editorconfig Normal file
View File

@ -0,0 +1,7 @@
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
[*.?pp]
indent_size = 2

397
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,397 @@
# Copyright 2020-2021 Peter Dimov
# Copyright 2021 Andrey Semashev
# Copyright 2021 Alexander Grund
# Copyright 2022 James E. King III
#
# 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)
---
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- bugfix/**
- feature/**
- fix/**
- pr/**
concurrency:
group: ${{format('{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
env:
GIT_FETCH_JOBS: 8
NET_RETRY_COUNT: 5
B2_CI_VERSION: 1
B2_VARIANT: debug,release
LCOV_BRANCH_COVERAGE: 0
CODECOV_NAME: Github Actions
jobs:
posix:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
# Linux, gcc
- { compiler: gcc-4.8, cxxstd: '03,11', os: ubuntu-18.04, install: 'g++-4.8-multilib', address-model: '32,64' }
- { compiler: gcc-4.9, cxxstd: '03,11', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: gcc-5, cxxstd: '03,11,14,1z', os: ubuntu-18.04, install: 'g++-5-multilib', address-model: '32,64' }
- { compiler: gcc-6, cxxstd: '03,11,14,17', os: ubuntu-18.04, install: 'g++-6-multilib', address-model: '32,64' }
- { compiler: gcc-7, cxxstd: '03,11,14,17', os: ubuntu-18.04, install: 'g++-7-multilib', address-model: '32,64' }
- { compiler: gcc-8, cxxstd: '03,11,14,17,2a', os: ubuntu-18.04, install: 'g++-8-multilib', address-model: '32,64' }
- { compiler: gcc-9, cxxstd: '03,11,14,17,2a', os: ubuntu-18.04, install: 'g++-9-multilib', address-model: '32,64' }
- { compiler: gcc-10, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, install: 'g++-10-multilib', address-model: '32,64' }
- { compiler: gcc-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, install: 'g++-11-multilib', address-model: '32,64' }
- { compiler: gcc-12, cxxstd: '03,11,14,17,20', os: ubuntu-22.04, install: 'g++-12-multilib', address-model: '32,64' }
- { name: GCC w/ sanitizers, sanitize: yes,
compiler: gcc-12, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 }
- { name: Collect coverage, coverage: yes,
compiler: gcc-8, cxxstd: '03,11', os: ubuntu-20.04, install: 'g++-8-multilib', address-model: '32,64' }
# Linux, clang
- { compiler: clang-3.7, cxxstd: '03,11,14', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.8, cxxstd: '03,11,14', os: ubuntu-20.04, container: 'ubuntu:16.04' }
- { compiler: clang-3.9, cxxstd: '03,11,14', os: ubuntu-18.04 }
- { compiler: clang-4.0, cxxstd: '03,11,14', os: ubuntu-18.04 }
- { compiler: clang-5.0, cxxstd: '03,11,14,1z', os: ubuntu-18.04 }
- { compiler: clang-6.0, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: clang-7, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: clang-8, cxxstd: '03,11,14,17', os: ubuntu-18.04 }
- { compiler: clang-9, cxxstd: '03,11,14,17,2a', os: ubuntu-20.04 }
- { compiler: clang-10, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-11, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04 }
- { compiler: clang-13, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 }
- { compiler: clang-14, cxxstd: '03,11,14,17,20', os: ubuntu-22.04 }
# libc++
- { compiler: clang-6.0, cxxstd: '03,11,14', os: ubuntu-18.04, stdlib: libc++, install: 'clang-6.0 libc++-dev libc++abi-dev' }
- { compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev' }
- { name: Clang w/ sanitizers, sanitize: yes,
compiler: clang-12, cxxstd: '03,11,14,17,20', os: ubuntu-20.04, stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev' }
# OSX, clang
- { compiler: clang, cxxstd: '03,11,14,17,2a', os: macos-11, sanitize: yes }
timeout-minutes: 120
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
env: {B2_USE_CCACHE: 1}
steps:
- name: Setup environment
run: |
if [ -f "/etc/debian_version" ]; then
echo "DEBIAN_FRONTEND=noninteractive" >> $GITHUB_ENV
export DEBIAN_FRONTEND=noninteractive
fi
if [ -n "${{matrix.container}}" ] && [ -f "/etc/debian_version" ]; then
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y sudo software-properties-common
# Need (newer) git, and the older Ubuntu container may require requesting the key manually using port 80
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E1DD270288B4E6030699E45FA1715D88E1DF1F24
for i in {1..${NET_RETRY_COUNT:-3}}; do sudo -E add-apt-repository -y ppa:git-core/ppa && break || sleep 10; done
apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y g++ python libpython-dev git
fi
# For jobs not compatible with ccache, use "ccache: no" in the matrix
if [[ "${{ matrix.ccache }}" == "no" ]]; then
echo "B2_USE_CCACHE=0" >> $GITHUB_ENV
fi
git config --global pack.threads 0
- uses: actions/checkout@v3
with:
# For coverage builds fetch the whole history, else only 1 commit using a 'fake ternary'
fetch-depth: ${{ matrix.coverage && '0' || '1' }}
- name: Cache ccache
uses: actions/cache@v3
if: env.B2_USE_CCACHE
with:
path: ~/.ccache
key: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-${{github.sha}}
restore-keys: ${{matrix.os}}-${{matrix.container}}-${{matrix.compiler}}-
- name: Fetch Boost.CI
uses: actions/checkout@v3
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Install packages
if: startsWith(matrix.os, 'ubuntu')
run: |
SOURCE_KEYS=(${{join(matrix.source_keys, ' ')}})
SOURCES=(${{join(matrix.sources, ' ')}})
# Add this by default
SOURCES+=(ppa:ubuntu-toolchain-r/test)
for key in "${SOURCE_KEYS[@]}"; do
for i in {1..$NET_RETRY_COUNT}; do
wget -O - "$key" | sudo apt-key add - && break || sleep 10
done
done
for source in "${SOURCES[@]}"; do
for i in {1..$NET_RETRY_COUNT}; do
sudo add-apt-repository $source && break || sleep 10
done
done
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT update
if [[ -z "${{matrix.install}}" ]]; then
pkgs="${{matrix.compiler}}"
pkgs="${pkgs/gcc-/g++-}"
else
pkgs="${{matrix.install}}"
fi
sudo apt-get -o Acquire::Retries=$NET_RETRY_COUNT install -y $pkgs
- name: Setup GCC Toolchain
if: matrix.gcc_toolchain
run: |
GCC_TOOLCHAIN_ROOT="$HOME/gcc-toolchain"
echo "GCC_TOOLCHAIN_ROOT=$GCC_TOOLCHAIN_ROOT" >> $GITHUB_ENV
MULTIARCH_TRIPLET="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
mkdir -p "$GCC_TOOLCHAIN_ROOT"
ln -s /usr/include "$GCC_TOOLCHAIN_ROOT/include"
ln -s /usr/bin "$GCC_TOOLCHAIN_ROOT/bin"
mkdir -p "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET"
ln -s "/usr/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}" "$GCC_TOOLCHAIN_ROOT/lib/gcc/$MULTIARCH_TRIPLET/${{matrix.gcc_toolchain}}"
- name: Setup multiarch
if: matrix.multiarch
run: |
sudo apt-get install --no-install-recommends -y binfmt-support qemu-user-static
sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
git clone https://github.com/jeking3/bdde.git
echo "$(pwd)/bdde/bin/linux" >> ${GITHUB_PATH}
echo "BDDE_DISTRO=${{ matrix.distro }}" >> ${GITHUB_ENV}
echo "BDDE_EDITION=${{ matrix.edition }}" >> ${GITHUB_ENV}
echo "BDDE_ARCH=${{ matrix.arch }}" >> ${GITHUB_ENV}
echo "B2_WRAPPER=bdde" >> ${GITHUB_ENV}
- name: Setup Boost
env:
B2_ADDRESS_MODEL: ${{matrix.address-model}}
B2_COMPILER: ${{matrix.compiler}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_SANITIZE: ${{matrix.sanitize}}
B2_STDLIB: ${{matrix.stdlib}}
# More entries can be added in the same way, see the B2_ARGS assignment in ci/enforce.sh for the possible keys.
# B2_DEFINES: ${{matrix.defines}}
# Variables set here (to non-empty) will override the top-level environment variables, e.g.
# B2_VARIANT: ${{matrix.variant}}
run: source ci/github/install.sh
- name: Setup coverage collection
if: matrix.coverage
run: ci/github/codecov.sh "setup"
- name: Run tests
if: '!matrix.coverity'
run: ci/build.sh
- name: Upload coverage
if: matrix.coverage
run: ci/codecov.sh "upload"
- name: Run coverity
if: matrix.coverity && github.event_name == 'push' && (github.ref_name == 'develop' || github.ref_name == 'master')
run: ci/github/coverity.sh
env:
COVERITY_SCAN_NOTIFICATION_EMAIL: ${{ secrets.COVERITY_SCAN_NOTIFICATION_EMAIL }}
COVERITY_SCAN_TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
windows:
defaults:
run:
shell: cmd
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@v3
- name: Fetch Boost.CI
uses: actions/checkout@v3
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
REM Copy ci folder if not testing Boost.CI
if "%GITHUB_REPOSITORY%" == "%GITHUB_REPOSITORY:boost-ci=%" xcopy /s /e /q /i /y boost-ci-cloned\ci .\ci
rmdir /s /q boost-ci-cloned
- name: Setup Boost
run: ci\github\install.bat
- name: Run tests
if: '!matrix.coverage'
run: ci\build.bat
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
- name: Collect coverage
shell: powershell
if: matrix.coverage
run: ci\opencppcoverage.ps1
env:
B2_TOOLSET: ${{matrix.toolset}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_ADDRESS_MODEL: ${{matrix.addrmd}}
- name: Upload coverage
if: matrix.coverage
uses: codecov/codecov-action@v2
with:
files: __out/cobertura.xml
MSYS2:
defaults:
run:
shell: msys2 {0}
strategy:
fail-fast: false
matrix:
include:
- { sys: MINGW32, compiler: gcc, cxxstd: '03,11,17,20' }
- { sys: MINGW64, compiler: gcc, cxxstd: '03,11,17,20' }
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Setup MSYS2 environment
uses: msys2/setup-msys2@v2
with:
msystem: ${{matrix.sys}}
update: true
install: git python
pacboy: gcc:p cmake:p ninja:p
- name: Fetch Boost.CI
uses: actions/checkout@v3
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env:
B2_COMPILER: ${{matrix.compiler}}
B2_CXXSTD: ${{matrix.cxxstd}}
B2_SANITIZE: ${{matrix.sanitize}}
B2_STDLIB: ${{matrix.stdlib}}
run: ci/github/install.sh
- name: Run tests
run: ci/build.sh
# Run also the CMake tests to avoid having to setup another matrix for CMake on MSYS
- name: Run CMake tests
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=ON -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --target tests --config Debug -j$B2_JOBS
ctest --output-on-failure --build-config Debug
CMake:
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-20.04, build_shared: ON, build_type: Debug, generator: 'Unix Makefiles' }
- { os: windows-2019, build_shared: ON, build_type: Debug, generator: 'Visual Studio 16 2019' }
timeout-minutes: 120
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Fetch Boost.CI
uses: actions/checkout@v3
with:
repository: boostorg/boost-ci
ref: master
path: boost-ci-cloned
- name: Get CI scripts folder
run: |
# Copy ci folder if not testing Boost.CI
[[ "$GITHUB_REPOSITORY" =~ "boost-ci" ]] || cp -r boost-ci-cloned/ci .
rm -rf boost-ci-cloned
- name: Setup Boost
env: {B2_DONT_BOOTSTRAP: 1}
run: source ci/github/install.sh
- name: Run CMake tests
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_test__ && cd __build_cmake_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DBUILD_TESTING=ON -DBoost_VERBOSE=ON ..
cmake --build . --target tests --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Run CMake subdir tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_subdir_test"
cd "$cmake_test_folder"
mkdir __build_cmake_subdir_test__ && cd __build_cmake_subdir_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=OFF -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} ..
cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}
- name: Install Library
run: |
cd "$BOOST_ROOT"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBOOST_INCLUDE_LIBRARIES=$SELF -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_INSTALL_PREFIX=~/.local -DBoost_VERBOSE=ON -DBoost_DEBUG=ON ..
cmake --build . --target install --config ${{matrix.build_type}} -j$B2_JOBS
- name: Run CMake install tests
run: |
cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_test" # New unified folder
[ -d "$cmake_test_folder" ] || cmake_test_folder="$BOOST_ROOT/libs/$SELF/test/cmake_install_test"
cd "$cmake_test_folder"
mkdir __build_cmake_install_test__ && cd __build_cmake_install_test__
cmake -G "${{matrix.generator}}" -DBOOST_CI_INSTALL_TEST=ON -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.build_shared}} -DCMAKE_PREFIX_PATH=~/.local ..
cmake --build . --config ${{matrix.build_type}} -j$B2_JOBS
ctest --output-on-failure --build-config ${{matrix.build_type}}

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/doc/html/

87
.travis.yml Normal file
View File

@ -0,0 +1,87 @@
# Copyright (C) 2016 Daniel James.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Use Trusty to get a reasonably recent version of Boost.
sudo: required
dist: trusty
language: c++
addons:
apt:
packages:
- libxml2-utils
- g++-multilib
matrix:
include:
- compiler: gcc
env: |
label="gcc C++03/11";
user_config="using gcc : : g++-4.8 --coverage -fsanitize=address ;"
enable_coverage=1
CXXSTD=03,11
- compiler: gcc
env: |
label="gcc 32 bit C++11";
user_config="using gcc : : g++-4.8 -m32 -fsanitize=address ;"
CXXSTD=11
- compiler: clang
env: |
label="clang C++11/17";
user_config="using clang : : clang++ -fsanitize=address ;"
CXXSTD=11,17
# sanitized=address not available for 32-bit clang on travis.
- compiler: clang
env: |
label="clang 32 bit";
user_config="using clang : : clang++ -m32 ;"
CXXSTD=03
before_install:
- if [ -n $enable_coverage ]; then pip install --user cpp-coveralls; fi
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
- |
# Pick snapshot to use
if [ "$TRAVIS_EVENT_TYPE" == "cron" ]
then
if [ "$TRAVIS_BRANCH" == "master" ]
then
snapshot=master
else
snapshot=develop
fi
else
#snapshot=stable
snapshot=master
fi
# Download and extract snapshot
echo "Downloading ${download_url}"
mkdir $HOME/download
cd $HOME/download
python ${TRAVIS_BUILD_DIR}/ci/download-boost-snapshot.py $snapshot
mv * ${BOOST_ROOT}
- rm -r ${BOOST_ROOT}/boost/unordered
- cd ${BOOST_ROOT}/tools/build
- mkdir ${HOME}/opt
- bash bootstrap.sh
- ./b2 install --prefix=$HOME/opt
after_success:
if [ -n $enable_coverage ]; then coveralls -r ${TRAVIS_BUILD_DIR} -b ${TRAVIS_BUILD_DIR}/test --gcov-options '\-lp' --include include/boost/unordered/ ; fi
script:
- cd ${TRAVIS_BUILD_DIR}/test
- ${HOME}/opt/bin/b2 -j 3 cxxstd=$CXXSTD -q include=${BOOST_ROOT} include=${TRAVIS_BUILD_DIR}/include
- xmllint --noout ${TRAVIS_BUILD_DIR}/doc/ref.xml

61
CMakeLists.txt Normal file
View File

@ -0,0 +1,61 @@
# Generated by `boostdep --cmake unordered`
# Copyright 2020, 2021 Peter Dimov
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
if(NOT DEFINED IDF_TARGET)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_unordered VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_unordered INTERFACE)
add_library(Boost::unordered ALIAS boost_unordered)
target_include_directories(boost_unordered INTERFACE include)
target_link_libraries(boost_unordered
INTERFACE
Boost::assert
Boost::config
Boost::container_hash
Boost::core
Boost::move
Boost::mp11
Boost::predef
Boost::preprocessor
Boost::throw_exception
Boost::tuple
Boost::type_traits
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
else()
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
idf_component_register(
SRCS
${headers}
INCLUDE_DIRS
include
REQUIRES
boost_assert
boost_config
boost_container_hash
boost_core
boost_move
boost_mp11
boost_predef
boost_preprocessor
boost_throw_exception
boost_tuple
boost_type_traits
)
endif()

23
LICENSE Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

49
README.md Normal file
View File

@ -0,0 +1,49 @@
# Boost.Unordered
Part of collection of the [Boost C++ Libraries](http://github.com/boostorg).
For accessing data based on key lookup, the C++ standard library offers `std::set`, `std::map`, `std::multiset` and `std::multimap`.
These are generally implemented using balanced binary trees so that lookup time has logarithmic complexity.
That is generally okay, but in many cases a hash table can perform better, as accessing data has constant complexity, on average.
The worst case complexity is linear, but that occurs rarely and with some care, can be avoided.
Also, the existing containers require a 'less than' comparison object to order their elements.
For some data types this is impossible to implement or isnt practical.
In contrast, a hash table only needs an equality function and a hash function for the key.
With this in mind, unordered associative containers were added to the C++ standard.
This is an implementation of the containers described in C++11, with some deviations from the standard in order to work with non-C++11 compilers and libraries.
### License
Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
### Properties
* C++03
* Header-Only
### Build Status
Branch | GH Actions | Appveyor | codecov.io | Deps | Docs | Tests |
:-------------: | ---------- | -------- | ---------- | ---- | ---- | ----- |
[`master`](https://github.com/boostorg/unordered/tree/master) | [![CI](https://github.com/boostorg/unordered/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/boostorg/unordered/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/unordered?branch=master&svg=true)](https://ci.appveyor.com/project/danieljames/unordered-qtwe6/branch/master) | [![codecov](https://codecov.io/gh/boostorg/unordered/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/unordered/branch/master) | [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/unordered.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](https://www.boost.org/doc/libs/master/libs/unordered/doc/html/unordered.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/unordered.html)
[`develop`](https://github.com/boostorg/unordered/tree/develop) | [![CI](https://github.com/boostorg/unordered/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/boostorg/unordered/actions/workflows/ci.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/github/boostorg/unordered?branch=develop&svg=true)](https://ci.appveyor.com/project/danieljames/unordered-qtwe6/branch/develop) | [![codecov](https://codecov.io/gh/boostorg/unordered/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/unordered/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/unordered.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](https://www.boost.org/doc/libs/develop/libs/unordered/doc/html/unordered.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/unordered.html)
### Directories
| Name | Purpose |
| ----------- | ------------------------------ |
| `doc` | documentation |
| `example` | examples |
| `include` | headers |
| `test` | unit tests |
### More information
* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-unordered)
* [Report bugs](https://github.com/boostorg/unordered/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[unordered]` tag at the beginning of the subject line.

38
_clang-format Normal file
View File

@ -0,0 +1,38 @@
# 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)
# Using clang format 4.0
# http://llvm.org/releases/4.0.0/tools/clang/docs/ClangFormatStyleOptions.html
# Becuase you have to start somewhere.
BasedOnStyle: LLVM
# Basic settings
ColumnLimit: 80
NamespaceIndentation: All
ContinuationIndentWidth: 2
IndentWidth: 2
UseTab: Never
Language: Cpp
Standard: Cpp03
# Code layout
AlignAfterOpenBracket: DontAlign
AlignTrailingComments: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterNamespace: false
AfterClass: true
AfterStruct: true
AfterUnion: true
AfterEnum: true
AfterFunction: true
AfterControlStatement: false
BeforeCatch: false
BeforeElse: false
PointerAlignment: Left
# Boost specific stuff
ForEachMacros: [ BOOST_FOREACH, UNORDERED_AUTO_TEST ]

488
benchmark/string.cpp Normal file
View File

@ -0,0 +1,488 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#include <boost/unordered_map.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/config.hpp>
#ifdef HAVE_ABSEIL
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std::chrono_literals;
static void print_time( std::chrono::steady_clock::time_point & t1, char const* label, std::uint32_t s, std::size_t size )
{
auto t2 = std::chrono::steady_clock::now();
std::cout << label << ": " << ( t2 - t1 ) / 1ms << " ms (s=" << s << ", size=" << size << ")\n";
t1 = t2;
}
constexpr unsigned N = 2'000'000;
constexpr int K = 10;
static std::vector<std::string> indices1, indices2;
static std::string make_index( unsigned x )
{
char buffer[ 64 ];
std::snprintf( buffer, sizeof(buffer), "pfx_%u_sfx", x );
return buffer;
}
static std::string make_random_index( unsigned x )
{
char buffer[ 64 ];
std::snprintf( buffer, sizeof(buffer), "pfx_%0*d_%u_sfx", x % 8 + 1, 0, x );
return buffer;
}
static void init_indices()
{
indices1.reserve( N*2+1 );
indices1.push_back( make_index( 0 ) );
for( unsigned i = 1; i <= N*2; ++i )
{
indices1.push_back( make_index( i ) );
}
indices2.reserve( N*2+1 );
indices2.push_back( make_index( 0 ) );
{
boost::detail::splitmix64 rng;
for( unsigned i = 1; i <= N*2; ++i )
{
indices2.push_back( make_random_index( static_cast<std::uint32_t>( rng() ) ) );
}
}
}
template<class Map> BOOST_NOINLINE void test_insert( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices1[ i ], i } );
}
print_time( t1, "Consecutive insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices2[ i ], i } );
}
print_time( t1, "Random insert", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_lookup( Map& map, std::chrono::steady_clock::time_point & t1 )
{
std::uint32_t s;
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices1[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices2[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Random lookup", s, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_iteration( Map& map, std::chrono::steady_clock::time_point & t1 )
{
auto it = map.begin();
while( it != map.end() )
{
if( it->second & 1 )
{
if constexpr( std::is_void_v< decltype( map.erase( it ) ) > )
{
map.erase( it++ );
}
else
{
it = map.erase( it );
}
}
else
{
++it;
}
}
print_time( t1, "Iterate and erase odd elements", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_erase( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices1[ i ] );
}
print_time( t1, "Consecutive erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices2[ i ] );
}
print_time( t1, "Random erase", 0, map.size() );
std::cout << std::endl;
}
// counting allocator
static std::size_t s_alloc_bytes = 0;
static std::size_t s_alloc_count = 0;
template<class T> struct allocator
{
using value_type = T;
allocator() = default;
template<class U> allocator( allocator<U> const & ) noexcept
{
}
template<class U> bool operator==( allocator<U> const & ) const noexcept
{
return true;
}
template<class U> bool operator!=( allocator<U> const& ) const noexcept
{
return false;
}
T* allocate( std::size_t n ) const
{
s_alloc_bytes += n * sizeof(T);
s_alloc_count++;
return std::allocator<T>().allocate( n );
}
void deallocate( T* p, std::size_t n ) const noexcept
{
s_alloc_bytes -= n * sizeof(T);
s_alloc_count--;
std::allocator<T>().deallocate( p, n );
}
};
//
struct record
{
std::string label_;
long long time_;
std::size_t bytes_;
std::size_t count_;
};
static std::vector<record> times;
template<template<class...> class Map> BOOST_NOINLINE void test( char const* label )
{
std::cout << label << ":\n\n";
s_alloc_bytes = 0;
s_alloc_count = 0;
Map<std::string, std::uint32_t> map;
auto t0 = std::chrono::steady_clock::now();
auto t1 = t0;
test_insert( map, t1 );
std::cout << "Memory: " << s_alloc_bytes << " bytes in " << s_alloc_count << " allocations\n\n";
record rec = { label, 0, s_alloc_bytes, s_alloc_count };
test_lookup( map, t1 );
test_iteration( map, t1 );
test_lookup( map, t1 );
test_erase( map, t1 );
auto tN = std::chrono::steady_clock::now();
std::cout << "Total: " << ( tN - t0 ) / 1ms << " ms\n\n";
rec.time_ = ( tN - t0 ) / 1ms;
times.push_back( rec );
}
// multi_index emulation of unordered_map
template<class K, class V> struct pair
{
K first;
mutable V second;
};
using namespace boost::multi_index;
template<class K, class V> using multi_index_map = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first> >
>,
::allocator< pair<K, V> >
>;
// aliases using the counting allocator
template<class K, class V> using allocator_for = ::allocator< std::pair<K const, V> >;
template<class K, class V> using std_unordered_map =
std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map =
boost::unordered_map<K, V, boost::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map =
absl::node_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map =
absl::flat_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
// 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 > {};
template<class K, class V> using std_unordered_map_fnv1a =
std::unordered_map<K, V, fnv1a_hash, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map_fnv1a =
boost::unordered_map<K, V, fnv1a_hash, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using multi_index_map_fnv1a = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first>, fnv1a_hash >
>,
::allocator< pair<K, V> >
>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map_fnv1a =
absl::node_hash_map<K, V, fnv1a_hash, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map_fnv1a =
absl::flat_hash_map<K, V, fnv1a_hash, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map_fnv1a =
tsl::hopscotch_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map_fnv1a =
tsl::hopscotch_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map_fnv1a =
tsl::robin_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map_fnv1a =
tsl::robin_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
//
int main()
{
init_indices();
#if 0
test<std_unordered_map>( "std::unordered_map" );
test<boost_unordered_map>( "boost::unordered_map" );
test<multi_index_map>( "multi_index_map" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
#endif
test<std_unordered_map_fnv1a>( "std::unordered_map, FNV-1a" );
test<boost_unordered_map_fnv1a>( "boost::unordered_map, FNV-1a" );
test<multi_index_map_fnv1a>( "multi_index_map, FNV-1a" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map_fnv1a>( "absl::node_hash_map, FNV-1a" );
test<absl_flat_hash_map_fnv1a>( "absl::flat_hash_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map_fnv1a>( "tsl::hopscotch_map, FNV-1a" );
test<tsl_hopscotch_pg_map_fnv1a>( "tsl::hopscotch_pg_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map_fnv1a>( "tsl::robin_map, FNV-1a" );
test<tsl_robin_pg_map_fnv1a>( "tsl::robin_pg_map, FNV-1a" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 31 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
#ifdef HAVE_ABSEIL
# include "absl/container/internal/raw_hash_set.cc"
# include "absl/hash/internal/hash.cc"
# include "absl/hash/internal/low_level_hash.cc"
# include "absl/hash/internal/city.cc"
#endif

489
benchmark/string_view.cpp Normal file
View File

@ -0,0 +1,489 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#include <boost/unordered_map.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/config.hpp>
#ifdef HAVE_ABSEIL
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#endif
#include <unordered_map>
#include <string_view>
#include <vector>
#include <memory>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std::chrono_literals;
static void print_time( std::chrono::steady_clock::time_point & t1, char const* label, std::uint32_t s, std::size_t size )
{
auto t2 = std::chrono::steady_clock::now();
std::cout << label << ": " << ( t2 - t1 ) / 1ms << " ms (s=" << s << ", size=" << size << ")\n";
t1 = t2;
}
constexpr unsigned N = 2'000'000;
constexpr int K = 10;
static std::vector<std::string> indices1, indices2;
static std::string make_index( unsigned x )
{
char buffer[ 64 ];
std::snprintf( buffer, sizeof(buffer), "pfx_%u_sfx", x );
return buffer;
}
static std::string make_random_index( unsigned x )
{
char buffer[ 64 ];
std::snprintf( buffer, sizeof(buffer), "pfx_%0*d_%u_sfx", x % 8 + 1, 0, x );
return buffer;
}
static void init_indices()
{
indices1.reserve( N*2+1 );
indices1.push_back( make_index( 0 ) );
for( unsigned i = 1; i <= N*2; ++i )
{
indices1.push_back( make_index( i ) );
}
indices2.reserve( N*2+1 );
indices2.push_back( make_index( 0 ) );
{
boost::detail::splitmix64 rng;
for( unsigned i = 1; i <= N*2; ++i )
{
indices2.push_back( make_random_index( static_cast<std::uint32_t>( rng() ) ) );
}
}
}
template<class Map> BOOST_NOINLINE void test_insert( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices1[ i ], i } );
}
print_time( t1, "Consecutive insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices2[ i ], i } );
}
print_time( t1, "Random insert", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_lookup( Map& map, std::chrono::steady_clock::time_point & t1 )
{
std::uint32_t s;
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices1[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices2[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Random lookup", s, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_iteration( Map& map, std::chrono::steady_clock::time_point & t1 )
{
auto it = map.begin();
while( it != map.end() )
{
if( it->second & 1 )
{
if constexpr( std::is_void_v< decltype( map.erase( it ) ) > )
{
map.erase( it++ );
}
else
{
it = map.erase( it );
}
}
else
{
++it;
}
}
print_time( t1, "Iterate and erase odd elements", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_erase( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices1[ i ] );
}
print_time( t1, "Consecutive erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices2[ i ] );
}
print_time( t1, "Random erase", 0, map.size() );
std::cout << std::endl;
}
// counting allocator
static std::size_t s_alloc_bytes = 0;
static std::size_t s_alloc_count = 0;
template<class T> struct allocator
{
using value_type = T;
allocator() = default;
template<class U> allocator( allocator<U> const & ) noexcept
{
}
template<class U> bool operator==( allocator<U> const & ) const noexcept
{
return true;
}
template<class U> bool operator!=( allocator<U> const& ) const noexcept
{
return false;
}
T* allocate( std::size_t n ) const
{
s_alloc_bytes += n * sizeof(T);
s_alloc_count++;
return std::allocator<T>().allocate( n );
}
void deallocate( T* p, std::size_t n ) const noexcept
{
s_alloc_bytes -= n * sizeof(T);
s_alloc_count--;
std::allocator<T>().deallocate( p, n );
}
};
//
struct record
{
std::string label_;
long long time_;
std::size_t bytes_;
std::size_t count_;
};
static std::vector<record> times;
template<template<class...> class Map> BOOST_NOINLINE void test( char const* label )
{
std::cout << label << ":\n\n";
s_alloc_bytes = 0;
s_alloc_count = 0;
Map<std::string_view, std::uint32_t> map;
auto t0 = std::chrono::steady_clock::now();
auto t1 = t0;
test_insert( map, t1 );
std::cout << "Memory: " << s_alloc_bytes << " bytes in " << s_alloc_count << " allocations\n\n";
record rec = { label, 0, s_alloc_bytes, s_alloc_count };
test_lookup( map, t1 );
test_iteration( map, t1 );
test_lookup( map, t1 );
test_erase( map, t1 );
auto tN = std::chrono::steady_clock::now();
std::cout << "Total: " << ( tN - t0 ) / 1ms << " ms\n\n";
rec.time_ = ( tN - t0 ) / 1ms;
times.push_back( rec );
}
// multi_index emulation of unordered_map
template<class K, class V> struct pair
{
K first;
mutable V second;
};
using namespace boost::multi_index;
template<class K, class V> using multi_index_map = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first> >
>,
::allocator< pair<K, V> >
>;
// aliases using the counting allocator
template<class K, class V> using allocator_for = ::allocator< std::pair<K const, V> >;
template<class K, class V> using std_unordered_map =
std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map =
boost::unordered_map<K, V, boost::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map =
absl::node_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map =
absl::flat_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
// fnv1a_hash
template<int Bits> struct fnv1a_hash_impl;
template<> struct fnv1a_hash_impl<32>
{
std::size_t operator()( std::string_view 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_view 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 > {};
template<class K, class V> using std_unordered_map_fnv1a =
std::unordered_map<K, V, fnv1a_hash, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map_fnv1a =
boost::unordered_map<K, V, fnv1a_hash, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using multi_index_map_fnv1a = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first>, fnv1a_hash >
>,
::allocator< pair<K, V> >
>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map_fnv1a =
absl::node_hash_map<K, V, fnv1a_hash, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map_fnv1a =
absl::flat_hash_map<K, V, fnv1a_hash, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map_fnv1a =
tsl::hopscotch_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map_fnv1a =
tsl::hopscotch_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map_fnv1a =
tsl::robin_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map_fnv1a =
tsl::robin_pg_map<K, V, fnv1a_hash, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
//
int main()
{
init_indices();
#if 0
test<std_unordered_map>( "std::unordered_map" );
test<boost_unordered_map>( "boost::unordered_map" );
test<multi_index_map>( "multi_index_map" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
#endif
test<std_unordered_map_fnv1a>( "std::unordered_map, FNV-1a" );
test<boost_unordered_map_fnv1a>( "boost::unordered_map, FNV-1a" );
test<multi_index_map_fnv1a>( "multi_index_map, FNV-1a" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map_fnv1a>( "absl::node_hash_map, FNV-1a" );
test<absl_flat_hash_map_fnv1a>( "absl::flat_hash_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map_fnv1a>( "tsl::hopscotch_map, FNV-1a" );
test<tsl_hopscotch_pg_map_fnv1a>( "tsl::hopscotch_pg_map, FNV-1a" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map_fnv1a>( "tsl::robin_map, FNV-1a" );
test<tsl_robin_pg_map_fnv1a>( "tsl::robin_pg_map, FNV-1a" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 31 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
#ifdef HAVE_ABSEIL
# include "absl/container/internal/raw_hash_set.cc"
# include "absl/hash/internal/hash.cc"
# include "absl/hash/internal/low_level_hash.cc"
# include "absl/hash/internal/city.cc"
#endif

386
benchmark/uint32.cpp Normal file
View File

@ -0,0 +1,386 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#include <boost/unordered_map.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/endian/conversion.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/config.hpp>
#ifdef HAVE_ABSEIL
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std::chrono_literals;
static void print_time( std::chrono::steady_clock::time_point & t1, char const* label, std::uint32_t s, std::size_t size )
{
auto t2 = std::chrono::steady_clock::now();
std::cout << label << ": " << ( t2 - t1 ) / 1ms << " ms (s=" << s << ", size=" << size << ")\n";
t1 = t2;
}
constexpr unsigned N = 2'000'000;
constexpr int K = 10;
static std::vector< std::uint32_t > indices1, indices2, indices3;
static void init_indices()
{
indices1.push_back( 0 );
for( unsigned i = 1; i <= N*2; ++i )
{
indices1.push_back( i );
}
indices2.push_back( 0 );
{
boost::detail::splitmix64 rng;
for( unsigned i = 1; i <= N*2; ++i )
{
indices2.push_back( static_cast<std::uint32_t>( rng() ) );
}
}
indices3.push_back( 0 );
for( unsigned i = 1; i <= N*2; ++i )
{
indices3.push_back( boost::endian::endian_reverse( static_cast<std::uint32_t>( i ) ) );
}
}
template<class Map> BOOST_NOINLINE void test_insert( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices1[ i ], i } );
}
print_time( t1, "Consecutive insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices2[ i ], i } );
}
print_time( t1, "Random insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices3[ i ], i } );
}
print_time( t1, "Consecutive reversed insert", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_lookup( Map& map, std::chrono::steady_clock::time_point & t1 )
{
std::uint32_t s;
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices1[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices2[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Random lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices3[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive reversed lookup", s, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_iteration( Map& map, std::chrono::steady_clock::time_point & t1 )
{
auto it = map.begin();
while( it != map.end() )
{
if( it->second & 1 )
{
if constexpr( std::is_void_v< decltype( map.erase( it ) ) > )
{
map.erase( it++ );
}
else
{
it = map.erase( it );
}
}
else
{
++it;
}
}
print_time( t1, "Iterate and erase odd elements", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_erase( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices1[ i ] );
}
print_time( t1, "Consecutive erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices2[ i ] );
}
print_time( t1, "Random erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices3[ i ] );
}
print_time( t1, "Consecutive reversed erase", 0, map.size() );
std::cout << std::endl;
}
// counting allocator
static std::size_t s_alloc_bytes = 0;
static std::size_t s_alloc_count = 0;
template<class T> struct allocator
{
using value_type = T;
allocator() = default;
template<class U> allocator( allocator<U> const & ) noexcept
{
}
template<class U> bool operator==( allocator<U> const & ) const noexcept
{
return true;
}
template<class U> bool operator!=( allocator<U> const& ) const noexcept
{
return false;
}
T* allocate( std::size_t n ) const
{
s_alloc_bytes += n * sizeof(T);
s_alloc_count++;
return std::allocator<T>().allocate( n );
}
void deallocate( T* p, std::size_t n ) const noexcept
{
s_alloc_bytes -= n * sizeof(T);
s_alloc_count--;
std::allocator<T>().deallocate( p, n );
}
};
//
struct record
{
std::string label_;
long long time_;
std::size_t bytes_;
std::size_t count_;
};
static std::vector<record> times;
template<template<class...> class Map> BOOST_NOINLINE void test( char const* label )
{
std::cout << label << ":\n\n";
s_alloc_bytes = 0;
s_alloc_count = 0;
Map<std::uint32_t, std::uint32_t> map;
auto t0 = std::chrono::steady_clock::now();
auto t1 = t0;
test_insert( map, t1 );
std::cout << "Memory: " << s_alloc_bytes << " bytes in " << s_alloc_count << " allocations\n\n";
record rec = { label, 0, s_alloc_bytes, s_alloc_count };
test_lookup( map, t1 );
test_iteration( map, t1 );
test_lookup( map, t1 );
test_erase( map, t1 );
auto tN = std::chrono::steady_clock::now();
std::cout << "Total: " << ( tN - t0 ) / 1ms << " ms\n\n";
rec.time_ = ( tN - t0 ) / 1ms;
times.push_back( rec );
}
// multi_index emulation of unordered_map
template<class K, class V> struct pair
{
K first;
mutable V second;
};
using namespace boost::multi_index;
template<class K, class V> using multi_index_map = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first> >
>,
::allocator< pair<K, V> >
>;
// aliases using the counting allocator
template<class K, class V> using allocator_for = ::allocator< std::pair<K const, V> >;
template<class K, class V> using std_unordered_map =
std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map =
boost::unordered_map<K, V, boost::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map =
absl::node_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map =
absl::flat_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
int main()
{
init_indices();
test<std_unordered_map>( "std::unordered_map" );
test<boost_unordered_map>( "boost::unordered_map" );
test<multi_index_map>( "multi_index_map" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 25 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
#ifdef HAVE_ABSEIL
# include "absl/container/internal/raw_hash_set.cc"
# include "absl/hash/internal/hash.cc"
# include "absl/hash/internal/low_level_hash.cc"
# include "absl/hash/internal/city.cc"
#endif

386
benchmark/uint64.cpp Normal file
View File

@ -0,0 +1,386 @@
// Copyright 2021 Peter Dimov.
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#define _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
#include <boost/unordered_map.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/endian/conversion.hpp>
#include <boost/core/detail/splitmix64.hpp>
#include <boost/config.hpp>
#ifdef HAVE_ABSEIL
# include "absl/container/node_hash_map.h"
# include "absl/container/flat_hash_map.h"
#endif
#ifdef HAVE_TSL_HOPSCOTCH
# include "tsl/hopscotch_map.h"
#endif
#ifdef HAVE_TSL_ROBIN
# include "tsl/robin_map.h"
#endif
#include <unordered_map>
#include <vector>
#include <memory>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std::chrono_literals;
static void print_time( std::chrono::steady_clock::time_point & t1, char const* label, std::uint64_t s, std::size_t size )
{
auto t2 = std::chrono::steady_clock::now();
std::cout << label << ": " << ( t2 - t1 ) / 1ms << " ms (s=" << s << ", size=" << size << ")\n";
t1 = t2;
}
constexpr unsigned N = 2'000'000;
constexpr int K = 10;
static std::vector< std::uint64_t > indices1, indices2, indices3;
static void init_indices()
{
indices1.push_back( 0 );
for( unsigned i = 1; i <= N*2; ++i )
{
indices1.push_back( i );
}
indices2.push_back( 0 );
{
boost::detail::splitmix64 rng;
for( unsigned i = 1; i <= N*2; ++i )
{
indices2.push_back( rng() );
}
}
indices3.push_back( 0 );
for( unsigned i = 1; i <= N*2; ++i )
{
indices3.push_back( boost::endian::endian_reverse( static_cast<std::uint64_t>( i ) ) );
}
}
template<class Map> BOOST_NOINLINE void test_insert( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices1[ i ], i } );
}
print_time( t1, "Consecutive insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices2[ i ], i } );
}
print_time( t1, "Random insert", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.insert( { indices3[ i ], i } );
}
print_time( t1, "Consecutive reversed insert", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_lookup( Map& map, std::chrono::steady_clock::time_point & t1 )
{
std::uint64_t s;
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices1[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices2[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Random lookup", s, map.size() );
s = 0;
for( int j = 0; j < K; ++j )
{
for( unsigned i = 1; i <= N * 2; ++i )
{
auto it = map.find( indices3[ i ] );
if( it != map.end() ) s += it->second;
}
}
print_time( t1, "Consecutive reversed lookup", s, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_iteration( Map& map, std::chrono::steady_clock::time_point & t1 )
{
auto it = map.begin();
while( it != map.end() )
{
if( it->second & 1 )
{
if constexpr( std::is_void_v< decltype( map.erase( it ) ) > )
{
map.erase( it++ );
}
else
{
it = map.erase( it );
}
}
else
{
++it;
}
}
print_time( t1, "Iterate and erase odd elements", 0, map.size() );
std::cout << std::endl;
}
template<class Map> BOOST_NOINLINE void test_erase( Map& map, std::chrono::steady_clock::time_point & t1 )
{
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices1[ i ] );
}
print_time( t1, "Consecutive erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices2[ i ] );
}
print_time( t1, "Random erase", 0, map.size() );
for( unsigned i = 1; i <= N; ++i )
{
map.erase( indices3[ i ] );
}
print_time( t1, "Consecutive reversed erase", 0, map.size() );
std::cout << std::endl;
}
// counting allocator
static std::size_t s_alloc_bytes = 0;
static std::size_t s_alloc_count = 0;
template<class T> struct allocator
{
using value_type = T;
allocator() = default;
template<class U> allocator( allocator<U> const & ) noexcept
{
}
template<class U> bool operator==( allocator<U> const & ) const noexcept
{
return true;
}
template<class U> bool operator!=( allocator<U> const& ) const noexcept
{
return false;
}
T* allocate( std::size_t n ) const
{
s_alloc_bytes += n * sizeof(T);
s_alloc_count++;
return std::allocator<T>().allocate( n );
}
void deallocate( T* p, std::size_t n ) const noexcept
{
s_alloc_bytes -= n * sizeof(T);
s_alloc_count--;
std::allocator<T>().deallocate( p, n );
}
};
//
struct record
{
std::string label_;
long long time_;
std::size_t bytes_;
std::size_t count_;
};
static std::vector<record> times;
template<template<class...> class Map> BOOST_NOINLINE void test( char const* label )
{
std::cout << label << ":\n\n";
s_alloc_bytes = 0;
s_alloc_count = 0;
Map<std::uint64_t, std::uint64_t> map;
auto t0 = std::chrono::steady_clock::now();
auto t1 = t0;
test_insert( map, t1 );
std::cout << "Memory: " << s_alloc_bytes << " bytes in " << s_alloc_count << " allocations\n\n";
record rec = { label, 0, s_alloc_bytes, s_alloc_count };
test_lookup( map, t1 );
test_iteration( map, t1 );
test_lookup( map, t1 );
test_erase( map, t1 );
auto tN = std::chrono::steady_clock::now();
std::cout << "Total: " << ( tN - t0 ) / 1ms << " ms\n\n";
rec.time_ = ( tN - t0 ) / 1ms;
times.push_back( rec );
}
// multi_index emulation of unordered_map
template<class K, class V> struct pair
{
K first;
mutable V second;
};
using namespace boost::multi_index;
template<class K, class V> using multi_index_map = multi_index_container<
pair<K, V>,
indexed_by<
hashed_unique< member<pair<K, V>, K, &pair<K, V>::first> >
>,
::allocator< pair<K, V> >
>;
// aliases using the counting allocator
template<class K, class V> using allocator_for = ::allocator< std::pair<K const, V> >;
template<class K, class V> using std_unordered_map =
std::unordered_map<K, V, std::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
template<class K, class V> using boost_unordered_map =
boost::unordered_map<K, V, boost::hash<K>, std::equal_to<K>, allocator_for<K, V>>;
#ifdef HAVE_ABSEIL
template<class K, class V> using absl_node_hash_map =
absl::node_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
template<class K, class V> using absl_flat_hash_map =
absl::flat_hash_map<K, V, absl::container_internal::hash_default_hash<K>, absl::container_internal::hash_default_eq<K>, allocator_for<K, V>>;
#endif
#ifdef HAVE_TSL_HOPSCOTCH
template<class K, class V> using tsl_hopscotch_map =
tsl::hopscotch_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_hopscotch_pg_map =
tsl::hopscotch_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
#ifdef HAVE_TSL_ROBIN
template<class K, class V> using tsl_robin_map =
tsl::robin_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
template<class K, class V> using tsl_robin_pg_map =
tsl::robin_pg_map<K, V, std::hash<K>, std::equal_to<K>, ::allocator< std::pair<K, V> >>;
#endif
int main()
{
init_indices();
test<std_unordered_map>( "std::unordered_map" );
test<boost_unordered_map>( "boost::unordered_map" );
test<multi_index_map>( "multi_index_map" );
#ifdef HAVE_ABSEIL
test<absl_node_hash_map>( "absl::node_hash_map" );
test<absl_flat_hash_map>( "absl::flat_hash_map" );
#endif
#ifdef HAVE_TSL_HOPSCOTCH
test<tsl_hopscotch_map>( "tsl::hopscotch_map" );
test<tsl_hopscotch_pg_map>( "tsl::hopscotch_pg_map" );
#endif
#ifdef HAVE_TSL_ROBIN
test<tsl_robin_map>( "tsl::robin_map" );
test<tsl_robin_pg_map>( "tsl::robin_pg_map" );
#endif
std::cout << "---\n\n";
for( auto const& x: times )
{
std::cout << std::setw( 25 ) << ( x.label_ + ": " ) << std::setw( 5 ) << x.time_ << " ms, " << std::setw( 9 ) << x.bytes_ << " bytes in " << x.count_ << " allocations\n";
}
}
#ifdef HAVE_ABSEIL
# include "absl/container/internal/raw_hash_set.cc"
# include "absl/hash/internal/hash.cc"
# include "absl/hash/internal/low_level_hash.cc"
# include "absl/hash/internal/city.cc"
#endif

View File

@ -1,59 +1,21 @@
# Copyright 2005 Daniel James.
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
using boostbook ;
using quickbook ;
import asciidoctor ;
path-constant images_location : ../ ;
path-constant admonishment_location : ../../../../doc/src/images ;
html unordered.html : unordered.adoc ;
xml unordered : unordered.qbk ;
boostbook standalone : unordered :
<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
install html_ : unordered.html : <location>html ;
<xsl:param>boost.compact.typedef=0
<xsl:param>boost.compact.function=0
<xsl:param>boost.compact.enum=0
pdf unordered.pdf : unordered.adoc ;
explicit unordered.pdf ;
# HTML Options:
<format>html:<xsl:param>boost.root=../../../..
<format>html:<xsl:param>img.src.path=../../../../doc/html/
<format>xhtml:<xsl:param>boost.root=../../../..
<format>xhtml:<xsl:param>img.src.path=../../../../doc/html/
# PDF Options:
# TOC Generation: this is needed for FOP-0.9 and later:
<xsl:param>fop1.extensions=0
<format>pdf:<xsl:param>xep.extensions=1
# TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
<format>pdf:<xsl:param>fop.extensions=0
# No indent on body text:
<format>pdf:<xsl:param>body.start.indent=0pt
# Margin size:
<format>pdf:<xsl:param>page.margin.inner=0.5in
# Margin size:
<format>pdf:<xsl:param>page.margin.outer=0.5in
# Paper type = A4
<format>pdf:<xsl:param>paper.type=A4
# Yes, we want graphics for admonishments:
<xsl:param>admon.graphics=1
# Set this one for PDF generation *only*:
# default png graphics are awful in PDF form,
# better use SVG's instead:
<format>pdf:<xsl:param>admon.graphics.extension=".svg"
<format>pdf:<xsl:param>use.role.for.mediaobject=1
<format>pdf:<xsl:param>preferred.mediaobject.role=print
<format>pdf:<xsl:param>img.src.path=$(images_location)/
#<format>pdf:<xsl:param>admon.graphics.path=$(admonishment_location)
<format>pdf:<xsl:param>draft.mode="no"
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/unordered/doc/html
;
install pdf_ : unordered.pdf : <location>pdf ;
explicit pdf_ ;
###############################################################################
alias boostdoc ;
explicit boostdoc ;
alias boostrelease : html_ ;
explicit boostrelease ;

View File

@ -1,26 +0,0 @@
<!--
Copyright Daniel James 2008-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)
-->
<section id="unordered.bibliography">
<title>Bibliography</title>
<bibliography>
<biblioentry>
<biblioset relation="journal">
<title>C/C++ Users Journal</title>
<date>February, 2006</date>
</biblioset>
<biblioset relation="article">
<authorgroup>
<author>
<firstname>Pete</firstname>
<surname>Becker</surname>
</author>
</authorgroup>
<title><ulink url="http://www.ddj.com/cpp/184402066">STL and TR1: Part III - Unordered containers</ulink></title>
</biblioset>
<para>An introducation to the standard unordered containers.</para>
</biblioentry>
</bibliography>
</section>

View File

@ -1,171 +0,0 @@
[/ Copyright 2006-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:buckets The Data Structure]
The containers are made up of a number of 'buckets', each of which can contain
any number of elements. For example, the following diagram shows an [classref
boost::unordered_set unordered_set] with 7 buckets containing 5 elements, `A`,
`B`, `C`, `D` and `E` (this is just for illustration, containers will typically
have more buckets).
[diagram buckets]
In order to decide which bucket to place an element in, the container applies
the hash function, `Hash`, to the element's key (for `unordered_set` and
`unordered_multiset` the key is the whole element, but is referred to as the key
so that the same terminology can be used for sets and maps). This returns a
value of type `std::size_t`. `std::size_t` has a much greater range of values
then the number of buckets, so that container applies another transformation to
that value to choose a bucket to place the element in.
Retrieving the elements for a given key is simple. The same process is applied
to the key to find the correct bucket. Then the key is compared with the
elements in the bucket to find any elements that match (using the equality
predicate `Pred`). If the hash function has worked well the elements will be
evenly distributed amongst the buckets so only a small number of elements will
need to be examined.
There is [link unordered.hash_equality more information on hash functions and
equality predicates in the next section].
You can see in the diagram that `A` & `D` have been placed in the same bucket.
When looking for elements in this bucket up to 2 comparisons are made, making
the search slower. This is known as a collision. To keep things fast we try to
keep collisions to a minimum.
'''
<table frame="all"><title>Methods for Accessing Buckets</title>
<tgroup cols="2">
<thead><row>
<entry><para>Method</para></entry>
<entry><para>Description</para></entry>
</row></thead>
<tbody>
<row>
<entry>'''`size_type bucket_count() const`'''</entry>
<entry>'''The number of buckets.'''</entry>
</row>
<row>
<entry>'''`size_type max_bucket_count() const`'''</entry>
<entry>'''An upper bound on the number of buckets.'''</entry>
</row>
<row>
<entry>'''`size_type bucket_size(size_type n) const`'''</entry>
<entry>'''The number of elements in bucket `n`.'''</entry>
</row>
<row>
<entry>'''`size_type bucket(key_type const& k) const`'''</entry>
<entry>'''Returns the index of the bucket which would contain k'''</entry>
</row>
<row>
<entry>'''`local_iterator begin(size_type n);`'''</entry>
<entry morerows='5'>'''Return begin and end iterators for bucket `n`.'''</entry>
</row>
<row>
<entry>'''`local_iterator end(size_type n);`'''</entry>
</row>
<row>
<entry>'''`const_local_iterator begin(size_type n) const;`'''</entry>
</row>
<row>
<entry>'''`const_local_iterator end(size_type n) const;`'''</entry>
</row>
<row>
<entry>'''`const_local_iterator cbegin(size_type n) const;`'''</entry>
</row>
<row>
<entry>'''`const_local_iterator cend(size_type n) const;`'''</entry>
</row>
</tbody>
</tgroup>
</table>
'''
[h2 Controlling the number of buckets]
As more elements are added to an unordered associative container, the number
of elements in the buckets will increase causing performance to degrade.
To combat this the containers increase the bucket count as elements are inserted.
You can also tell the container to change the bucket count (if required) by
calling `rehash`.
The standard leaves a lot of freedom to the implementer to decide how the
number of buckets are chosen, but it does make some requirements based on the
container's 'load factor', the average number of elements per bucket.
Containers also have a 'maximum load factor' which they should try to keep the
load factor below.
You can't control the bucket count directly but there are two ways to
influence it:
* Specify the minimum number of buckets when constructing a container or
when calling `rehash`.
* Suggest a maximum load factor by calling `max_load_factor`.
`max_load_factor` doesn't let you set the maximum load factor yourself, it just
lets you give a /hint/. And even then, the draft standard doesn't actually
require the container to pay much attention to this value. The only time the
load factor is /required/ to be less than the maximum is following a call to
`rehash`. But most implementations will try to keep the number of elements
below the max load factor, and set the maximum load factor to be the same as
or close to the hint - unless your hint is unreasonably small or large.
[table:bucket_size Methods for Controlling Bucket Size
[[Method] [Description]]
[
[`X(size_type n)`]
[Construct an empty container with at least `n` buckets (`X` is the container type).]
]
[
[`X(InputIterator i, InputIterator j, size_type n)`]
[Construct an empty container with at least `n` buckets and insert elements
from the range \[`i`, `j`) (`X` is the container type).]
]
[
[`float load_factor() const`]
[The average number of elements per bucket.]
]
[
[`float max_load_factor() const`]
[Returns the current maximum load factor.]
]
[
[`float max_load_factor(float z)`]
[Changes the container's maximum load factor, using `z` as a hint.]
]
[
[`void rehash(size_type n)`]
[Changes the number of buckets so that there at least n buckets, and
so that the load factor is less than the maximum load factor.]
]
]
[h2 Iterator Invalidation]
It is not specified how member functions other than `rehash` affect
the bucket count, although `insert` is only allowed to invalidate iterators
when the insertion causes the load factor to be greater than or equal to the
maximum load factor. For most implementations this means that insert will only
change the number of buckets when this happens. While iterators can be
invalidated by calls to `insert` and `rehash`, pointers and references to the
container's elements are never invalidated.
In a similar manner to using `reserve` for `vector`s, it can be a good idea
to call `rehash` before inserting a large number of elements. This will get
the expensive rehashing out of the way and let you store iterators, safe in
the knowledge that they won't be invalidated. If you are inserting `n`
elements into container `x`, you could first call:
x.rehash((x.size() + n) / x.max_load_factor() + 1);
[blurb Note: `rehash`'s argument is the minimum number of buckets, not the
number of elements, which is why the new size is divided by the maximum load factor. The
`+ 1` guarantees there is no invalidation; without it, reallocation could occur
if the number of bucket exactly divides the target size, since the container is
allowed to rehash when the load factor is equal to the maximum load factor.]
[endsect]

View File

@ -1,202 +0,0 @@
[/ Copyright 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 Review Version]
Initial review version, for the review conducted from 7th December 2007 to
16th December 2007.
[h2 1.35.0 Add-on - 31st March 2008]
Unofficial release uploaded to vault, to be used with Boost 1.35.0. Incorporated
many of the suggestions from the review.
* Improved portability thanks to Boost regression testing.
* Fix lots of typos, and clearer text in the documentation.
* Fix floating point to `std::size_t` conversion when calculating sizes from
the max load factor, and use `double` in the calculation for greater accuracy.
* Fix some errors in the examples.
[h2 Boost 1.36.0]
First official release.
* Rearrange the internals.
* Move semantics - full support when rvalue references are available, emulated
using a cut down version of the Adobe move library when they are not.
* Emplace support when rvalue references and variadic template are available.
* More efficient node allocation when rvalue references and variadic template
are available.
* Added equality operators.
[h2 Boost 1.37.0]
* Rename overload of `emplace` with hint, to `emplace_hint` as specified in
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf n2691].
* Provide forwarding headers at `<boost/unordered/unordered_map_fwd.hpp>` and
`<boost/unordered/unordered_set_fwd.hpp>`.
* Move all the implementation inside `boost/unordered`, to assist
modularization and hopefully make it easier to track changes in subversion.
[h2 Boost 1.38.0]
* Use [@boost:/libs/utility/swap.html `boost::swap`].
* [@https://svn.boost.org/trac/boost/ticket/2237 Ticket 2237]:
Document that the equality and inequality operators are undefined for two
objects if their equality predicates aren't equivalent. Thanks to Daniel
Krügler.
* [@https://svn.boost.org/trac/boost/ticket/1710 Ticket 1710]:
Use a larger prime number list. Thanks to Thorsten Ottosen and Hervé
Brönnimann.
* Use
[@boost:/libs/type_traits/doc/html/boost_typetraits/category/alignment.html
aligned storage] to store the types. This changes the way the allocator is
used to construct nodes. It used to construct the node with two calls to
the allocator's `construct` method - once for the pointers and once for the
value. It now constructs the node with a single call to construct and
then constructs the value using in place construction.
* Add support for C++0x initializer lists where they're available (currently
only g++ 4.4 in C++0x mode).
[h2 Boost 1.39.0]
* [@https://svn.boost.org/trac/boost/ticket/2756 Ticket 2756]: Avoid a warning
on Visual C++ 2009.
* Some other minor internal changes to the implementation, tests and
documentation.
* Avoid an unnecessary copy in `operator[]`.
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]: Fix length of
prime number list.
[h2 Boost 1.40.0]
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]:
Store the prime list as a preprocessor sequence - so that it will always get
the length right if it changes again in the future.
* [@https://svn.boost.org/trac/boost/ticket/1978 Ticket 1978]:
Implement `emplace` for all compilers.
* [@https://svn.boost.org/trac/boost/ticket/2908 Ticket 2908],
[@https://svn.boost.org/trac/boost/ticket/3096 Ticket 3096]:
Some workarounds for old versions of borland, including adding explicit
destructors to all containers.
* [@https://svn.boost.org/trac/boost/ticket/3082 Ticket 3082]:
Disable incorrect Visual C++ warnings.
* Better configuration for C++0x features when the headers aren't available.
* Create less buckets by default.
[h2 Boost 1.41.0 - Major update]
* The original version made heavy use of macros to sidestep some of the older
compilers' poor template support. But since I no longer support those
compilers and the macro use was starting to become a maintenance burden it
has been rewritten to use templates instead of macros for the implementation
classes.
* The container objcet is now smaller thanks to using `boost::compressed_pair`
for EBO and a slightly different function buffer - now using a bool instead
of a member pointer.
* Buckets are allocated lazily which means that constructing an empty container
will not allocate any memory.
[h2 Boost 1.42.0]
* Support instantiating the containers with incomplete value types.
* Reduced the number of warnings (mostly in tests).
* Improved codegear compatibility.
* [@http://svn.boost.org/trac/boost/ticket/3693 Ticket 3693]:
Add `erase_return_void` as a temporary workaround for the current
`erase` which can be inefficient because it has to find the next
element to return an iterator.
* Add templated find overload for compatible keys.
* [@http://svn.boost.org/trac/boost/ticket/3773 Ticket 3773]:
Add missing `std` qualifier to `ptrdiff_t`.
* Some code formatting changes to fit almost all lines into 80 characters.
[h2 Boost 1.43.0]
* [@http://svn.boost.org/trac/boost/ticket/3966 Ticket 3966]:
`erase_return_void` is now `quick_erase`, which is the
[@http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#579
current forerunner for resolving the slow erase by iterator], although
there's a strong possibility that this may change in the future. The old
method name remains for backwards compatibility but is considered deprecated
and will be removed in a future release.
* Use Boost.Exception.
* Stop using deprecated `BOOST_HAS_*` macros.
[h2 Boost 1.45.0]
* Fix a bug when inserting into an `unordered_map` or `unordered_set` using
iterators which returns `value_type` by copy.
[h2 Boost 1.48.0 - Major update]
This is major change which has been converted to use Boost.Move's move
emulation, and be more compliant with the C++11 standard. See the
[link unordered.compliance compliance section] for details.
The container now meets C++11's complexity requirements, but to do so
uses a little more memory. This means that `quick_erase` and
`erase_return_void` are no longer required, they'll be removed in a
future version.
C++11 support has resulted in some breaking changes:
* Equality comparison has been changed to the C++11 specification.
In a container with equivalent keys, elements in a group with equal
keys used to have to be in the same order to be considered equal,
now they can be a permutation of each other. To use the old
behavior define the macro `BOOST_UNORDERED_DEPRECATED_EQUALITY`.
* The behaviour of swap is different when the two containers to be
swapped has unequal allocators. It used to allocate new nodes using
the appropriate allocators, it now swaps the allocators if
the allocator has a member structure `propagate_on_container_swap`,
such that `propagate_on_container_swap::value` is true.
* Allocator's `construct` and `destroy` functions are called with raw
pointers, rather than the allocator's `pointer` type.
* `emplace` used to emulate the variadic pair constructors that
appeared in early C++0x drafts. Since they were removed it no
longer does so. It does emulate the new `piecewise_construct`
pair constructors - only you need to use
`boost::piecewise_construct`. To use the old emulation of
the variadic consturctors define
`BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT`.
[h2 Boost 1.49.0]
* Fix warning due to accidental odd assignment.
* Slightly better error messages.
[h2 Boost 1.50.0]
* Fix equality for `unordered_multiset` and `unordered_multimap`.
* [@https://svn.boost.org/trac/boost/ticket/6857 Ticket 6857]:
Implement `reserve`.
* [@https://svn.boost.org/trac/boost/ticket/6771 Ticket 6771]:
Avoid gcc's `-Wfloat-equal` warning.
* [@https://svn.boost.org/trac/boost/ticket/6784 Ticket 6784]:
Fix some Sun specific code.
* [@https://svn.boost.org/trac/boost/ticket/6190 Ticket 6190]:
Avoid gcc's `-Wshadow` warning.
* [@https://svn.boost.org/trac/boost/ticket/6905 Ticket 6905]:
Make namespaces in macros compatible with `bcp` custom namespaces.
Fixed by Luke Elliott.
* Remove some of the smaller prime number of buckets, as they may make
collisions quite probable (e.g. multiples of 5 are very common because
we used base 10).
* On old versions of Visual C++, use the container library's implementation
of `allocator_traits`, as it's more likely to work.
* On machines with 64 bit std::size_t, use power of 2 buckets, with Thomas
Wang's hash function to pick which one to use. As modulus is very slow
for 64 bit values.
* Some internal changes.
[endsect]

View File

@ -1,161 +0,0 @@
[/ Copyright 2006-2011 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[section:comparison Comparison with Associative Containers]
[table:interface_differences Interface differences.
[[Associative Containers] [Unordered Associative Containers]]
[
[Parameterized by an ordering relation `Compare`]
[Parameterized by a function object `Hash` and an equivalence relation
`Pred`]
]
[
[Keys can be compared using `key_compare` which is accessed by member function `key_comp()`,
values can be compared using `value_compare` which is accessed by member function `value_comp()`.]
[Keys can be hashed using `hasher` which is accessed by member function `hash_function()`,
and checked for equality using `key_equal` which is accessed by member function `key_eq()`.
There is no function object for compared or hashing values.]
]
[
[Constructors have optional extra parameters for the comparison object.]
[Constructors have optional extra parameters for the initial minimum
number of buckets, a hash function and an equality object.]
]
[
[Keys `k1`, `k2` are considered equivalent if
`!Compare(k1, k2) && !Compare(k2, k1)`]
[Keys `k1`, `k2` are considered equivalent if `Pred(k1, k2)`]
]
[
[Member function `lower_bound(k)` and `upper_bound(k)`]
[No equivalent. Since the elements aren't ordered `lower_bound` and
`upper_bound` would be meaningless.]
]
[
[`equal_range(k)` returns an empty range at the position that k
would be inserted if k isn't present in the container.]
[`equal_range(k)` returns a range at the end of the container if
k isn't present in the container. It can't return a positioned
range as k could be inserted into multiple place. To find out the
bucket that k would be inserted into use `bucket(k)`. But remember
that an insert can cause the container to rehash - meaning that the
element can be inserted into a different bucket.]
]
[
[`iterator`, `const_iterator` are of the bidirectional category.]
[`iterator`, `const_iterator` are of at least the forward category.]
]
[
[Iterators, pointers and references to the container's elements are
never invalidated.]
[[link unordered.buckets.iterator_invalidation Iterators can
be invalidated by calls to insert or rehash]. Pointers and
references to the container's elements are never invalidated.]
]
[
[Iterators iterate through the container in the order defined by
the comparison object.]
[Iterators iterate through the container in an arbitrary order, that
can change as elements are inserted. Although, equivalent elements
are always adjacent.]
]
[
[No equivalent]
[Local iterators can be used to iterate through individual buckets.
(The order of local iterators and iterators aren't
required to have any correspondence.)]
]
[
[Can be compared using the `==`, `!=`, `<`, `<=`, `>`, `>=` operators.]
[Can be compared using the `==` and `!=` operators.]
]
[
[]
[When inserting with a hint, implementations are permitted to ignore
the hint.]
]
[
[`erase` never throws an exception]
[The containers' hash or predicate function can throw exceptions
from `erase`]
]
]
[table:complexity_guarantees Complexity Guarantees
[[Operation] [Associative Containers] [Unordered Associative Containers]]
[
[Construction of empty container]
[constant]
[O(/n/) where /n/ is the minimum number of buckets.]
]
[
[Construction of container from a range of /N/ elements]
[O(/N/ log /N/), O(/N/) if the range is sorted with `value_comp()`]
[Average case O(/N/), worst case
O(/N/'''<superscript>2</superscript>''')]
]
[
[Insert a single element]
[logarithmic]
[Average case constant, worst case linear]
]
[
[Insert a single element with a hint]
[Amortized constant if t elements inserted right after hint,
logarithmic otherwise]
[Average case constant, worst case linear (ie. the same as
a normal insert).]
]
[
[Inserting a range of /N/ elements]
[ /N/ log(`size()`+/N/) ]
[Average case O(/N/), worst case O(/N/ * `size()`)]
]
[
[Erase by key, `k`]
[O(log(`size()`) + `count(k)`)]
[Average case: O(`count(k)`), Worst case: O(`size()`)]
]
[
[Erase a single element by iterator]
[Amortized constant]
[Average case: O(1), Worst case: O(`size()`)]
]
[
[Erase a range of /N/ elements]
[O(log(`size()`) + /N/)]
[Average case: O(/N/), Worst case: O(`size()`)]
]
[
[Clearing the container]
[O(`size()`)]
[O(`size()`)]
]
[
[Find]
[logarithmic]
[Average case: O(1), Worst case: O(`size()`)]
]
[/ TODO: Average case is probably wrong. ]
[
[Count]
[O(log(`size()`) + `count(k)`)]
[Average case: O(1), Worst case: O(`size()`)]
]
[
[`equal_range(k)`]
[logarithmic]
[Average case: O(`count(k)`), Worst case: O(`size()`)]
]
[
[`lower_bound`,`upper_bound`]
[logarithmic]
[n/a]
]
]
[endsect]

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,313 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="507.85925"
height="400.45422"
viewBox="1.33 0.95 6.01 4.09"
id="svg2">
<defs
id="defs95" />
<rect
width="6.0023117"
height="4.0815721"
x="1.3310578"
y="0.95080346"
id="rect4"
style="fill:#e5e5e5;stroke:none;stroke-width:0" />
<rect
width="6.0023117"
height="4.0815721"
x="1.3310578"
y="0.95080346"
id="rect6"
style="opacity:1;fill:none;stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="1.5711501"
y="1.1908962"
id="rect8"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="1.5711501"
y="1.1908962"
id="rect10"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="1.7289008"
y="1.4950322"
id="text12"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 1</text>
<line
x1="1.5711501"
y1="1.6710808"
x2="2.7716124"
y2="1.6710808"
id="line14"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="3.0117054"
y="1.1908962"
id="rect16"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="3.0117054"
y="1.1908962"
id="rect18"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="3.1603069"
y="1.4950322"
id="text20"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 2</text>
<line
x1="3.0117054"
y1="1.6710808"
x2="4.2121677"
y2="1.6710808"
id="line22"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="4.4522605"
y="1.1908962"
id="rect24"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="4.4522605"
y="1.1908962"
id="rect26"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="4.5917125"
y="1.4950322"
id="text28"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 3</text>
<line
x1="4.4522605"
y1="1.6710808"
x2="5.6527228"
y2="1.6710808"
id="line30"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="5.8928151"
y="1.1908962"
id="rect32"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="5.8928151"
y="1.1908962"
id="rect34"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="6.0688629"
y="1.4858831"
id="text36"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 4</text>
<line
x1="5.8928151"
y1="1.6710808"
x2="7.093277"
y2="1.6710808"
id="line38"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="2.2941716"
y="3.1054616"
id="rect40"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="2.2941716"
y="3.1054616"
id="rect42"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="2.4427731"
y="3.4187472"
id="text44"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 5</text>
<line
x1="2.2941716"
y1="3.5856469"
x2="3.4946339"
y2="3.5856469"
id="line46"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="3.7347264"
y="3.1054616"
id="rect48"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="3.7347264"
y="3.1054616"
id="rect50"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="3.8833277"
y="3.4187472"
id="text52"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 6</text>
<line
x1="3.7347264"
y1="3.5856469"
x2="4.9351892"
y2="3.5856469"
id="line54"
style="stroke:#000000;stroke-width:0.02400924" />
<rect
width="1.2004625"
height="1.6806473"
x="5.175281"
y="3.1054616"
id="rect56"
style="fill:#ffffff;stroke:none;stroke-width:0" />
<rect
width="1.2004625"
height="1.6806473"
x="5.175281"
y="3.1054616"
id="rect58"
style="fill:none;stroke:#000000;stroke-width:0.02400924" />
<text
x="5.3330317"
y="3.4187472"
id="text60"
style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 7</text>
<line
x1="5.175281"
y1="3.5856469"
x2="6.3757439"
y2="3.5856469"
id="line62"
style="stroke:#000000;stroke-width:0.02400924" />
<ellipse
cx="7.1999998"
cy="4.0110002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse64"
style="fill:#ffffff;stroke:none" />
<ellipse
cx="7.1999998"
cy="4.0110002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse66"
style="fill:none;stroke:#000000;stroke-width:0.035" />
<text
x="6.1443377"
y="2.1364057"
id="text68"
style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">A</text>
<ellipse
cx="3.007"
cy="4.0300002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse70"
style="fill:#ffffff;stroke:none" />
<ellipse
cx="3.007"
cy="4.0300002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse72"
style="fill:none;stroke:#000000;stroke-width:0.035" />
<text
x="3.2742035"
y="2.1540098"
id="text74"
style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">B</text>
<ellipse
cx="4.0599999"
cy="6.7820001"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse76"
style="fill:#ffffff;stroke:none" />
<ellipse
cx="4.0599999"
cy="6.7820001"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse78"
style="fill:none;stroke:#000000;stroke-width:0.035" />
<text
x="3.976877"
y="4.0473108"
id="text80"
style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">C</text>
<ellipse
cx="7.8449998"
cy="4.6550002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse82"
style="fill:#ffffff;stroke:none" />
<ellipse
cx="7.8449998"
cy="4.6550002"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse84"
style="fill:none;stroke:#000000;stroke-width:0.035" />
<text
x="6.5808516"
y="2.5937216"
id="text86"
style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">D</text>
<ellipse
cx="0.87"
cy="4.0079999"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse88"
style="fill:#ffffff;stroke:none" />
<ellipse
cx="0.87"
cy="4.0079999"
rx="0.308"
ry="0.308"
transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)"
id="ellipse90"
style="fill:none;stroke:#000000;stroke-width:0.035" />
<text
x="1.7991183"
y="2.1403852"
id="text92"
style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">E</text>
</svg>

Before

Width:  |  Height:  |  Size: 9.1 KiB

BIN
doc/diagrams/fca.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -1,86 +0,0 @@
[/ Copyright 2006-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:hash_equality Equality Predicates and Hash Functions]
While the associative containers use an ordering relation to specify how the
elements are stored, the unordered associative containers use an equality
predicate and a hash function. For example, [classref boost::unordered_map]
is declared as:
template <
class Key, class Mapped,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class ``[classref boost::unordered_map unordered_map]``;
The hash function comes first as you might want to change the hash function
but not the equality predicate. For example, if you wanted to use the
[@http://www.isthe.com/chongo/tech/comp/fnv/ FNV-1 hash] you could write:
[import src_code/dictionary.cpp]
[case_sensitive_dictionary_fnv]
There is an [@boost:/libs/unordered/examples/fnv1.hpp implementation
of FNV-1] in the examples directory.
If you wish to use a different equality function,
you will also need to use a matching hash function. For
example, to implement a case insensitive dictionary you need to define a
case insensitive equality predicate and hash function:
[case_insensitive_functions]
Which you can then use in a case insensitive dictionary:
[case_insensitive_dictionary]
This is a simplified version of the example at
[@boost:/libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
which supports other locales and string types.
[caution
Be careful when using the equality (`==`) operator with custom equality
predicates, especially if you're using a function pointer. If you compare two
containers with different equality predicates then the result is undefined.
For most stateless function objects this is impossible - since you can only
compare objects with the same equality predicate you know the equality
predicates must be equal. But if you're using function pointers or a stateful
equality predicate (e.g. boost::function) then you can get into trouble.
]
[h2 Custom Types]
Similarly, a custom hash function can be used for custom types:
[import src_code/point1.cpp]
[point_example1]
Since the default hash function is [link hash Boost.Hash],
we can [link hash.custom extend it to support the type]
so that the hash function doesn't need to be explicitly given:
[import src_code/point2.cpp]
[point_example2]
See the [link hash.custom Boost.Hash documentation] for more detail on how to
do this. Remember that it relies on extensions to the draft standard - so it
won't work for other implementations of the unordered associative containers,
you'll need to explicitly use Boost.Hash.
[table:access_methods Methods for accessing the hash and equality functions.
[[Method] [Description]]
[
[`hasher hash_function() const`]
[Returns the container's hash function.]
]
[
[`key_equal key_eq() const`]
[Returns the container's key equality function.]
]
]
[endsect]

View File

@ -1,101 +0,0 @@
[/ Copyright 2006-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 __hash-table__ [@http://en.wikipedia.org/wiki/Hash_table
hash table]]
[def __hash-function__ [@http://en.wikipedia.org/wiki/Hash_function
hash function]]
[section:intro Introduction]
For accessing data based on key lookup, the C++ standard library offers `std::set`,
`std::map`, `std::multiset` and `std::multimap`. These are generally
implemented using balanced binary trees so that lookup time has
logarithmic complexity. That is generally okay, but in many cases a
__hash-table__ can perform better, as accessing data has constant complexity,
on average. The worst case complexity is linear, but that occurs rarely and
with some care, can be avoided.
Also, the existing containers require a 'less than' comparison object
to order their elements. For some data types this is impossible to implement
or isn't practical. In contrast, a hash table only needs an equality function
and a hash function for the key.
With this in mind, unordered associative containers were added to the C++
standard. This is an implementation of the containers described in C++11,
with some [link unordered.compliance deviations from the standard] in
order to work with non-C++11 compilers and libraries.
`unordered_set` and `unordered_multiset` are defined in the header
<[headerref boost/unordered_set.hpp]>
namespace boost {
template <
class Key,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_set unordered_set]``;
template<
class Key,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_multiset unordered_multiset]``;
}
`unordered_map` and `unordered_multimap` are defined in the header
<[headerref boost/unordered_map.hpp]>
namespace boost {
template <
class Key, class Mapped,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_map unordered_map]``;
template<
class Key, class Mapped,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_multimap unordered_multimap]``;
}
When using Boost.TR1, these classes are included from `<unordered_set>` and
`<unordered_map>`, with the classes added to the `std::tr1` namespace.
The containers are used in a similar manner to the normal associative
containers:
[import src_code/intro.cpp]
[intro_example1_2]
But since the elements aren't ordered, the output of:
[intro_example1_3]
can be in any order. For example, it might be:
two,2
one,1
three,3
To store an object in an unordered associative container requires both an
key equality function and a hash function. The default function objects in
the standard containers support a few basic types including integer types,
floating point types, pointer types, and the standard strings. Since
Boost.Unordered uses [classref boost::hash] it also supports some other types,
including standard containers. To use any types not supported by these methods
you have to [link hash.custom extend Boost.Hash to support the type] or use
your own custom equality predicates and hash functions. See the
[link unordered.hash_equality Equality Predicates and Hash Functions] section
for more details.
There are other differences, which are listed in the
[link unordered.comparison Comparison with Associative Containers] section.
[endsect]

47
doc/preview.md Normal file
View File

@ -0,0 +1,47 @@
# Building Boost from the Tip of Develop
To build Boost from the tip of the develop branch without cloning the entire
history, use the command below:
Linux:
```bash
cwd=$(pwd) \
&& cd ~ \
&& git clone -b develop --depth 1 --recurse-submodules --shallow-submodules --jobs 8 https://github.com/boostorg/boost.git boost-develop-beta \
&& cd boost-develop-beta \
&& ./bootstrap.sh \
&& ./b2 install --prefix=boost-install cxxstd=17 \
&& echo "Boost successfully installed into $(realpath boost-install)!
Add this to your CMake toolchain file.
list(APPEND CMAKE_PREFIX_PATH $(realpath boost-install))
" \
&& cd $cwd
```
Windows (using plain Command Prompt):
```bat
cmd /v
set cwd=%cd% ^
&& cd %homepath% ^
&& git clone -b develop --depth 1 --recurse-submodules --shallow-submodules --jobs 8 https://github.com/boostorg/boost.git boost-develop-beta ^
&& cd boost-develop-beta ^
&& bootstrap.bat ^
&& b2 install --prefix=boost-install cxxstd=17 address-model=64 ^
&& echo Boost successfully installed into !cd!\boost-install! ^
&& echo Add this to your CMake toolchain file. ^
&& echo list(APPEND CMAKE_PREFIX_PATH !cd:\=/!/boost-install) ^
&& cd !cwd! ^
&& exit
```
Note: you can build Boost with a specific compiler by setting the toolset in
the `./b2` command above. To build with clang, specify `toolset=clang`; to build
with a specific version of gcc, clang or msvc, specify e.g. `toolset=gcc-12` for GCC
12, `clang-14` for Clang 14, `msvc-14.3` for MSVC 14.3. The value of `cxxstd`
can also be set to other values such as 11 for C++11, 14 for C++14, etc.
For more info on what's possible, check out this link on b2:
https://www.boost.org/doc/libs/develop/tools/build/doc/html/index.html#bbv2.overview.builtins.features
This should hopefully cover the two most common cases of building a dependency,
setting the compiler and C++ standard used.

View File

@ -1,106 +0,0 @@
[/ Copyright 2006-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 __wang__
[@http://www.concentric.net/~Ttwang/tech/inthash.htm
Thomas Wang's article on integer hash functions]]
[section:rationale Implementation Rationale]
The intent of this library is to implement the unordered
containers in the draft standard, so the interface was fixed. But there are
still some implementation decisions to make. The priorities are
conformance to the standard and portability.
The [@http://en.wikipedia.org/wiki/Hash_table wikipedia article on hash tables]
has a good summary of the implementation issues for hash tables in general.
[h2 Data Structure]
By specifying an interface for accessing the buckets of the container the
standard pretty much requires that the hash table uses chained addressing.
It would be conceivable to write a hash table that uses another method. For
example, it could use open addressing, and use the lookup chain to act as a
bucket but there are a some serious problems with this:
* The draft standard requires that pointers to elements aren't invalidated, so
the elements can't be stored in one array, but will need a layer of
indirection instead - losing the efficiency and most of the memory gain,
the main advantages of open addressing.
* Local iterators would be very inefficient and may not be able to
meet the complexity requirements.
* There are also the restrictions on when iterators can be invalidated. Since
open addressing degrades badly when there are a high number of collisions the
restrictions could prevent a rehash when it's really needed. The maximum load
factor could be set to a fairly low value to work around this - but the
standard requires that it is initially set to 1.0.
* And since the standard is written with a eye towards chained
addressing, users will be surprised if the performance doesn't reflect that.
So chained addressing is used.
[/ (Removing for now as this is out of date)
For containers with unique keys I store the buckets in a single-linked list.
There are other possible data structures (such as a double-linked list)
that allow for some operations to be faster (such as erasing and iteration)
but the possible gain seems small compared to the extra memory needed.
The most commonly used operations (insertion and lookup) would not be improved
at all.
But for containers with equivalent keys a single-linked list can degrade badly
when a large number of elements with equivalent keys are inserted. I think it's
reasonable to assume that users who choose to use `unordered_multiset` or
`unordered_multimap` do so because they are likely to insert elements with
equivalent keys. So I have used an alternative data structure that doesn't
degrade, at the expense of an extra pointer per node.
This works by adding storing a circular linked list for each group of equivalent
nodes in reverse order. This allows quick navigation to the end of a group (since
the first element points to the last) and can be quickly updated when elements
are inserted or erased. The main disadvantage of this approach is some hairy code
for erasing elements.
]
[/ (Starting to write up new structure, might not be ready in time)
The node used to be stored in a linked list for each bucket but that
didn't meet the complexity requirements for C++11, so now the nodes
are stored in one long single linked list. But there needs a way to get
the bucket from the node, to do that a copy of the key's hash value is
stored in the node. Another possibility would be to store a pointer to
the bucket, or the bucket's index, but storing the hash value allows
some operations to be faster.
]
[h2 Number of Buckets]
There are two popular methods for choosing the number of buckets in a hash
table. One is to have a prime number of buckets, another is to use a power
of 2.
Using a prime number of buckets, and choosing a bucket by using the modulus
of the hash function's result will usually give a good result. The downside
is that the required modulus operation is fairly expensive.
Using a power of 2 allows for much quicker selection of the bucket
to use, but at the expense of loosing the upper bits of the hash value.
For some specially designed hash functions it is possible to do this and
still get a good result but as the containers can take arbitrary hash
functions this can't be relied on.
To avoid this a transformation could be applied to the hash function, for an
example see __wang__. Unfortunately, a transformation like Wang's requires
knowledge of the number of bits in the hash value, so it isn't portable enough.
This leaves more expensive methods, such as Knuth's Multiplicative Method
(mentioned in Wang's article). These don't tend to work as well as taking the
modulus of a prime, and the extra computation required might negate
efficiency advantage of power of 2 hash tables.
So, this implementation uses a prime number for the hash table size.
[endsect]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

188
doc/roadmap.md Normal file
View File

@ -0,0 +1,188 @@
# Refactoring Roadmap
[Proof of concept](https://github.com/joaquintides/fca_unordered) implementation for a fast closed-addressing implementation.
## Plan of Refactoring
* remove `ptr_node` and `ptr_bucket`
* see if the code can survive a lack of the `extra_node` or maybe we hard-code it in
* implement bucket groups as they are in `fca` but don't use them directly yet, add alongside the `buckets_` data member in `struct table`
* try to remove `bucket_info_` from the node structure (breaks all call-sites that use `get_bucket()` and dependents)
* make sure `fca` can successfully handle multi-variants at this stage + supports mutable iterators for `map`/`multimap`
* do a hard-break:
* update code to no longer use one single linked list across all buckets (each bucket contains its own unique list)
* integrate the `bucket_group<Node>` structure into the `table` (update iterator call-sites to include `bucket_iterator`s)
Blockers:
* how to handle `multi` variants with new `fca` prototype
## Implementation Differences
### Unordered
### Node Type
Bullet Points:
* reify node type into a single one
* come up with implementation for multi- variants
* code that touches `get_bucket()` and `*_in_group()` member functions may need updating
There are two node types in Unordered, `struct node` and `struct ptr_node`, and the node type is selected conditionally based on the Allocator's pointer type:
```c++
template <typename A, typename T, typename NodePtr, typename BucketPtr>
struct pick_node2
{
typedef boost::unordered::detail::node<A, T> node;
// ...
};
template <typename A, typename T>
struct pick_node2<A, T, boost::unordered::detail::ptr_node<T>*,
boost::unordered::detail::ptr_bucket*>
{
typedef boost::unordered::detail::ptr_node<T> node;
// ...
};
template <typename A, typename T> struct pick_node
{
typedef typename boost::remove_const<T>::type nonconst;
typedef boost::unordered::detail::allocator_traits<
typename boost::unordered::detail::rebind_wrap<A,
boost::unordered::detail::ptr_node<nonconst> >::type>
tentative_node_traits;
typedef boost::unordered::detail::allocator_traits<
typename boost::unordered::detail::rebind_wrap<A,
boost::unordered::detail::ptr_bucket>::type>
tentative_bucket_traits;
typedef pick_node2<A, nonconst, typename tentative_node_traits::pointer,
typename tentative_bucket_traits::pointer>
pick;
typedef typename pick::node node;
typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer;
};
```
The node types are identical in terms of interface and the only difference is that `node` is chosen when the Allocator uses fancy pointers and `ptr_node` is chosen when the Allocator's pointer type is `T*`.
Nodes in Unorderd store `bucket_info_`:
```cpp
template <typename A, typename T>
struct node : boost::unordered::detail::value_base<T>
{
link_pointer next_;
std::size_t bucket_info_;
node() : next_(), bucket_info_(0) {}
// ...
};
```
`bucket_info_` maps each node back to its corresponding bucket via the member function:
```cpp
std::size_t get_bucket() const
{
return bucket_info_ & ((std::size_t)-1 >> 1);
}
```
`bucket_info_` is also used to demarcate the start of equivalent nodes in the containers via:
```cpp
// Note that nodes start out as the first in their group, as `bucket_info_` defaults to 0.
std::size_t is_first_in_group() const
{ return !(bucket_info_ & ~((std::size_t)-1 >> 1)); }
void set_first_in_group()
{ bucket_info_ = bucket_info_ & ((std::size_t)-1 >> 1); }
void reset_first_in_group()
{ bucket_info_ = bucket_info_ | ~((std::size_t)-1 >> 1); }
```
A goal of refactoring is to simply have one node type:
```cpp
template<class T>
struct node {
node *next;
T value;
};
```
that is used unconditionally. This also requires updating the code that touches the `bucket_info_` along with the code that that touches the `*_in_group()` member functions.
### Bucket Type
Bullet points:
* reify bucket structure into a single one
* figure out how to add `bucket_group`s to the table struct
Buckets are similar to nodes in that there are two variations: `template<class NodePointer> struct bucket` and `struct ptr_bucket`.
The buckets exist to contain a pointer to a node, however they contain an `enum { extra_node = true };` or `enum { extra_node = false }` to determine whether or not the code should explicitly allocate a default constructed node whose address assigned as the dummy node at the end of the bucket array.
`extra_node` is used in the creation and deletion of the bucket array but it is not inherently clear what its intended purpose is.
### Iterators
Iterators are currently templated on the type of Node they store. Because `fca` constructs iterators with two arguments, all the call-sites that instantiate iterators will need to be updated but this a straight-forward mechanical change.
Iterators are selected, as of now, via the `detail::map` and `detail::set` class templates.
For example, for `unordered_map`, `iterator` is defined as:
```cpp
typedef boost::unordered::detail::map<A, K, T, H, P> types;
typedef typename types::table table;
typedef typename table::iterator iterator;
```
The iterator is a member typedef of the `table` which is `types::table`. Examining `types` (aka `detail::map<...>`), we see:
```cpp
template <typename A, typename K, typename M, typename H, typename P>
struct map {
// ...
typedef boost::unordered::detail::table<types> table;
// ...
};
```
Examining the `detail::table<types>` struct, we see:
```cpp
template <typename Types>
struct table {
// ...
typedef typename Types::iterator iterator;
// ...
}
```
Collapsing all of this, we see that our iterator types are defined here:
```cpp
template <typename A, typename K, typename M, typename H, typename P>
struct map
{
// ...
typedef boost::unordered::detail::pick_node<A, value_type> pick;
typedef typename pick::node node;
typedef boost::unordered::iterator_detail::iterator<node> iterator;
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail::l_iterator<node> l_iterator;
typedef boost::unordered::iterator_detail::cl_iterator<node>
cl_iterator;
// ...
};
```
This is similarly designed for `detail::set`:
```cpp
typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail::cl_iterator<node> l_iterator;
typedef boost::unordered::iterator_detail::cl_iterator<node>
cl_iterator;
```
The only difference here is that `set::iterator` is always a `c_iterator`, a `const_iterator` type.

View File

@ -1,103 +0,0 @@
// Copyright 2006-2007 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "../../examples/fnv1.hpp"
//[case_insensitive_functions
struct iequal_to
: std::binary_function<std::string, std::string, bool>
{
bool operator()(std::string const& x,
std::string const& y) const
{
return boost::algorithm::iequals(x, y, std::locale());
}
};
struct ihash
: std::unary_function<std::string, std::size_t>
{
std::size_t operator()(std::string const& x) const
{
std::size_t seed = 0;
std::locale locale;
for(std::string::const_iterator it = x.begin();
it != x.end(); ++it)
{
boost::hash_combine(seed, std::toupper(*it, locale));
}
return seed;
}
};
//]
int main() {
//[case_sensitive_dictionary_fnv
boost::unordered_map<std::string, int, hash::fnv_1>
dictionary;
//]
BOOST_TEST(dictionary.empty());
dictionary["one"] = 1;
BOOST_TEST(dictionary.size() == 1);
BOOST_TEST(dictionary.find("ONE") == dictionary.end());
dictionary.insert(std::make_pair("ONE", 2));
BOOST_TEST(dictionary.size() == 2);
BOOST_TEST(dictionary.find("ONE") != dictionary.end() &&
dictionary.find("ONE")->first == "ONE" &&
dictionary.find("ONE")->second == 2);
dictionary["One"] = 3;
BOOST_TEST(dictionary.size() == 3);
BOOST_TEST(dictionary.find("One") != dictionary.end() &&
dictionary.find("One")->first == "One" &&
dictionary.find("One")->second == 3);
dictionary["two"] = 4;
BOOST_TEST(dictionary.size() == 4);
BOOST_TEST(dictionary.find("Two") == dictionary.end() &&
dictionary.find("two") != dictionary.end() &&
dictionary.find("two")->second == 4);
//[case_insensitive_dictionary
boost::unordered_map<std::string, int, ihash, iequal_to>
idictionary;
//]
BOOST_TEST(idictionary.empty());
idictionary["one"] = 1;
BOOST_TEST(idictionary.size() == 1);
BOOST_TEST(idictionary.find("ONE") != idictionary.end() &&
idictionary.find("ONE") == idictionary.find("one"));
idictionary.insert(std::make_pair("ONE", 2));
BOOST_TEST(idictionary.size() == 1);
BOOST_TEST(idictionary.find("ONE") != idictionary.end() &&
idictionary.find("ONE")->first == "one" &&
idictionary.find("ONE")->second == 1);
idictionary["One"] = 3;
BOOST_TEST(idictionary.size() == 1);
BOOST_TEST(idictionary.find("ONE") != idictionary.end() &&
idictionary.find("ONE")->first == "one" &&
idictionary.find("ONE")->second == 3);
idictionary["two"] = 4;
BOOST_TEST(idictionary.size() == 2);
BOOST_TEST(idictionary.find("two") != idictionary.end() &&
idictionary.find("TWO")->first == "two" &&
idictionary.find("Two")->second == 4);
return boost::report_errors();
}

View File

@ -1,30 +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)
//[intro_example1_1
#include <boost/unordered_map.hpp>
#include <boost/foreach.hpp>
#include <cassert>
#include <iostream>
//]
int main() {
//[intro_example1_2
typedef boost::unordered_map<std::string, int> map;
map x;
x["one"] = 1;
x["two"] = 2;
x["three"] = 3;
assert(x.at("one") == 1);
assert(x.find("missing") == x.end());
//]
//[intro_example1_3
BOOST_FOREACH(map::value_type i, x) {
std::cout<<i.first<<","<<i.second<<"\n";
}
//]
}

View File

@ -1,45 +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 <boost/unordered_set.hpp>
#include <boost/detail/lightweight_test.hpp>
//[point_example1
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
struct point_hash
: std::unary_function<point, std::size_t>
{
std::size_t operator()(point const& p) const
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
};
boost::unordered_multiset<point, point_hash> points;
//]
int main() {
point x[] = {{1,2}, {3,4}, {1,5}, {1,2}};
for(int i = 0; i < sizeof(x) / sizeof(point); ++i)
points.insert(x[i]);
BOOST_TEST(points.count(x[0]) == 2);
BOOST_TEST(points.count(x[1]) == 1);
point y = {10, 2};
BOOST_TEST(points.count(y) == 0);
return boost::report_errors();
}

View File

@ -1,43 +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 <boost/unordered_set.hpp>
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
//[point_example2
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
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;
}
// Now the default function objects work.
boost::unordered_multiset<point> points;
//]
int main() {
point x[] = {{1,2}, {3,4}, {1,5}, {1,2}};
for(int i = 0; i < sizeof(x) / sizeof(point); ++i)
points.insert(x[i]);
BOOST_TEST(points.count(x[0]) == 2);
BOOST_TEST(points.count(x[1]) == 1);
point y = {10, 2};
BOOST_TEST(points.count(y) == 0);
return boost::report_errors();
}

23
doc/unordered.adoc Normal file
View File

@ -0,0 +1,23 @@
= Boost.Unordered
:toc: left
:toclevels: 3
:idprefix:
:docinfo: private-footer
:source-highlighter: rouge
:source-language: c++
:nofooter:
:sectlinks:
:leveloffset: +1
include::unordered/intro.adoc[]
include::unordered/buckets.adoc[]
include::unordered/benchmarks.adoc[]
include::unordered/hash_equality.adoc[]
include::unordered/comparison.adoc[]
include::unordered/compliance.adoc[]
include::unordered/rationale.adoc[]
include::unordered/ref.adoc[]
include::unordered/changes.adoc[]
include::unordered/bibliography.adoc[]
include::unordered/copyright.adoc[]

View File

@ -1,38 +0,0 @@
[/ Copyright 2006-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) ]
[library Boost.Unordered
[quickbook 1.5]
[authors [James, Daniel]]
[copyright 2003 2004 Jeremy B. Maitin-Shepard]
[copyright 2005 2006 2007 2008 Daniel James]
[purpose std::tr1 compliant hash containers]
[id unordered]
[dirname unordered]
[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])
]
]
[template diagram[name] '''<inlinemediaobject>
<imageobject role="html">
<imagedata align = "center" fileref="../../libs/unordered/doc/diagrams/'''[name]'''.png"></imagedata>
</imageobject>
<imageobject role="print">
<imagedata align = "center" fileref="../../libs/unordered/doc/diagrams/'''[name]'''.svg"></imagedata>
</imageobject>
</inlinemediaobject>''']
[include:unordered intro.qbk]
[include:unordered buckets.qbk]
[include:unordered hash_equality.qbk]
[include:unordered comparison.qbk]
[include:unordered compliance.qbk]
[include:unordered rationale.qbk]
[include:unordered changes.qbk]
[xinclude ref.xml]
[xinclude bibliography.xml]

View File

@ -0,0 +1,277 @@
[#benchmarks]
:idprefix: benchmarks_
:imagesdir: ../diagrams
= Benchmarks
All benchmarks were created using `unordered_set<unsigned int>` (non-duplicate) and `unordered_multiset<unsigned int>` (duplicate). The source code can be https://github.com/joaquintides/boost_unordered_benchmark[found here].
The insertion benchmarks insert `n` random values, where `n` is between 10,000 and 3 million. For the duplicated benchmarks, the same random values are repeated an average of 5 times.
The erasure benchmarks erase all `n` elements randomly until the container is empty.
The successful lookup benchmarks are done by looking up all `n` values, in the their original insertion order.
The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value.
== GCC 11 + libstdc++-v3
=== Insertion
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/gcc/running insertion.xlsx.practice.png[width=250,link=../diagrams/benchmarks/gcc/running insertion.xlsx.practice.png,window=_blank]
|image::benchmarks/gcc/running%20insertion.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice non-unique.png,window=_blank]
|image::benchmarks/gcc/running%20insertion.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice non-unique 5.png,window=_blank]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements +
max load factor 5
|===
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash.png,window=_blank]
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique.png,window=_blank]
|image::benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/running%20insertion.xlsx.practice norehash non-unique 5.png,window=_blank]
h|non-duplicate elements, +
prior `reserve`
h|duplicate elements, +
prior `reserve`
h|duplicate elements, +
max load factor 5, +
prior `reserve`
|===
=== Erasure
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice.png,window=_blank]
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique.png,window=_blank]
|image::benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,link=../diagrams/benchmarks/gcc/scattered%20erasure.xlsx.practice non-unique 5.png,window=_blank]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements +
max load factor 5
|===
=== Successful Lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice.png]
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
=== Unsuccessful lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/gcc/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
== Clang 12 + libc++
=== Insertion
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice.png]
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique.png]
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png[width=250, window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash.png]
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique.png]
|image::benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/running%20insertion.xlsx.practice norehash non-unique 5.png]
h|non-duplicate elements, +
prior `reserve`
h|duplicate elements, +
prior `reserve`
h|duplicate elements, +
max load factor 5, +
prior `reserve`
|===
=== Erasure
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice.png]
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique.png]
|image::benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20erasure.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
=== Successful lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice.png]
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
=== Unsuccessful lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/clang_libcpp/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
== Visual Studio 2019 + Dinkumware
=== Insertion
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/vs/running%20insertion.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice.png]
|image::benchmarks/vs/running%20insertion.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice non-unique.png]
|image::benchmarks/vs/running%20insertion.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash.png]
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique.png]
|image::benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/running%20insertion.xlsx.practice norehash non-unique 5.png]
h|non-duplicate elements, +
prior `reserve`
h|duplicate elements, +
prior `reserve`
h|duplicate elements, +
max load factor 5, +
prior `reserve`
|===
=== Erasure
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/vs/scattered%20erasure.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice.png]
|image::benchmarks/vs/scattered%20erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice non-unique.png]
|image::benchmarks/vs/scattered%20erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20erasure.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
=== Successful lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice.png]
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20successful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===
=== Unsuccessful lookup
[caption=]
[cols="3*^.^a", frame=all, grid=all]
|===
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice.png]
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique.png]
|image::benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=../diagrams/benchmarks/vs/scattered%20unsuccessful%20looukp.xlsx.practice non-unique 5.png]
h|non-duplicate elements
h|duplicate elements
h|duplicate elements, +
max load factor 5
|===

View File

@ -0,0 +1,10 @@
[#bibliography]
:idprefix: bibliography_
= Bibliography
* _C/C++ Users Journal_. February, 2006. Pete Becker. http://www.ddj.com/cpp/184402066[STL and TR1: Part III - Unordered containers^]. +
An introducation to the standard unordered containers.

210
doc/unordered/buckets.adoc Normal file
View File

@ -0,0 +1,210 @@
[#buckets]
:idprefix: buckets_
:imagesdir: ../diagrams
= The Data Structure
The containers are made up of a number of 'buckets', each of which can contain
any number of elements. For example, the following diagram shows an <<unordered_set,unordered_set>> with 7 buckets containing 5 elements, `A`,
`B`, `C`, `D` and `E` (this is just for illustration, containers will typically
have more buckets).
image::buckets.png[]
In order to decide which bucket to place an element in, the container applies
the hash function, `Hash`, to the element's key (for `unordered_set` and
`unordered_multiset` the key is the whole element, but is referred to as the key
so that the same terminology can be used for sets and maps). This returns a
value of type `std::size_t`. `std::size_t` has a much greater range of values
then the number of buckets, so the container applies another transformation to
that value to choose a bucket to place the element in.
Retrieving the elements for a given key is simple. The same process is applied
to the key to find the correct bucket. Then the key is compared with the
elements in the bucket to find any elements that match (using the equality
predicate `Pred`). If the hash function has worked well the elements will be
evenly distributed amongst the buckets so only a small number of elements will
need to be examined.
There is <<hash_equality, more information on hash functions and
equality predicates in the next section>>.
You can see in the diagram that `A` & `D` have been placed in the same bucket.
When looking for elements in this bucket up to 2 comparisons are made, making
the search slower. This is known as a collision. To keep things fast we try to
keep collisions to a minimum.
[caption=, title='Table {counter:table-counter}. Methods for Accessing Buckets']
[cols="1,.^1", frame=all, grid=rows]
|===
|Method |Description
|`size_type bucket_count() const`
|The number of buckets.
|`size_type max_bucket_count() const`
|An upper bound on the number of buckets.
|`size_type bucket_size(size_type n) const`
|The number of elements in bucket `n`.
|`size_type bucket(key_type const& k) const`
|Returns the index of the bucket which would contain `k`.
|`local_iterator begin(size_type n)`
1.6+|Return begin and end iterators for bucket `n`.
|`local_iterator end(size_type n)`
|`const_local_iterator begin(size_type n) const`
|`const_local_iterator end(size_type n) const`
|`const_local_iterator cbegin(size_type n) const`
|`const_local_iterator cend(size_type n) const`
|===
== Controlling the number of buckets
As more elements are added to an unordered associative container, the number
of elements in the buckets will increase causing performance to degrade.
To combat this the containers increase the bucket count as elements are inserted.
You can also tell the container to change the bucket count (if required) by
calling `rehash`.
The standard leaves a lot of freedom to the implementer to decide how the
number of buckets is chosen, but it does make some requirements based on the
container's 'load factor', the average number of elements per bucket.
Containers also have a 'maximum load factor' which they should try to keep the
load factor below.
You can't control the bucket count directly but there are two ways to
influence it:
* Specify the minimum number of buckets when constructing a container or when calling `rehash`.
* Suggest a maximum load factor by calling `max_load_factor`.
`max_load_factor` doesn't let you set the maximum load factor yourself, it just
lets you give a _hint_. And even then, the standard doesn't actually
require the container to pay much attention to this value. The only time the
load factor is _required_ to be less than the maximum is following a call to
`rehash`. But most implementations will try to keep the number of elements
below the max load factor, and set the maximum load factor to be the same as
or close to the hint - unless your hint is unreasonably small or large.
[caption=, title='Table {counter:table-counter}. Methods for Controlling Bucket Size']
[cols="1,.^1", frame=all, grid=rows]
|===
|Method |Description
|`X(size_type n)`
|Construct an empty container with at least `n` buckets (`X` is the container type).
|`X(InputIterator i, InputIterator j, size_type n)`
|Construct an empty container with at least `n` buckets and insert elements from the range `[i, j)` (`X` is the container type).
|`float load_factor() const`
|The average number of elements per bucket.
|`float max_load_factor() const`
|Returns the current maximum load factor.
|`float max_load_factor(float z)`
|Changes the container's maximum load factor, using `z` as a hint.
|`void rehash(size_type n)`
|Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
|===
== Iterator Invalidation
It is not specified how member functions other than `rehash` and `reserve` affect
the bucket count, although `insert` is only allowed to invalidate iterators
when the insertion causes the load factor to be greater than or equal to the
maximum load factor. For most implementations this means that `insert` will only
change the number of buckets when this happens. While iterators can be
invalidated by calls to `insert`, `rehash` and `reserve`, pointers and references to the
container's elements are never invalidated.
In a similar manner to using `reserve` for ``vector``s, it can be a good idea
to call `reserve` before inserting a large number of elements. This will get
the expensive rehashing out of the way and let you store iterators, safe in
the knowledge that they won't be invalidated. If you are inserting `n`
elements into container `x`, you could first call:
```
x.reserve(n);
```
Note:: `reserve(n)` reserves space for at least `n` elements, allocating enough buckets
so as to not exceed the maximum load factor.
+
Because the maximum load factor is defined as the number of elements divided by the total
number of available buckets, this function is logically equivalent to:
+
```
x.rehash(std::ceil(n / x.max_load_factor()))
```
+
See the <<unordered_map_rehash,reference for more details>> on the `rehash` function.
== Fast Closed Addressing Implementation
++++
<style>
.imageblock > .title {
text-align: inherit;
}
</style>
++++
Boost.Unordered sports one of the fastest implementations of closed addressing, also commonly known as https://en.wikipedia.org/wiki/Hash_table#Separate_chaining[separate chaining]. An example figure representing the data structure is below:
[#img-bucket-groups,.text-center]
.A simple bucket group approach
image::bucket-groups.png[align=center]
An array of "buckets" is allocated and each bucket in turn points to its own individual linked list. This makes meeting the standard requirements of bucket iteration straight-forward. Unfortunately, iteration of the entire container is often times slow using this layout as each bucket must be examined for occupancy, yielding a time complexity of `O(bucket_count() + size())` when the standard requires complexity to be `O(size())`.
Canonical standard implementations will wind up looking like the diagram below:
[.text-center]
.The canonical standard approach
image::singly-linked.png[align=center,link=../diagrams/singly-linked.png,window=_blank]
It's worth noting that this approach is only used by pass:[libc++] and pass:[libstdc++]; the MSVC Dinkumware implementation uses a different one. A more detailed analysis of the standard containers can be found http://bannalia.blogspot.com/2013/10/implementation-of-c-unordered.html[here].
This unusually laid out data structure is chosen to make iteration of the entire container efficient by inter-connecting all of the nodes into a singly-linked list. One might also notice that buckets point to the node _before_ the start of the bucket's elements. This is done so that removing elements from the list can be done efficiently without introducing the need for a doubly-linked list. Unfortunately, this data structure introduces a guaranteed extra indirection. For example, to access the first element of a bucket, something like this must be done:
```c++
auto const idx = get_bucket_idx(hash_function(key));
node* p = buckets[idx]; // first load
node* n = p->next; // second load
if (n && is_in_bucket(n, idx)) {
value_type const& v = *n; // third load
// ...
}
```
With a simple bucket group layout, this is all that must be done:
```c++
auto const idx = get_bucket_idx(hash_function(key));
node* n = buckets[idx]; // first load
if (n) {
value_type const& v = *n; // second load
// ...
}
```
In practice, the extra indirection can have a dramatic performance impact to common operations such as `insert`, `find` and `erase`. But to keep iteration of the container fast, Boost.Unordered introduces a novel data structure, a "bucket group". A bucket group is a fixed-width view of a subsection of the buckets array. It contains a bitmask (a `std::size_t`) which it uses to track occupancy of buckets and contains two pointers so that it can form a doubly-linked list with non-empty groups. An example diagram is below:
[#img-fca-layout]
.The new layout used by Boost
image::fca.png[align=center]
Thus container-wide iteration is turned into traversing the non-empty bucket groups (an operation with constant time complexity) which reduces the time complexity back to `O(size())`. In total, a bucket group is only 4 words in size and it views `sizeof(std::size_t) * CHAR_BIT` buckets meaning that for all common implementations, there's only 4 bits of space overhead per bucket introduced by the bucket groups.
For more information on implementation rationale, read the <<Implementation Rationale, corresponding section>>.

381
doc/unordered/changes.adoc Normal file
View File

@ -0,0 +1,381 @@
[#changes]
= Change Log
:idprefix: changes_
:svn-ticket-url: https://svn.boost.org/trac/boost/ticket
:github-pr-url: https://github.com/boostorg/unordered/pull
:cpp: C++
== Release 1.80.0 - Major update
* Refactor internal implementation to be dramatically faster
* Allow `final` Hasher and KeyEqual objects
* Update documentation, adding benchmark graphs and notes on the new internal
data structures
== Release 1.79.0
* Improved {cpp}20 support:
** All containers have been updated to support
heterogeneous `count`, `equal_range` and `find`.
** All containers now implement the member function `contains`.
** `erase_if` has been implemented for all containers.
* Improved {cpp}23 support:
** All containers have been updated to support
heterogeneous `erase` and `extract`.
* Changed behavior of `reserve` to eagerly
allocate ({github-pr-url}/59[PR#59^]).
* Various warning fixes in the test suite.
* Update code to internally use `boost::allocator_traits`.
* Switch to Fibonacci hashing.
* Update documentation to be written in AsciiDoc instead of QuickBook.
== Release 1.67.0
* Improved {cpp}17 support:
** Add template deduction guides from the standard.
** Use a simple implementation of `optional` in node handles, so
that they're closer to the standard.
** Add missing `noexcept` specifications to `swap`, `operator=`
and node handles, and change the implementation to match.
Using `std::allocator_traits::is_always_equal`, or our own
implementation when not available, and
`boost::is_nothrow_swappable` in the implementation.
* Improved {cpp}20 support:
** Use `boost::to_address`, which has the proposed {cpp}20 semantics,
rather than the old custom implementation.
* Add `element_type` to iterators, so that `std::pointer_traits`
will work.
* Use `std::piecewise_construct` on recent versions of Visual {cpp},
and other uses of the Dinkumware standard library,
now using Boost.Predef to check compiler and library versions.
* Use `std::iterator_traits` rather than the boost iterator traits
in order to remove dependency on Boost.Iterator.
* Remove iterators' inheritance from `std::iterator`, which is
deprecated in {cpp}17, thanks to Daniela Engert
({github-pr-url}/7[PR#7^]).
* Stop using `BOOST_DEDUCED_TYPENAME`.
* Update some Boost include paths.
* Rename some internal methods, and variables.
* Various testing improvements.
* Miscellaneous internal changes.
== Release 1.66.0
* Simpler move construction implementation.
* Documentation fixes ({github-pr-url}/6[GitHub #6^]).
== Release 1.65.0
* Add deprecated attributes to `quick_erase` and `erase_return_void`.
I really will remove them in a future version this time.
* Small standards compliance fixes:
** `noexpect` specs for `swap` free functions.
** Add missing `insert(P&&)` methods.
== Release 1.64.0
* Initial support for new {cpp}17 member functions:
`insert_or_assign` and `try_emplace` in `unordered_map`,
* Initial support for `merge` and `extract`.
Does not include transferring nodes between
`unordered_map` and `unordered_multimap` or between `unordered_set` and
`unordered_multiset` yet. That will hopefully be in the next version of
Boost.
== Release 1.63.0
* Check hint iterator in `insert`/`emplace_hint`.
* Fix some warnings, mostly in the tests.
* Manually write out `emplace_args` for small numbers of arguments -
should make template error messages a little more bearable.
* Remove superfluous use of `boost::forward` in emplace arguments,
which fixes emplacing string literals in old versions of Visual {cpp}.
* Fix an exception safety issue in assignment. If bucket allocation
throws an exception, it can overwrite the hash and equality functions while
leaving the existing elements in place. This would mean that the function
objects wouldn't match the container elements, so elements might be in the
wrong bucket and equivalent elements would be incorrectly handled.
* Various reference documentation improvements.
* Better allocator support ({svn-ticket-url}/12459[#12459^]).
* Make the no argument constructors implicit.
* Implement missing allocator aware constructors.
* Fix assigning the hash/key equality functions for empty containers.
* Remove unary/binary_function from the examples in the documentation.
They are removed in {cpp}17.
* Support 10 constructor arguments in emplace. It was meant to support up to 10
arguments, but an off by one error in the preprocessor code meant it only
supported up to 9.
== Release 1.62.0
* Remove use of deprecated `boost::iterator`.
* Remove `BOOST_NO_STD_DISTANCE` workaround.
* Remove `BOOST_UNORDERED_DEPRECATED_EQUALITY` warning.
* Simpler implementation of assignment, fixes an exception safety issue
for `unordered_multiset` and `unordered_multimap`. Might be a little slower.
* Stop using return value SFINAE which some older compilers have issues
with.
== Release 1.58.0
* Remove unnecessary template parameter from const iterators.
* Rename private `iterator` typedef in some iterator classes, as it
confuses some traits classes.
* Fix move assignment with stateful, propagate_on_container_move_assign
allocators ({svn-ticket-url}/10777[#10777^]).
* Fix rare exception safety issue in move assignment.
* Fix potential overflow when calculating number of buckets to allocate
({github-pr-url}/4[GitHub #4^]).
== Release 1.57.0
* Fix the `pointer` typedef in iterators ({svn-ticket-url}/10672[#10672^]).
* Fix Coverity warning
({github-pr-url}/2[GitHub #2^]).
== Release 1.56.0
* Fix some shadowed variable warnings ({svn-ticket-url}/9377[#9377^]).
* Fix allocator use in documentation ({svn-ticket-url}/9719[#9719^]).
* Always use prime number of buckets for integers. Fixes performance
regression when inserting consecutive integers, although makes other
uses slower ({svn-ticket-url}/9282[#9282^]).
* Only construct elements using allocators, as specified in {cpp}11 standard.
== Release 1.55.0
* Avoid some warnings ({svn-ticket-url}/8851[#8851^], {svn-ticket-url}/8874[#8874^]).
* Avoid exposing some detail functions via. ADL on the iterators.
* Follow the standard by only using the allocators' construct and destroy
methods to construct and destroy stored elements. Don't use them for internal
data like pointers.
== Release 1.54.0
* Mark methods specified in standard as `noexpect`. More to come in the next
release.
* If the hash function and equality predicate are known to both have nothrow
move assignment or construction then use them.
== Release 1.53.0
* Remove support for the old pre-standard variadic pair constructors, and
equality implementation. Both have been deprecated since Boost 1.48.
* Remove use of deprecated config macros.
* More internal implementation changes, including a much simpler
implementation of `erase`.
== Release 1.52.0
* Faster assign, which assigns to existing nodes where possible, rather than
creating entirely new nodes and copy constructing.
* Fixed bug in `erase_range` ({svn-ticket-url}/7471[#7471^]).
* Reverted some of the internal changes to how nodes are created, especially
for {cpp}11 compilers. 'construct' and 'destroy' should work a little better
for {cpp}11 allocators.
* Simplified the implementation a bit. Hopefully more robust.
== Release 1.51.0
* Fix construction/destruction issue when using a {cpp}11 compiler with a
{cpp}03 allocator ({svn-ticket-url}/7100[#7100^]).
* Remove a `try..catch` to support compiling without exceptions.
* Adjust SFINAE use to try to support g++ 3.4 ({svn-ticket-url}/7175[#7175^]).
* Updated to use the new config macros.
== Release 1.50.0
* Fix equality for `unordered_multiset` and `unordered_multimap`.
* {svn-ticket-url}/6857[Ticket 6857^]:
Implement `reserve`.
* {svn-ticket-url}/6771[Ticket 6771^]:
Avoid gcc's `-Wfloat-equal` warning.
* {svn-ticket-url}/6784[Ticket 6784^]:
Fix some Sun specific code.
* {svn-ticket-url}/6190[Ticket 6190^]:
Avoid gcc's `-Wshadow` warning.
* {svn-ticket-url}/6905[Ticket 6905^]:
Make namespaces in macros compatible with `bcp` custom namespaces.
Fixed by Luke Elliott.
* Remove some of the smaller prime number of buckets, as they may make
collisions quite probable (e.g. multiples of 5 are very common because
we used base 10).
* On old versions of Visual {cpp}, use the container library's implementation
of `allocator_traits`, as it's more likely to work.
* On machines with 64 bit std::size_t, use power of 2 buckets, with Thomas
Wang's hash function to pick which one to use. As modulus is very slow
for 64 bit values.
* Some internal changes.
== Release 1.49.0
* Fix warning due to accidental odd assignment.
* Slightly better error messages.
== Release 1.48.0 - Major update
This is major change which has been converted to use Boost.Move's move
emulation, and be more compliant with the {cpp}11 standard. See the
xref:unordered.adoc#compliance[compliance section] for details.
The container now meets {cpp}11's complexity requirements, but to do so
uses a little more memory. This means that `quick_erase` and
`erase_return_void` are no longer required, they'll be removed in a
future version.
{cpp}11 support has resulted in some breaking changes:
* Equality comparison has been changed to the {cpp}11 specification.
In a container with equivalent keys, elements in a group with equal
keys used to have to be in the same order to be considered equal,
now they can be a permutation of each other. To use the old
behavior define the macro `BOOST_UNORDERED_DEPRECATED_EQUALITY`.
* The behaviour of swap is different when the two containers to be
swapped has unequal allocators. It used to allocate new nodes using
the appropriate allocators, it now swaps the allocators if
the allocator has a member structure `propagate_on_container_swap`,
such that `propagate_on_container_swap::value` is true.
* Allocator's `construct` and `destroy` functions are called with raw
pointers, rather than the allocator's `pointer` type.
* `emplace` used to emulate the variadic pair constructors that
appeared in early {cpp}0x drafts. Since they were removed it no
longer does so. It does emulate the new `piecewise_construct`
pair constructors - only you need to use
`boost::piecewise_construct`. To use the old emulation of
the variadic constructors define
`BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT`.
== Release 1.45.0
* Fix a bug when inserting into an `unordered_map` or `unordered_set` using
iterators which returns `value_type` by copy.
== Release 1.43.0
* {svn-ticket-url}/3966[Ticket 3966^]:
`erase_return_void` is now `quick_erase`, which is the
http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#579[
current forerunner for resolving the slow erase by iterator^], although
there's a strong possibility that this may change in the future. The old
method name remains for backwards compatibility but is considered deprecated
and will be removed in a future release.
* Use Boost.Exception.
* Stop using deprecated `BOOST_HAS_*` macros.
== Release 1.42.0
* Support instantiating the containers with incomplete value types.
* Reduced the number of warnings (mostly in tests).
* Improved codegear compatibility.
* {svn-ticket-url}/3693[Ticket 3693^]:
Add `erase_return_void` as a temporary workaround for the current
`erase` which can be inefficient because it has to find the next
element to return an iterator.
* Add templated find overload for compatible keys.
* {svn-ticket-url}/3773[Ticket 3773^]:
Add missing `std` qualifier to `ptrdiff_t`.
* Some code formatting changes to fit almost all lines into 80 characters.
== Release 1.41.0 - Major update
* The original version made heavy use of macros to sidestep some of the older
compilers' poor template support. But since I no longer support those
compilers and the macro use was starting to become a maintenance burden it
has been rewritten to use templates instead of macros for the implementation
classes.
* The container object is now smaller thanks to using `boost::compressed_pair`
for EBO and a slightly different function buffer - now using a bool instead
of a member pointer.
* Buckets are allocated lazily which means that constructing an empty container
will not allocate any memory.
== Release 1.40.0
* {svn-ticket-url}/2975[Ticket 2975^]:
Store the prime list as a preprocessor sequence - so that it will always get
the length right if it changes again in the future.
* {svn-ticket-url}/1978[Ticket 1978^]:
Implement `emplace` for all compilers.
* {svn-ticket-url}/2908[Ticket 2908^],
{svn-ticket-url}/3096[Ticket 3096^]:
Some workarounds for old versions of borland, including adding explicit
destructors to all containers.
* {svn-ticket-url}/3082[Ticket 3082^]:
Disable incorrect Visual {cpp} warnings.
* Better configuration for {cpp}0x features when the headers aren't available.
* Create less buckets by default.
== Release 1.39.0
* {svn-ticket-url}/2756[Ticket 2756^]: Avoid a warning
on Visual {cpp} 2009.
* Some other minor internal changes to the implementation, tests and
documentation.
* Avoid an unnecessary copy in `operator[]`.
* {svn-ticket-url}/2975[Ticket 2975^]: Fix length of
prime number list.
== Release 1.38.0
* Use link:../../../core/swap.html[`boost::swap`^].
* {svn-ticket-url}/2237[Ticket 2237^]:
Document that the equality and inequality operators are undefined for two
objects if their equality predicates aren't equivalent. Thanks to Daniel
Krügler.
* {svn-ticket-url}/1710[Ticket 1710^]:
Use a larger prime number list. Thanks to Thorsten Ottosen and Hervé
Brönnimann.
* Use
link:../../../type_traits/index.html[aligned storage^] to store the types.
This changes the way the allocator is used to construct nodes. It used to
construct the node with two calls to the allocator's `construct`
method - once for the pointers and once for the value. It now constructs
the node with a single call to construct and then constructs the value using
in place construction.
* Add support for {cpp}0x initializer lists where they're available (currently
only g++ 4.4 in {cpp}0x mode).
== Release 1.37.0
* Rename overload of `emplace` with hint, to `emplace_hint` as specified in
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf[n2691^].
* Provide forwarding headers at `<boost/unordered/unordered_map_fwd.hpp>` and
`<boost/unordered/unordered_set_fwd.hpp>`.
* Move all the implementation inside `boost/unordered`, to assist
modularization and hopefully make it easier to track Release subversion.
== Release 1.36.0
First official release.
* Rearrange the internals.
* Move semantics - full support when rvalue references are available, emulated
using a cut down version of the Adobe move library when they are not.
* Emplace support when rvalue references and variadic template are available.
* More efficient node allocation when rvalue references and variadic template
are available.
* Added equality operators.
== Boost 1.35.0 Add-on - 31st March 2008
Unofficial release uploaded to vault, to be used with Boost 1.35.0. Incorporated
many of the suggestions from the review.
* Improved portability thanks to Boost regression testing.
* Fix lots of typos, and clearer text in the documentation.
* Fix floating point to `std::size_t` conversion when calculating sizes from
the max load factor, and use `double` in the calculation for greater accuracy.
* Fix some errors in the examples.
== Review Version
Initial review version, for the review conducted from 7th December 2007 to
16th December 2007.

View File

@ -0,0 +1,112 @@
[#comparison]
:idprefix: comparison_
= Comparison with Associative Containers
[caption=, title='Table {counter:table-counter} Interface differences']
[cols="1,1", frame=all, grid=rows]
|===
|Associative Containers |Unordered Associative Containers
|Parameterized by an ordering relation `Compare`
|Parameterized by a function object `Hash` and an equivalence relation `Pred`
|Keys can be compared using `key_compare` which is accessed by member function `key_comp()`, values can be compared using `value_compare` which is accessed by member function `value_comp()`.
|Keys can be hashed using `hasher` which is accessed by member function `hash_function()`, and checked for equality using `key_equal` which is accessed by member function `key_eq()`. There is no function object for compared or hashing values.
|Constructors have optional extra parameters for the comparison object.
|Constructors have optional extra parameters for the initial minimum number of buckets, a hash function and an equality object.
|Keys `k1`, `k2` are considered equivalent if `!Compare(k1, k2) && !Compare(k2, k1)`.
|Keys `k1`, `k2` are considered equivalent if `Pred(k1, k2)`
|Member function `lower_bound(k)` and `upper_bound(k)`
|No equivalent. Since the elements aren't ordered `lower_bound` and `upper_bound` would be meaningless.
|`equal_range(k)` returns an empty range at the position that `k` would be inserted if `k` isn't present in the container.
|`equal_range(k)` returns a range at the end of the container if `k` isn't present in the container. It can't return a positioned range as `k` could be inserted into multiple place. To find out the bucket that `k` would be inserted into use `bucket(k)`. But remember that an insert can cause the container to rehash - meaning that the element can be inserted into a different bucket.
|`iterator`, `const_iterator` are of the bidirectional category.
|`iterator`, `const_iterator` are of at least the forward category.
|Iterators, pointers and references to the container's elements are never invalidated.
|<<buckets_iterator_invalidation,Iterators can be invalidated by calls to insert or rehash>>. Pointers and references to the container's elements are never invalidated.
|Iterators iterate through the container in the order defined by the comparison object.
|Iterators iterate through the container in an arbitrary order, that can change as elements are inserted, although equivalent elements are always adjacent.
|No equivalent
|Local iterators can be used to iterate through individual buckets. (The order of local iterators and iterators aren't required to have any correspondence.)
|Can be compared using the `==`, `!=`, `<`, `\<=`, `>`, `>=` operators.
|Can be compared using the `==` and `!=` operators.
|
|When inserting with a hint, implementations are permitted to ignore the hint.
|`erase` never throws an exception
|The containers' hash or predicate function can throw exceptions from `erase`.
|===
---
[caption=, title='Table {counter:table-counter} Complexity Guarantees']
[cols="1,1,1", frame=all, grid=rows]
|===
|Operation |Associative Containers |Unordered Associative Containers
|Construction of empty container
|constant
|O(_n_) where _n_ is the minimum number of buckets.
|Construction of container from a range of _N_ elements
|O(_N log N_), O(_N_) if the range is sorted with `value_comp()`
|Average case O(_N_), worst case O(_N^2^_)
|Insert a single element
|logarithmic
|Average case constant, worst case linear
|Insert a single element with a hint
|Amortized constant if `t` elements inserted right after hint, logarithmic otherwise
|Average case constant, worst case linear (ie. the same as a normal insert).
|Inserting a range of _N_ elements
|_N_ log(`size()` + _N_)
|Average case O(_N_), worst case O(_N_ * `size()`)
|Erase by key, `k`
|O(log(`size()`) + `count(k)`)
|Average case: O(`count(k)`), Worst case: O(`size()`)
|Erase a single element by iterator
|Amortized constant
|Average case: O(1), Worst case: O(`size()`)
|Erase a range of _N_ elements
|O(log(`size()`) + _N_)
|Average case: O(_N_), Worst case: O(`size()`)
|Clearing the container
|O(`size()`)
|O(`size()`)
|Find
|logarithmic
|Average case: O(1), Worst case: O(`size()`)
|Count
|O(log(`size()`) + `count(k)`)
|Average case: O(1), Worst case: O(`size()`)
|`equal_range(k)`
|logarithmic
|Average case: O(`count(k)`), Worst case: O(`size()`)
|`lower_bound`,`upper_bound`
|logarithmic
|n/a
|===

View File

@ -1,25 +1,31 @@
[/ Copyright 2011 Daniel James.
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ]
[#compliance]
= Standard Compliance
[section:compliance C++11 Compliance]
:idprefix: compliance_
[section:move Move emulation]
:cpp: C++
The intent of Boost.Unordered is to implement a close (but imperfect)
implementation of the {cpp}17 standard, that will work with {cpp}98 upwards.
The wide compatibility does mean some comprimises have to be made.
With a compiler and library that fully support {cpp}11, the differences should
be minor.
== Move emulation
Support for move semantics is implemented using Boost.Move. If rvalue
references are available it will use them, but if not it uses a close,
but imperfect emulation. On such compilers you'll need to use Boost.Move
to take advantage of using movable container elements, also note that:
but imperfect emulation. On such compilers:
* Non-copyable objects can be stored in the containers, but without support
for rvalue references the container will not be movable.
* Non-copyable objects can be stored in the containers.
They can be constructed in place using `emplace`, or if they support
Boost.Move, moved into place.
* The containers themselves are not movable.
* Argument forwarding is not perfect.
[endsect]
== Use of allocators
[section:allocator_compliance Use of allocators]
C++11 introduced a new allocator system. It's backwards compatible due to
{cpp}11 introduced a new allocator system. It's backwards compatible due to
the lax requirements for allocators in the old standard, but might need
some changes for allocators which worked with the old versions of the
unordered containers.
@ -50,23 +56,27 @@ Due to imperfect move emulation, some assignments might check
`propagate_on_container_copy_assignment` on some compilers and
`propagate_on_container_move_assignment` on others.
The use of the allocator's construct and destruct methods might be a bit
surprising.
Nodes are constructed and destructed using the allocator, but the elements
are stored in aligned space within the node and constructed and destructed
by calling the constructor and destructor directly.
== Construction/Destruction using allocators
In C++11 the allocator's construct function has the signature:
The following support is required for full use of {cpp}11 style
construction/destruction:
template <class U, class... Args>
void construct(U* p, Args&&... args);
* Variadic templates.
* Piecewise construction of `std::pair`.
* Either `std::allocator_traits` or expression SFINAE.
which supports calling `construct` for the contained object, but
most existing allocators don't support this. If member function detection
was good enough then with old allocators it would fall back to calling
the element's constructor directly but in general, detection isn't good
enough to do this which is why Boost.Unordered just calls the constructor
directly every time. In most cases this will work okay.
This is detected using Boost.Config. The macro
`BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0
otherwise.
When this is the case `allocator_traits::construct` and
`allocator_traits::destroy` will always be used, apart from when piecewise
constructing a `std::pair` using `boost::tuple` (see <<compliance_pairs,below>>), but that should be easily avoided.
When support is not available `allocator_traits::construct` and
`allocator_traits::destroy` are never called.
== Pointer Traits
`pointer_traits` aren't used. Instead, pointer types are obtained from
rebound allocators, this can cause problems if the allocator can't be
@ -74,38 +84,33 @@ used with incomplete types. If `const_pointer` is not defined in the
allocator, `boost::pointer_to_other<pointer, const value_type>::type`
is used to obtain a const pointer.
[endsect]
[section:pairs Pairs]
== Pairs
Since the containers use `std::pair` they're limited to the version
from the current standard library. But since C++11 `std::pair`'s
from the current standard library. But since {cpp}11 ``std::pair``'s
`piecewise_construct` based constructor is very useful, `emplace`
emulates it with a `piecewise_construct` in the `boost::unordered`
namespace. So for example, the following will work:
boost::unordered_multimap<std::string, std::complex> x;
[source,c++]
----
boost::unordered_multimap<std::string, std::complex> x;
x.emplace(
boost::unordered::piecewise_construct,
boost::make_tuple("key"), boost::make_tuple(1, 2));
x.emplace(
boost::unordered::piecewise_construct,
boost::make_tuple("key"), boost::make_tuple(1, 2));
----
Older drafts of the standard also supported variadic constructors
for `std::pair`, where the first argument would be used for the
first part of the pair, and the remaining for the second part.
[endsect]
[section:misc Miscellaneous]
== Miscellaneous
When swapping, `Pred` and `Hash` are not currently swapped by calling
`swap`, their copy constructors are used. As a consequence when swapping
an exception may be throw from their copy constructor.
an exception may be thrown from their copy constructor.
Variadic constructor arguments for `emplace` are only used when both
rvalue references and variadic template parameters are available.
Otherwise `emplace` can only take up to 10 constructors arguments.
[endsect]
[endsect]

View File

@ -0,0 +1,14 @@
[#copyright]
= Copyright and License
:idprefix: copyright_
*Daniel James*
Copyright (C) 2003, 2004 Jeremy B. Maitin-Shepard
Copyright (C) 2005-2008 Daniel James
Copyright (C) 2022 Christian Mazakas
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@ -0,0 +1,149 @@
[#hash_equality]
:idprefix: hash_equality_
= Equality Predicates and Hash Functions
While the associative containers use an ordering relation to specify how the
elements are stored, the unordered associative containers use an equality
predicate and a hash function. For example, <<unordered_map,boost::unordered_map>>
is declared as:
```
template <
class Key, class Mapped,
class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class unordered_map;
```
The hash function comes first as you might want to change the hash function
but not the equality predicate. For example, if you wanted to use the
http://www.isthe.com/chongo/tech/comp/fnv/[FNV-1 hash^] you could write:
```
boost::unordered_map<std::string, int, hash::fnv_1>
dictionary;
```
There is an link:../../examples/fnv1.hpp[implementation of FNV-1^] in the examples directory.
If you wish to use a different equality function, you will also need to use a matching hash function. For example, to implement a case insensitive dictionary you need to define a case insensitive equality predicate and hash function:
```
struct iequal_to
{
bool operator()(std::string const& x,
std::string const& y) const
{
return boost::algorithm::iequals(x, y, std::locale());
}
};
struct ihash
{
std::size_t operator()(std::string const& x) const
{
std::size_t seed = 0;
std::locale locale;
for(std::string::const_iterator it = x.begin();
it != x.end(); ++it)
{
boost::hash_combine(seed, std::toupper(*it, locale));
}
return seed;
}
};
```
Which you can then use in a case insensitive dictionary:
```
boost::unordered_map<std::string, int, ihash, iequal_to>
idictionary;
```
This is a simplified version of the example at
link:../../examples/case_insensitive.hpp[/libs/unordered/examples/case_insensitive.hpp^] which supports other locales and string types.
CAUTION: Be careful when using the equality (`==`) operator with custom equality
predicates, especially if you're using a function pointer. If you compare two
containers with different equality predicates then the result is undefined.
For most stateless function objects this is impossible - since you can only
compare objects with the same equality predicate you know the equality
predicates must be equal. But if you're using function pointers or a stateful
equality predicate (e.g. `boost::function`) then you can get into trouble.
== Custom Types
Similarly, a custom hash function can be used for custom types:
```
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
struct point_hash
{
std::size_t operator()(point const& p) const
{
std::size_t seed = 0;
boost::hash_combine(seed, p.x);
boost::hash_combine(seed, p.y);
return seed;
}
};
boost::unordered_multiset<point, point_hash> points;
```
Since the default hash function is link:../../../container_hash/index.html[Boost.Hash^],
we can extend it to support the type so that the hash function doesn't need to be explicitly given:
```
struct point {
int x;
int y;
};
bool operator==(point const& p1, point const& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
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;
}
// Now the default function objects work.
boost::unordered_multiset<point> points;
```
See the link:../../../container_hash/index.html[Boost.Hash documentation^] for more detail on how to
do this. Remember that it relies on extensions to the standard - so it
won't work for other implementations of the unordered associative containers,
you'll need to explicitly use Boost.Hash.
[caption=, title='Table {counter:table-counter} Methods for accessing the hash and equality functions']
[cols="1,.^1", frame=all, grid=rows]
|===
|Method |Description
|`hasher hash_function() const`
|Returns the container's hash function.
|`key_equal key_eq() const`
|Returns the container's key equality function..
|===

116
doc/unordered/intro.adoc Normal file
View File

@ -0,0 +1,116 @@
[#intro]
= Introduction
:idprefix: intro_
:cpp: C++
For accessing data based on key lookup, the {cpp} standard library offers `std::set`,
`std::map`, `std::multiset` and `std::multimap`. These are generally
implemented using balanced binary trees so that lookup time has
logarithmic complexity. That is generally okay, but in many cases a
link:https://en.wikipedia.org/wiki/Hash_table[hash table^] can perform better, as accessing data has constant complexity,
on average. The worst case complexity is linear, but that occurs rarely and
with some care, can be avoided.
Also, the existing containers require a 'less than' comparison object
to order their elements. For some data types this is impossible to implement
or isn't practical. In contrast, a hash table only needs an equality function
and a hash function for the key.
With this in mind, unordered associative containers were added to the {cpp}
standard. This is an implementation of the containers described in {cpp}11,
with some <<compliance,deviations from the standard>> in
order to work with non-{cpp}11 compilers and libraries.
`unordered_set` and `unordered_multiset` are defined in the header
`<boost/unordered_set.hpp>`
[source,c++]
----
namespace boost {
template <
class Key,
class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class unordered_set;
template<
class Key,
class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class unordered_multiset;
}
----
`unordered_map` and `unordered_multimap` are defined in the header
`<boost/unordered_map.hpp>`
[source,c++]
----
namespace boost {
template <
class Key, class Mapped,
class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class unordered_map;
template<
class Key, class Mapped,
class Hash = boost::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class unordered_multimap;
}
----
When using Boost.TR1, these classes are included from `<unordered_set>` and
`<unordered_map>`, with the classes added to the `std::tr1` namespace.
The containers are used in a similar manner to the normal associative
containers:
[source,cpp]
----
typedef boost::unordered_map<std::string, int> map;
map x;
x["one"] = 1;
x["two"] = 2;
x["three"] = 3;
assert(x.at("one") == 1);
assert(x.find("missing") == x.end());
----
But since the elements aren't ordered, the output of:
[source,c++]
----
BOOST_FOREACH(map::value_type i, x) {
std::cout<<i.first<<","<<i.second<<"\n";
}
----
can be in any order. For example, it might be:
[source]
----
two,2
one,1
three,3
----
To store an object in an unordered associative container requires both a
key equality function and a hash function. The default function objects in
the standard containers support a few basic types including integer types,
floating point types, pointer types, and the standard strings. Since
Boost.Unordered uses link:../../../container_hash/index.html[boost::hash^] it also supports some other types,
including standard containers. To use any types not supported by these methods
you have to extend Boost.Hash to support the type or use
your own custom equality predicates and hash functions. See the
<<hash_equality,Equality Predicates and Hash Functions>> section
for more details.
There are other differences, which are listed in the
<<comparison,Comparison with Associative Containers>> section.

View File

@ -0,0 +1,72 @@
[#rationale]
:idprefix: rationale_
= Implementation Rationale
The intent of this library is to implement the unordered
containers in the standard, so the interface was fixed. But there are
still some implementation decisions to make. The priorities are
conformance to the standard and portability.
The http://en.wikipedia.org/wiki/Hash_table[Wikipedia article on hash tables^]
has a good summary of the implementation issues for hash tables in general.
== Data Structure
By specifying an interface for accessing the buckets of the container the
standard pretty much requires that the hash table uses chained addressing.
It would be conceivable to write a hash table that uses another method. For
example, it could use open addressing, and use the lookup chain to act as a
bucket but there are some serious problems with this:
* The standard requires that pointers to elements aren't invalidated, so
the elements can't be stored in one array, but will need a layer of
indirection instead - losing the efficiency and most of the memory gain,
the main advantages of open addressing.
* Local iterators would be very inefficient and may not be able to
meet the complexity requirements.
* There are also the restrictions on when iterators can be invalidated. Since
open addressing degrades badly when there are a high number of collisions the
restrictions could prevent a rehash when it's really needed. The maximum load
factor could be set to a fairly low value to work around this - but the
standard requires that it is initially set to 1.0.
* And since the standard is written with a eye towards chained
addressing, users will be surprised if the performance doesn't reflect that.
So chained addressing is used.
== Number of Buckets
There are two popular methods for choosing the number of buckets in a hash
table. One is to have a prime number of buckets, another is to use a power
of 2.
Using a prime number of buckets, and choosing a bucket by using the modulus
of the hash function's result will usually give a good result. The downside
is that the required modulus operation is fairly expensive. This is what the
containers used to do in most cases.
Using a power of 2 allows for much quicker selection of the bucket to use,
but at the expense of losing the upper bits of the hash value. For some
specially designed hash functions it is possible to do this and still get a
good result but as the containers can take arbitrary hash functions this can't
be relied on.
To avoid this a transformation could be applied to the hash function, for an
example see
http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm[Thomas Wang's article on integer hash functions^].
Unfortunately, a transformation like Wang's requires knowledge of the number
of bits in the hash value, so it was only used when `size_t` was 64 bit.
Since release 1.79.0, https://en.wikipedia.org/wiki/Hash_function#Fibonacci_hashing[Fibonacci hashing]
is used instead. With this implementation, the bucket number is determined
by using `(h * m) >> (w - k)`, where `h` is the hash value, `m` is the golden
ratio multiplied by `2^w`, `w` is the word size (32 or 64), and `2^k` is the
number of buckets. This provides a good compromise between speed and
distribution.
Since release 1.80.0, prime numbers are chosen for the number of buckets in
tandem with sophisticated modulo arithmetic. This removes the need for "mixing"
the result of the user's hash function as was used for release 1.79.0.

7
doc/unordered/ref.adoc Normal file
View File

@ -0,0 +1,7 @@
[#reference]
= Reference
include::unordered_map.adoc[]
include::unordered_multimap.adoc[]
include::unordered_set.adoc[]
include::unordered_multiset.adoc[]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@
namespace hash_examples
{
struct iequal_to
: std::binary_function<std::string, std::string, bool>
{
iequal_to() {}
explicit iequal_to(std::locale const& l) : locale_(l) {}
@ -34,7 +33,6 @@ namespace hash_examples
};
struct ihash
: std::unary_function<std::string, std::size_t>
{
ihash() {}
explicit ihash(std::locale const& l) : locale_(l) {}

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