From 106f92f586a5b91295321cc2e4970f98c6e3108c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:16:22 +0000 Subject: [PATCH 01/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/nav_zh_Hans.adoc | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 doc/modules/ROOT/nav_zh_Hans.adoc diff --git a/doc/modules/ROOT/nav_zh_Hans.adoc b/doc/modules/ROOT/nav_zh_Hans.adoc new file mode 100644 index 0000000..7143f6a --- /dev/null +++ b/doc/modules/ROOT/nav_zh_Hans.adoc @@ -0,0 +1,51 @@ +* xref:intro.adoc[] +* xref:buckets.adoc[] +* xref:hash_equality.adoc[] +* xref:regular.adoc[] +* xref:concurrent.adoc[] +* xref:hash_quality.adoc[] +* xref:compliance.adoc[] +* xref:structures.adoc[] +* xref:debuggability.adoc[] +* xref:benchmarks.adoc[] +* xref:rationale.adoc[] +* xref:ref.adoc[] +** xref:reference/header_unordered_map_fwd.adoc[``] +** xref:reference/header_unordered_map_top.adoc[``] +** xref:reference/header_unordered_map.adoc[``] +** xref:reference/unordered_map.adoc[`unordered_map`] +** xref:reference/unordered_multimap.adoc[`unordered_multimap`] +** xref:reference/header_unordered_set_fwd.adoc[``] +** xref:reference/header_unordered_set_top.adoc[``] +** xref:reference/header_unordered_set.adoc[``] +** xref:reference/unordered_set.adoc[`unordered_set`] +** xref:reference/unordered_multiset.adoc[`unordered_multiset`] +** xref:reference/hash_traits.adoc[Hash Traits] +** xref:reference/stats.adoc[Statistics] +** xref:reference/header_unordered_flat_map_fwd.adoc[``] +** xref:reference/header_unordered_flat_map.adoc[``] +** xref:reference/unordered_flat_map.adoc[`unordered_flat_map`] +** xref:reference/header_unordered_flat_set_fwd.adoc[``] +** xref:reference/header_unordered_flat_set.adoc[``] +** xref:reference/unordered_flat_set.adoc[`unordered_flat_set`] +** xref:reference/header_unordered_node_map_fwd.adoc[``] +** xref:reference/header_unordered_node_map.adoc[``] +** xref:reference/unordered_node_map.adoc[`unordered_node_map`] +** xref:reference/header_unordered_node_set_fwd.adoc[``] +** xref:reference/header_unordered_node_set.adoc[``] +** xref:reference/unordered_node_set.adoc[`unordered_node_set`] +** xref:reference/header_concurrent_flat_map_fwd.adoc[``] +** xref:reference/header_concurrent_flat_map.adoc[``] +** xref:reference/concurrent_flat_map.adoc[`concurrent_flat_map`] +** xref:reference/header_concurrent_flat_set_fwd.adoc[``] +** xref:reference/header_concurrent_flat_set.adoc[``] +** xref:reference/concurrent_flat_set.adoc[`concurrent_flat_set`] +** xref:reference/header_concurrent_node_map_fwd.adoc[``] +** xref:reference/header_concurrent_node_map.adoc[``] +** xref:reference/concurrent_node_map.adoc[`concurrent_node_map`] +** xref:reference/header_concurrent_node_set_fwd.adoc[``] +** xref:reference/header_concurrent_node_set.adoc[``] +** xref:reference/concurrent_node_set.adoc[`concurrent_node_set`] +* xref:changes.adoc[] +* xref:bibliography.adoc[] +* xref:copyright.adoc[] From b091420b30aba66c9d340edb1ab146c317a6dbe8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:16:43 +0000 Subject: [PATCH 02/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/structures_zh_Hans.adoc | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 doc/modules/ROOT/pages/structures_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/structures_zh_Hans.adoc b/doc/modules/ROOT/pages/structures_zh_Hans.adoc new file mode 100644 index 0000000..7cb0bff --- /dev/null +++ b/doc/modules/ROOT/pages/structures_zh_Hans.adoc @@ -0,0 +1,109 @@ +[#structures] = Data Structures + +:idprefix: structures_ + +== Closed-addressing Containers + +++++ + +++++ + +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=_images/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. + +A more detailed description of Boost.Unordered's closed-addressing implementation is given in an https://bannalia.blogspot.com/2022/06/advancing-state-of-art-for.html[external article]. For more information on implementation rationale, read the xref:rationale.adoc#rationale_closed_addressing_containers[corresponding section]. + +== Open-addressing Containers + +The diagram shows the basic internal layout of `boost::unordered_flat_set`/`unordered_node_set` and `boost:unordered_flat_map`/`unordered_node_map`. + + +[#img-foa-layout] +.Open-addressing layout used by Boost.Unordered. +image::foa.png[align=center] + +As with all open-addressing containers, elements (or pointers to the element nodes in the case of `boost::unordered_node_set` and `boost::unordered_node_map`) are stored directly in the bucket array. This array is logically divided into 2^_n_^ _groups_ of 15 elements each. In addition to the bucket array, there is an associated _metadata array_ with 2^_n_^ 16-byte words. + +[#img-foa-metadata] +.Breakdown of a metadata word. +image::foa-metadata.png[align=center] + +A metadata word is divided into 15 _h_~_i_~ bytes (one for each associated bucket), and an _overflow byte_ (_ofw_ in the diagram). The value of _h_~_i_~ is: + +- 0 if the corresponding bucket is empty. - 1 to encode a special empty bucket called a _sentinel_, which is used internally to stop iteration when the container has been fully traversed. - If the bucket is occupied, a _reduced hash value_ obtained from the hash value of the element. + +When looking for an element with hash value _h_, SIMD technologies such as https://en.wikipedia.org/wiki/SSE2[SSE2] and https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(Neon)[Neon] allow us to very quickly inspect the full metadata word and look for the reduced value of _h_ among all the 15 buckets with just a handful of CPU instructions: non-matching buckets can be readily discarded, and those whose reduced hash value matches need be inspected via full comparison with the corresponding element. If the looked-for element is not present, the overflow byte is inspected: + +- If the bit in the position _h_ mod 8 is zero, lookup terminates (and the element is not present). - If the bit is set to 1 (the group has been _overflowed_), further groups are checked using https://en.wikipedia.org/wiki/Quadratic_probing[_quadratic probing_], and the process is repeated. + +Insertion is algorithmically similar: empty buckets are located using SIMD, and when going past a full group its corresponding overflow bit is set to 1. + +In architectures without SIMD support, the logical layout stays the same, but the metadata word is codified using a technique we call _bit interleaving_: this layout allows us to emulate SIMD with reasonably good performance using only standard arithmetic and logical operations. + +[#img-foa-metadata-interleaving] +.Bit-interleaved metadata word. +image::foa-metadata-interleaving.png[align=center] + +A more detailed description of Boost.Unordered's open-addressing implementation is given in an https://bannalia.blogspot.com/2022/11/inside-boostunorderedflatmap.html[external article]. For more information on implementation rationale, read the xref:rationale.adoc#rationale_open_addresing_containers[corresponding section]. + +== Concurrent Containers + +`boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map` use the basic xref:structures.adoc#structures_open_addressing_containers[open-addressing layout] described above augmented with synchronization mechanisms. + + +[#img-cfoa-layout] +.Concurrent open-addressing layout used by Boost.Unordered. +image::cfoa.png[align=center] + +Two levels of synchronization are used: + +* Container level: A read-write mutex is used to control access from any operation +to the container. Typically, such access is in read mode (that is, concurrent) even for modifying operations, so for most practical purposes there is no thread contention at this level. Access is only in write mode (blocking) when rehashing or performing container-wide operations such as swapping or assignment. +* Group level: Each 15-slot group is equipped with an 8-byte word containing: +** A read-write spinlock for synchronized access to any element in the group. ** An atomic _insertion counter_ used for optimistic insertion as described below. + +By using atomic operations to access the group metadata, lookup is (group-level) lock-free up to the point where an actual comparison needs to be done with an element that has been previously SIMD-matched: only then is the group's spinlock used. + +Insertion uses the following _optimistic algorithm_: + +* The value of the insertion counter for the initial group in the probe +sequence is locally recorded (let's call this value `c0`). +* Lookup is as described above. If lookup finds no equivalent element, +search for an available slot for insertion successively locks/unlocks each group in the probing sequence. +* When an available slot is located, it is preemptively occupied (its +reduced hash value is set) and the insertion counter is atomically incremented: if no other thread has incremented the counter during the whole operation (which is checked by comparing with `c0`), then we're good to go and complete the insertion, otherwise we roll back and start over. + +This algorithm has very low contention both at the lookup and actual insertion phases in exchange for the possibility that computations have to be started over if some other thread interferes in the process by performing a succesful insertion beginning at the same group. In practice, the start-over frequency is extremely small, measured in the range of parts per million for some of our benchmarks. + +For more information on implementation rationale, read the xref:rationale.adoc#rationale_concurrent_containers[corresponding section]. From ae0c043c2d0ded5537370fc35fe26fbd3248437a Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:16:59 +0000 Subject: [PATCH 03/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/regular_zh_Hans.adoc | 165 ++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 doc/modules/ROOT/pages/regular_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/regular_zh_Hans.adoc b/doc/modules/ROOT/pages/regular_zh_Hans.adoc new file mode 100644 index 0000000..f17b37a --- /dev/null +++ b/doc/modules/ROOT/pages/regular_zh_Hans.adoc @@ -0,0 +1,165 @@ +[#regular] = Regular Containers + +:idprefix: regular_ + +Boost.Unordered closed-addressing containers (`boost::unordered_set`, `boost::unordered_map`, `boost::unordered_multiset` and `boost::unordered_multimap`) are fully conformant with the C++ specification for unordered associative containers, so for those who know how to use `std::unordered_set`, `std::unordered_map`, etc., their homonyms in Boost.Unordered are drop-in replacements. The interface of open-addressing containers (`boost::unordered_node_set`, `boost::unordered_node_map`, `boost::unordered_flat_set` and `boost::unordered_flat_map`) is very similar, but they present some minor differences listed in the dedicated xref:compliance.adoc#compliance_open_addressing_containers[standard compliance section]. + + +For readers without previous experience with hash containers but familiar with normal associative containers (`std::set`, `std::map`, `std::multiset` and `std::multimap`), Boost.Unordered containers are used in a similar manner: + +[source,cpp] +---- +typedef boost::unordered_map 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++] +---- +for(const map::value_type& i: x) { + std::cout<`, `>=` operators. +|Can be compared using the `==` and `!=` operators. + +| +|When inserting with a hint, implementations are permitted to ignore the hint. + +|=== + +--- + +[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 + +|=== From b8be3bdf8b5394a3f1fa4d5efbeea46af3710dbf Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:17:00 +0000 Subject: [PATCH 04/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Structures (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-structures-adoc/ --- doc/modules/ROOT/pages/structures_zh_Hans.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/modules/ROOT/pages/structures_zh_Hans.adoc b/doc/modules/ROOT/pages/structures_zh_Hans.adoc index 7cb0bff..dba552d 100644 --- a/doc/modules/ROOT/pages/structures_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/structures_zh_Hans.adoc @@ -91,19 +91,19 @@ Two levels of synchronization are used: * Container level: A read-write mutex is used to control access from any operation to the container. Typically, such access is in read mode (that is, concurrent) even for modifying operations, so for most practical purposes there is no thread contention at this level. Access is only in write mode (blocking) when rehashing or performing container-wide operations such as swapping or assignment. * Group level: Each 15-slot group is equipped with an 8-byte word containing: -** A read-write spinlock for synchronized access to any element in the group. ** An atomic _insertion counter_ used for optimistic insertion as described below. - By using atomic operations to access the group metadata, lookup is (group-level) lock-free up to the point where an actual comparison needs to be done with an element that has been previously SIMD-matched: only then is the group's spinlock used. Insertion uses the following _optimistic algorithm_: -* The value of the insertion counter for the initial group in the probe sequence is locally recorded (let's call this value `c0`). -* Lookup is as described above. If lookup finds no equivalent element, + +* A read-write spinlock for synchronized access to any element in the group. ** An atomic _insertion counter_ used for optimistic insertion as described below. search for an available slot for insertion successively locks/unlocks each group in the probing sequence. -* When an available slot is located, it is preemptively occupied (its +* The value of the insertion counter for the initial group in the probe reduced hash value is set) and the insertion counter is atomically incremented: if no other thread has incremented the counter during the whole operation (which is checked by comparing with `c0`), then we're good to go and complete the insertion, otherwise we roll back and start over. - +* Lookup is as described above. If lookup finds no equivalent element, This algorithm has very low contention both at the lookup and actual insertion phases in exchange for the possibility that computations have to be started over if some other thread interferes in the process by performing a succesful insertion beginning at the same group. In practice, the start-over frequency is extremely small, measured in the range of parts per million for some of our benchmarks. For more information on implementation rationale, read the xref:rationale.adoc#rationale_concurrent_containers[corresponding section]. + +For more information on implementation rationale, read the xref:rationale.adoc#rationale_concurrent_containers[corresponding section]. From 4990670d8434fbef022f59192b900db1e1d27c71 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:04 +0000 Subject: [PATCH 05/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/ref_zh_Hans.adoc | 39 +++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 doc/modules/ROOT/pages/ref_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/ref_zh_Hans.adoc b/doc/modules/ROOT/pages/ref_zh_Hans.adoc new file mode 100644 index 0000000..36976a2 --- /dev/null +++ b/doc/modules/ROOT/pages/ref_zh_Hans.adoc @@ -0,0 +1,39 @@ +[#reference] += Reference + +* xref:reference/header_unordered_map_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_map_top.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_map.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_map.adoc[Class Template ++++++unordered_map++++++] +* xref:reference/unordered_multimap.adoc[Class Template ++++++unordered_multimap++++++] +* xref:reference/header_unordered_set_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_set_top.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_set.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_set.adoc[Class Template ++++++unordered_set++++++] +* xref:reference/unordered_multiset.adoc[Class Template ++++++unordered_multiset++++++] +* xref:reference/hash_traits.adoc[Hash Traits] +* xref:reference/stats.adoc[Statistics] +* xref:reference/header_unordered_flat_map_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_flat_map.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_flat_map.adoc[Class Template ++++++unordered_flat_map++++++] +* xref:reference/header_unordered_flat_set_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_flat_set.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_flat_set.adoc[Class Template ++++++unordered_flat_set++++++] +* xref:reference/header_unordered_node_map_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_node_map.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_node_map.adoc[Class Template ++++++unordered_node_map++++++] +* xref:reference/header_unordered_node_set_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_unordered_node_set.adoc[++++++++++++ Synopsis] +* xref:reference/unordered_node_set.adoc[Class Template ++++++unordered_node_set++++++] +* xref:reference/header_concurrent_flat_map_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_concurrent_flat_map.adoc[++++++++++++ Synopsis] +* xref:reference/concurrent_flat_map.adoc[Class Template ++++++concurrent_flat_map++++++] +* xref:reference/header_concurrent_flat_set_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_concurrent_flat_set.adoc[++++++++++++ Synopsis] +* xref:reference/concurrent_flat_set.adoc[Class Template ++++++concurrent_flat_set++++++] +* xref:reference/header_concurrent_node_map_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_concurrent_node_map.adoc[++++++++++++ Synopsis] +* xref:reference/concurrent_node_map.adoc[Class Template ++++++concurrent_node_map++++++] +* xref:reference/header_concurrent_node_set_fwd.adoc[++++++++++++ Synopsis] +* xref:reference/header_concurrent_node_set.adoc[++++++++++++ Synopsis] +* xref:reference/concurrent_node_set.adoc[Class Template ++++++concurrent_node_set++++++] From 91ff11ad64db7519067979dcb4ec8cffea40260d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:19 +0000 Subject: [PATCH 06/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/rationale_zh_Hans.adoc | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 doc/modules/ROOT/pages/rationale_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/rationale_zh_Hans.adoc b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc new file mode 100644 index 0000000..db2db06 --- /dev/null +++ b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc @@ -0,0 +1,79 @@ +[#rationale] + +:idprefix: rationale_ + += Implementation Rationale + +== Closed-addressing Containers + +`boost::unordered_[multi]set` and `boost::unordered_[multi]map` adhere to the standard requirements for unordered associative containers, 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 closed 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 closed +addressing, users will be surprised if the performance doesn't reflect that. + +So closed 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 `2^w` divided by the golden ratio, `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. + +== Open-addresing Containers + +The C++ standard specification of unordered associative containers impose severe limitations on permissible implementations, the most important being that closed addressing is implicitly assumed. Slightly relaxing this specification opens up the possibility of providing container variations taking full advantage of open-addressing techniques. + +The design of `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` has been guided by Peter Dimov's https://pdimov.github.io/articles/unordered_dev_plan.html[Development Plan for Boost.Unordered^]. We discuss here the most relevant principles. + +=== Hash Function + +Given its rich functionality and cross-platform interoperability, `boost::hash` remains the default hash function of open-addressing containers. As it happens, `boost::hash` for integral and other basic types does not possess the statistical properties required by open addressing; to cope with this, we implement a post-mixing stage: + +{nbsp}{nbsp}{nbsp}{nbsp} _a_ <- _h_ *mul* _C_, + {nbsp}{nbsp}{nbsp}{nbsp} _h_ <- *high*(_a_) *xor* *low*(_a_), + +where *mul* is an _extended multiplication_ (128 bits in 64-bit architectures, 64 bits in 32-bit environments), and *high* and *low* are the upper and lower halves of an extended word, respectively. In 64-bit architectures, _C_ is the integer part of 2^64^∕https://en.wikipedia.org/wiki/Golden_ratio[_φ_], whereas in 32 bits _C_ = 0xE817FB2Du has been obtained from https://arxiv.org/abs/2001.05304[Steele and Vigna (2021)^]. + +When using a hash function directly suitable for open addressing, post-mixing can be opted out of via a dedicated `link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]` trait. `boost::hash` specializations for string types are marked as avalanching. + +=== Platform Interoperability + +The observable behavior of `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` is deterministically identical across different compilers as long as their ``std::size_t``s are the same size and the user-provided hash function and equality predicate are also interoperable —this includes elements being ordered in exactly the same way for the same sequence of operations. + +Although the implementation internally uses SIMD technologies, such as https://en.wikipedia.org/wiki/SSE2[SSE2^] and https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(NEON)[Neon^], when available, this does not affect interoperatility. For instance, the behavior is the same for Visual Studio on an x64-mode Intel CPU with SSE2 and for GCC on an IBM s390x without any supported SIMD technology. + +== Concurrent Containers + +The same data structure used by Boost.Unordered open-addressing containers has been chosen also as the foundation of `boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map`: + +* Open-addressing is faster than closed-addressing alternatives, both in non-concurrent and +concurrent scenarios. +* Open-addressing layouts are eminently suitable for concurrent access and modification +with minimal locking. In particular, the metadata array can be used for implementations of lookup that are lock-free up to the last step of actual element comparison. +* Layout compatibility with Boost.Unordered flat containers allows for +xref:concurrent.adoc#concurrent_interoperability_with_non_concurrent_containers[fast transfer] of all elements between a concurrent container and its non-concurrent counterpart, and vice versa. + +=== Hash Function and Platform Interoperability + +Concurrent containers make the same decisions and provide the same guarantees as Boost.Unordered open-addressing containers with regards to xref:#rationale_hash_function[hash function defaults] and xref:#rationale_platform_interoperability[platform interoperability]. From 74528b2e636d091069a01217403bba5ecd2c0bf3 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:30 +0000 Subject: [PATCH 07/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/intro_zh_Hans.adoc | 57 +++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 doc/modules/ROOT/pages/intro_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/intro_zh_Hans.adoc b/doc/modules/ROOT/pages/intro_zh_Hans.adoc new file mode 100644 index 0000000..2eb3215 --- /dev/null +++ b/doc/modules/ROOT/pages/intro_zh_Hans.adoc @@ -0,0 +1,57 @@ +[#intro] += Introduction + +:idprefix: intro_ :cpp: C++ + +link:https://en.wikipedia.org/wiki/Hash_table[Hash tables^] are extremely popular computer data structures and can be found under one form or another in virtually any programming language. Whereas other associative structures such as rb-trees (used in {cpp} by `std::set` and `std::map`) have logarithmic-time complexity for insertion and lookup, hash tables, if configured properly, perform these operations in constant time on average, and are generally much faster. + +{cpp} introduced __unordered associative containers__ `std::unordered_set`, `std::unordered_map`, `std::unordered_multiset` and `std::unordered_multimap` in {cpp}11, but research on hash tables hasn't stopped since: advances in CPU architectures such as more powerful caches, link:https://en.wikipedia.org/wiki/Single_instruction,_multiple_data[SIMD] operations and increasingly available link:https://en.wikipedia.org/wiki/Multi-core_processor[multicore processors] open up possibilities for improved hash-based data structures and new use cases that are simply beyond reach of unordered associative containers as specified in 2011. + +Boost.Unordered offers a catalog of hash containers with different standards compliance levels, performances and intented usage scenarios: + +[caption=, title='Table {counter:table-counter}. Boost.Unordered containers'] +[cols="1,1,.^1", frame=all, grid=all] +|=== +^h| ^h|*Node-based* ^h|*Flat* + +^.^h|*Closed addressing* ^m| boost::unordered_set + boost::unordered_map + boost::unordered_multiset + boost::unordered_multimap ^| + +^.^h|*Open addressing* ^m| boost::unordered_node_set + boost::unordered_node_map ^m| boost::unordered_flat_set + boost::unordered_flat_map + +^.^h|*Concurrent* ^| `boost::concurrent_node_set` + `boost::concurrent_node_map` ^| `boost::concurrent_flat_set` + `boost::concurrent_flat_map` + +|=== + +* **Closed-addressing containers** are fully compliant with the C++ specification +for unordered associative containers and feature one of the fastest implementations in the market within the technical constraints imposed by the required standard interface. +* **Open-addressing containers** rely on much faster data structures and algorithms +(more than 2 times faster in typical scenarios) while slightly diverging from the standard interface to accommodate the implementation. There are two variants: **flat** (the fastest) and **node-based**, which provide pointer stability under rehashing at the expense of being slower. +* Finally, **concurrent containers** are designed and implemented to be used in high-performance +multithreaded scenarios. Their interface is radically different from that of regular C++ containers. Flat and node-based variants are provided. + +All sets and maps in Boost.Unordered are instantiatied similarly as `std::unordered_set` and `std::unordered_map`, respectively: + +[source,c++] +---- +namespace boost { + template < + class Key, + class Hash = boost::hash, + class Pred = std::equal_to, + class Alloc = std::allocator > + class unordered_set; + // same for unordered_multiset, unordered_flat_set, unordered_node_set, + // concurrent_flat_set and concurrent_node_set + + template < + class Key, class Mapped, + class Hash = boost::hash, + class Pred = std::equal_to, + class Alloc = std::allocator > > + class unordered_map; + // same for unordered_multimap, unordered_flat_map, unordered_node_map, + // concurrent_flat_map and concurrent_node_map +} +---- + +Storing 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 xref:hash_equality.adoc#hash_equality[Equality Predicates and Hash Functions], section for more details. From 084156550cddd78b1ff70f0de1353cfa0283829a Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:34 +0000 Subject: [PATCH 08/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/hash_quality_zh_Hans.adoc | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc new file mode 100644 index 0000000..3e6efee --- /dev/null +++ b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc @@ -0,0 +1,114 @@ +[#hash_quality] = Hash Quality + +:idprefix: hash_quality_ + +In order to work properly, hash tables require that the supplied hash function be of __good quality__, roughly meaning that it uses its `std::size_t` output space as uniformly as possible, much like a random number generator would do —except, of course, that the value of a hash function is not random but strictly determined by its input argument. + +Closed-addressing containers in Boost.Unordered are fairly robust against hash functions with less-than-ideal quality, but open-addressing and concurrent containers are much more sensitive to this factor, and their performance can degrade dramatically if the hash function is not appropriate. In general, if you're using functions provided by or generated with link:../../../../container_hash/index.html[Boost.Hash^], the quality will be adequate, but you have to be careful when using alternative hash algorithms. + +The rest of this section applies only to open-addressing and concurrent containers. + +== Hash Post-mixing and the Avalanching Property + +Even if your supplied hash function does not conform to the uniform behavior required by open addressing, chances are that the performance of Boost.Unordered containers will be acceptable, because the library executes an internal __post-mixing__ step that improves the statistical properties of the calculated hash values. This comes with an extra computational cost; if you'd like to opt out of post-mixing, annotate your hash function as follows: + +[source,c++] +---- +struct my_string_hash_function +{ + using is_avalanching = std::true_type; // instruct Boost.Unordered to not use post-mixing + + std::size_t operator()(const std::string& x) const + { + ... + } +}; +---- + +By setting the `link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]` trait, we inform Boost.Unordered that `my_string_hash_function` is of sufficient quality to be used directly without any post-mixing safety net. This comes at the risk of degraded performance in the cases where the hash function is not as well-behaved as we've declared. + +== Container Statistics + +If we globally define the macro `BOOST_UNORDERED_ENABLE_STATS`, open-addressing and concurrent containers will calculate some internal statistics directly correlated to the quality of the hash function: + +[source,c++] +---- +#define BOOST_UNORDERED_ENABLE_STATS +#include + +... + +int main() +{ + boost::unordered_flat_map m; + ... // use m + + auto stats = m.get_stats(); + ... // inspect stats +} +---- + +The `stats` object provides the following information: + +[source,subs=+quotes] +---- +stats + .insertion // *Insertion operations* + .count // Number of operations + .probe_length // Probe length per operation + .average + .variance + .deviation + .successful_lookup // *Lookup operations (element found)* + .count // Number of operations + .probe_length // Probe length per operation + .average + .variance + .deviation + .num_comparisons // Elements compared per operation + .average + .variance + .deviation + .unsuccessful_lookup // *Lookup operations (element not found)* + .count // Number of operations + .probe_length // Probe length per operation + .average + .variance + .deviation + .num_comparisons // Elements compared per operation + .average + .variance + .deviation +---- + +Statistics for three internal operations are maintained: insertions (without considering the previous lookup to determine that the key is not present yet), successful lookups, and unsuccessful lookups (including those issued internally when inserting elements). _Probe length_ is the number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed per operation. If the hash function behaves properly: + +* Average probe lengths should be close to 1.0. +* The average number of comparisons per successful lookup should be close to 1.0 (that is, +just the element found is checked). +* The average number of comparisons per unsuccessful lookup should be close to 0.0. + +An link:../../../benchmark/string_stats.cpp[example^] is provided that displays container statistics for `boost::hash`, an implementation of the https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a hash^] and two ill-behaved custom hash functions that have been incorrectly marked as avalanching: + +[listing] +---- + boost::unordered_flat_map: 319 ms + insertion: probe length 1.08771 + successful lookup: probe length 1.06206, num comparisons 1.02121 + unsuccessful lookup: probe length 1.12301, num comparisons 0.0388251 + + boost::unordered_flat_map, FNV-1a: 301 ms + insertion: probe length 1.09567 + successful lookup: probe length 1.06202, num comparisons 1.0227 + unsuccessful lookup: probe length 1.12195, num comparisons 0.040527 + +boost::unordered_flat_map, slightly_bad_hash: 654 ms + insertion: probe length 1.03443 + successful lookup: probe length 1.04137, num comparisons 6.22152 + unsuccessful lookup: probe length 1.29334, num comparisons 11.0335 + + boost::unordered_flat_map, bad_hash: 12216 ms + insertion: probe length 699.218 + successful lookup: probe length 590.183, num comparisons 43.4886 + unsuccessful lookup: probe length 1361.65, num comparisons 75.238 +---- From 284da822b4dd4a233f5ac14b53513ff3e90a7ac7 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:48 +0000 Subject: [PATCH 09/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/hash_equality_zh_Hans.adoc | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc new file mode 100644 index 0000000..4835af9 --- /dev/null +++ b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc @@ -0,0 +1,70 @@ +[#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, `xref:reference/unordered_map.adoc[boost::unordered_map]` is declared as: + +```cpp template < class Key, class Mapped, class Hash = boost::hash, class Pred = std::equal_to, class Alloc = std::allocator > > 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 https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a hash^] you could write: + +```cpp boost::unordered_map dictionary; ``` + +There is an link:../../../examples/fnv1.hpp[implementation of FNV-1a^] 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: + +```cpp 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: ```cpp boost::unordered_map 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: + +```cpp 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 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: + +```cpp 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 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.. + +|=== From ff780c4124130c51bc6261a6c2ce99ed9b58cf83 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:55 +0000 Subject: [PATCH 10/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/debuggability_zh_Hans.adoc | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 doc/modules/ROOT/pages/debuggability_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc new file mode 100644 index 0000000..e02366a --- /dev/null +++ b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc @@ -0,0 +1,64 @@ +[#debuggability] +:idprefix: debuggability_ + += Debuggability + +== Visual Studio Natvis + +All containers and iterators have custom visualizations in the Natvis framework. + +=== Using in your project + +To visualize Boost.Unordered containers in the Natvis framework in your project, simply add the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost_unordered.natvis] to your Visual Studio project as an "Existing Item". + +=== Visualization structure + +The visualizations mirror those for the standard unordered containers. A container has a maximum of 100 elements displayed at once. Each set element has its item name listed as `[i]`, where `i` is the index in the display, starting at `0`. Each map element has its item name listed as `[\{key-display}]` by default. For example, if the first element is the pair `("abc", 1)`, the item name will be `["abc"]`. This behaviour can be overridden by using the view "ShowElementsByIndex", which switches the map display behaviour to name the elements by index. This same view name is used in the standard unordered containers. + +By default, the closed-addressing containers will show the `[hash_function]` and `[key_eq]`, the `[spare_hash_function]` and `[spare_key_eq]` if applicable, the `[allocator]`, and the elements. Using the view "detailed" adds the `[bucket_count]` and `[max_load_factor]`. Conversely, using the view "simple" shows only the elements, with no other items present. + +By default, the open-addressing containers will show the `[hash_function]`, `[key_eq]`, `[allocator]`, and the elements. Using the view "simple" shows only the elements, with no other items present. Both the SIMD and the non-SIMD implementations are viewable through the Natvis framework. + +Iterators are displayed similarly to their standard counterparts. An iterator is displayed as though it were the element that it points to. An end iterator is simply displayed as `{ end iterator }`. + +=== Fancy pointers + +The container visualizations also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has natvis customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost_unordered.natvis]. + +== GDB Pretty-Printers + +All containers and iterators have a custom GDB pretty-printer. + +=== Using in your project + +Always, when using pretty-printers, you must enable pretty-printing like below. This is typically a one-time setup. + +```plaintext (gdb) set print pretty on ``` + +By default, if you compile into an ELF binary format, your binary will contain the Boost.Unordered pretty-printers. To use the embedded pretty-printers, ensure you allow auto-loading like below. This must be done every time you load GDB, or add it to a ".gdbinit" file. + +```plaintext (gdb) add-auto-load-safe-path [/path/to/executable] ``` + +You can choose to compile your binary _without_ embedding the pretty-printers by defining `BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS`, which disables the embedded GDB pretty-printers for all Boost libraries that have this feature. + +You can load the pretty-printers externally from the non-embedded Python script. Add the script, link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py], using the `source` command as shown below. + +```plaintext (gdb) source [/path/to/boost]/libs/unordered/extra/boost_unordered_printers.py ``` + +=== Visualization structure + +The visualizations mirror the standard unordered containers. The map containers display an association from key to mapped value. The set containers display an association from index to value. An iterator is either displayed with its item, or as an end iterator. Here is what may be shown for an example `boost::unordered_map`, an example `boost::unordered_set`, and their respective begin and end iterators. + +```plaintext (gdb) print example_unordered_map $1 = boost::unordered_map with 3 elements = {["C"] = "c", ["B"] = "b", ["A"] = "a"} (gdb) print example_unordered_map_begin $2 = iterator = { {first = "C", second = "c"} } (gdb) print example_unordered_map_end $3 = iterator = { end iterator } (gdb) print example_unordered_set $4 = boost::unordered_set with 3 elements = {[0] = "c", [1] = "b", [2] = "a"} (gdb) print example_unordered_set_begin $5 = iterator = { "c" } (gdb) print example_unordered_set_end $6 = iterator = { end iterator } ``` + +The other containers are identical other than replacing "`boost::unordered_{map|set}`" with the appropriate template name when displaying the container itself. Note that each sub-element (i.e. the key, the mapped value, or the value) is displayed based on its own printing settings which may include its own pretty-printer. + +Both the SIMD and the non-SIMD implementations are viewable through the GDB pretty-printers. + +For open-addressing containers where xref:hash_quality.adoc#hash_quality_container_statistics[container statistics] are enabled, you can obtain these statistics by calling `get_stats()` on the container, from within GDB. This is overridden in GDB as an link:https://sourceware.org/gdb/current/onlinedocs/gdb.html/Xmethod-API.html[xmethod], so it will not invoke any C++ synchronization code. See the following printout as an example for the expected format. + +```plaintext (gdb) print example_flat_map.get_stats() $1 = [stats] = {[insertion] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}}, [successful_lookup] = {[count] = 0, [probe_length] = {avg = 0.0, var = 0.0, dev = 0.0}, [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}, [unsuccessful_lookup] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}, [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}} ``` + +=== Fancy pointers + +The pretty-printers also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has GDB pretty-printer customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py]. From 12c31f9394716c6374cc274d805c289b4a1c72f4 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:17:59 +0000 Subject: [PATCH 11/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/copyright_zh_Hans.adoc | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 doc/modules/ROOT/pages/copyright_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/copyright_zh_Hans.adoc b/doc/modules/ROOT/pages/copyright_zh_Hans.adoc new file mode 100644 index 0000000..43a906a --- /dev/null +++ b/doc/modules/ROOT/pages/copyright_zh_Hans.adoc @@ -0,0 +1,20 @@ +[#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-2025 Christian Mazakas + +Copyright (C) 2022-2025 Joaquín M López Muñoz + +Copyright (C) 2022-2023 Peter Dimov + +Copyright (C) 2024 Braden Ganetsky + +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) From 02cd9f4efc8967462037947bfb578d74df56cfc5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:18:09 +0000 Subject: [PATCH 12/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/concurrent_zh_Hans.adoc | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 doc/modules/ROOT/pages/concurrent_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc new file mode 100644 index 0000000..4e2a132 --- /dev/null +++ b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc @@ -0,0 +1,251 @@ +[#concurrent] = Concurrent Containers + +:idprefix: concurrent_ + +Boost.Unordered provides `boost::concurrent_node_set`, `boost::concurrent_node_map`, `boost::concurrent_flat_set` and `boost::concurrent_flat_map`, hash tables that allow concurrent write/read access from different threads without having to implement any synchronzation mechanism on the user's side. + +[source,c++] +---- +std::vector input; +boost::concurrent_flat_map m; + +... + +// process input in parallel +const int num_threads = 8; +std::vector threads; +std::size_t chunk = input.size() / num_threads; // how many elements per thread + +for (int i = 0; i < num_threads; ++i) { + threads.emplace_back([&,i] { + // calculate the portion of input this thread takes care of + std::size_t start = i * chunk; + std::size_t end = (i == num_threads - 1)? input.size(): (i + 1) * chunk; + + for (std::size_t n = start; n < end; ++n) { + m.emplace(input[n], calculation(input[n])); + } + }); +} +---- + +In the example above, threads access `m` without synchronization, just as we'd do in a single-threaded scenario. In an ideal setting, if a given workload is distributed among _N_ threads, execution is _N_ times faster than with one thread —this limit is never attained in practice due to synchronization overheads and _contention_ (one thread waiting for another to leave a locked portion of the map), but Boost.Unordered concurrent containers are designed to perform with very little overhead and typically achieve _linear scaling_ (that is, performance is proportional to the number of threads up to the number of logical cores in the CPU). + +== Visitation-based API + +The first thing a new user of Boost.Unordered concurrent containers will notice is that these classes _do not provide iterators_ (which makes them technically not https://en.cppreference.com/w/cpp/named_req/Container[Containers^] in the C++ standard sense). The reason for this is that iterators are inherently thread-unsafe. Consider this hypothetical code: + +[source,c++] +---- +auto it = m.find(k); // A: get an iterator pointing to the element with key k +if (it != m.end() ) { + some_function(*it); // B: use the value of the element +} +---- + +In a multithreaded scenario, the iterator `it` may be invalid at point B if some other thread issues an `m.erase(k)` operation between A and B. There are designs that can remedy this by making iterators lock the element they point to, but this approach lends itself to high contention and can easily produce deadlocks in a program. `operator[]` has similar concurrency issues, and is not provided by `boost::concurrent_flat_map`/`boost::concurrent_node_map` either. Instead, element access is done through so-called _visitation functions_: + +[source,c++] +---- +m.visit(k, [](const auto& x) { // x is the element with key k (if it exists) + some_function(x); // use it +}); +---- + +The visitation function passed by the user (in this case, a lambda function) is executed internally by Boost.Unordered in a thread-safe manner, so it can access the element without worrying about other threads interfering in the process. + +On the other hand, a visitation function can _not_ access the container itself: + +[source,c++] +---- +m.visit(k, [&](const auto& x) { + some_function(x, m.size()); // forbidden: m can't be accessed inside visitation +}); +---- + +Access to a different container is allowed, though: + +[source,c++] +---- +m.visit(k, [&](const auto& x) { + if (some_function(x)) { + m2.insert(x); // OK, m2 is a different boost::concurrent_flat_map + } +}); +---- + +But, in general, visitation functions should be as lightweight as possible to reduce contention and increase parallelization. In some cases, moving heavy work outside of visitation may be beneficial: + +[source,c++] +---- +std::optional o; +bool found = m.visit(k, [&](const auto& x) { + o = x; +}); +if (found) { + some_heavy_duty_function(*o); +} +---- + +Visitation is prominent in the API provided by concurrent containers, and many classical operations have visitation-enabled variations: + +[source,c++] +---- +m.insert_or_visit(x, [](auto& y) { + // if insertion failed because of an equivalent element y, + // do something with it, for instance: + ++y.second; // increment the mapped part of the element +}); +---- + +Note that in this last example the visitation function could actually _modify_ the element: as a general rule, operations on a concurrent map `m` will grant visitation functions const/non-const access to the element depending on whether `m` is const/non-const. Const access can be always be explicitly requested by using `cvisit` overloads (for instance, `insert_or_cvisit`) and may result in higher parallelization. For concurrent sets, on the other hand, visitation is always const access. + +Although expected to be used much less frequently, concurrent containers also provide insertion operations where an element can be visited right after element creation (in addition to the usual visitation when an equivalent element already exists): + +[source,c++] +---- + m.insert_and_cvisit(x, + [](const auto& y) { + std::cout<< "(" << y.first << ", " << y.second <<") inserted\n"; + }, + [](const auto& y) { + std::cout<< "(" << y.first << ", " << y.second << ") already exists\n"; + }); +---- + +Consult the references of `xref:reference/concurrent_node_set.adoc#concurrent_node_set[boost::concurrent_node_set]`, `xref:reference/concurrent_node_map.adoc#concurrent_node_map[boost::concurrent_node_map]`, `xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[boost::concurrent_flat_set]` and `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[boost::concurrent_flat_map]` for the complete list of visitation-enabled operations. + +== Whole-Table Visitation + +In the absence of iterators, `visit_all` is provided as an alternative way to process all the elements in the container: + +[source,c++] +---- +m.visit_all([](auto& x) { + x.second = 0; // reset the mapped part of the element +}); +---- + +In C++17 compilers implementing standard parallel algorithms, whole-table visitation can be parallelized: + +[source,c++] +---- +m.visit_all(std::execution::par, [](auto& x) { // run in parallel + x.second = 0; // reset the mapped part of the element +}); +---- + +Traversal can be interrupted midway: + +[source,c++] +---- +// finds the key to a given (unique) value + +int key = 0; +int value = ...; +bool found = !m.visit_while([&](const auto& x) { + if(x.second == value) { + key = x.first; + return false; // finish + } + else { + return true; // keep on visiting + } +}); + +if(found) { ... } +---- + +There is one last whole-table visitation operation, `erase_if`: + +[source,c++] +---- +m.erase_if([](auto& x) { + return x.second == 0; // erase the elements whose mapped value is zero +}); +---- + +`visit_while` and `erase_if` can also be parallelized. Note that, in order to increase efficiency, whole-table visitation operations do not block the table during execution: this implies that elements may be inserted, modified or erased by other threads during visitation. It is advisable not to assume too much about the exact global state of a concurrent container at any point in your program. + +== Bulk visitation + +Suppose you have an `std::array` of keys you want to look up for in a concurrent map: + +[source,c++] +---- +std::array keys; +... +for(const auto& key: keys) { + m.visit(key, [](auto& x) { ++x.second; }); +} +---- + +_Bulk visitation_ allows us to pass all the keys in one operation: + +[source,c++] +---- +m.visit(keys.begin(), keys.end(), [](auto& x) { ++x.second; }); +---- + +This functionality is not provided for mere syntactic convenience, though: by processing all the keys at once, some internal optimizations can be applied that increase performance over the regular, one-at-a-time case (consult the xref:benchmarks.adoc#benchmarks_boostconcurrent_flatnode_map[benchmarks]). In fact, it may be beneficial to buffer incoming keys so that they can be bulk visited in chunks: + +[source,c++] +---- +static constexpr auto bulk_visit_size = boost::concurrent_flat_map::bulk_visit_size; +std::array buffer; +std::size_t i=0; +while(...) { // processing loop + ... + buffer[i++] = k; + if(i == bulk_visit_size) { + map.visit(buffer.begin(), buffer.end(), [](auto& x) { ++x.second; }); + i = 0; + } + ... +} +// flush remaining keys +map.visit(buffer.begin(), buffer.begin() + i, [](auto& x) { ++x.second; }); +---- + +There's a latency/throughput tradeoff here: it will take longer for incoming keys to be processed (since they are buffered), but the number of processed keys per second is higher. `bulk_visit_size` is the recommended chunk size —smaller buffers may yield worse performance. + +== Blocking Operations + +Concurrent containers can be copied, assigned, cleared and merged just like any other Boost.Unordered container. Unlike most other operations, these are _blocking_, that is, all other threads are prevented from accesing the tables involved while a copy, assignment, clear or merge operation is in progress. Blocking is taken care of automatically by the library and the user need not take any special precaution, but overall performance may be affected. + +Another blocking operation is _rehashing_, which happens explicitly via `rehash`/`reserve` or during insertion when the table's load hits `max_load()`. As with non-concurrent containers, reserving space in advance of bulk insertions will generally speed up the process. + +== Interoperability with non-concurrent containers + +As open-addressing and concurrent containers are based on the same internal data structure, they can be efficiently move-constructed from their non-concurrent counterpart, and vice versa. + +[caption=, title='Table {counter:table-counter}. Concurrent/non-concurrent interoperatibility'] +[cols="1,1", frame=all, grid=all] +|=== +^|`boost::concurrent_node_set` ^|`boost::unordered_node_set` + +^|`boost::concurrent_node_map` ^|`boost::unordered_node_map` + +^|`boost::concurrent_flat_set` ^|`boost::unordered_flat_set` + +^|`boost::concurrent_flat_map` ^|`boost::unordered_flat_map` + +|=== + +This interoperability comes handy in multistage scenarios where parts of the data processing happen in parallel whereas other steps are non-concurrent (or non-modifying). In the following example, we want to construct a histogram from a huge input vector of words: the population phase can be done in parallel with `boost::concurrent_flat_map` and results then transferred to the final container. + +[source,c++] +---- +std::vector words = ...; + +// Insert words in parallel +boost::concurrent_flat_map m0; +std::for_each( + std::execution::par, words.begin(), words.end(), + [&](const auto& word) { + m0.try_emplace_or_visit(word, 1, [](auto& x) { ++x.second; }); + }); + +// Transfer to a regular unordered_flat_map +boost::unordered_flat_map m=std::move(m0); +---- From e770249ece80006bd1b32757ba7c1fec476e681c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:18:14 +0000 Subject: [PATCH 13/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/compliance_zh_Hans.adoc | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 doc/modules/ROOT/pages/compliance_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc new file mode 100644 index 0000000..b787095 --- /dev/null +++ b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc @@ -0,0 +1,94 @@ +[#compliance] += Standard Compliance + +:idprefix: compliance_ + +:cpp: C++ + +== Closed-addressing Containers + +`boost::unordered_[multi]set` and `boost::unordered_[multi]map` provide a conformant implementation for {cpp}11 (or later) compilers of the latest standard revision of {cpp} unordered associative containers, with very minor deviations as noted. The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. + +=== Deduction Guides + +Deduction guides for https://en.cppreference.com/w/cpp/language/class_template_argument_deduction[class template argument deduction (CTAD)^] are only available on {cpp}17 (or later) compilers. + +=== Piecewise Pair Emplacement + +In accordance with the standard specification, `boost::unordered_[multi]map::emplace` supports piecewise pair construction: + +[source,c++] +---- +boost::unordered_multimap x; + +x.emplace( + std::piecewise_construct, + std::make_tuple("key"), std::make_tuple(1, 2)); +---- + +Additionally, the same functionality is provided via non-standard `boost::unordered::piecewise_construct` and Boost.Tuple: + +[source,c++] +---- +x.emplace( + boost::unordered::piecewise_construct, + boost::make_tuple("key"), boost::make_tuple(1, 2)); +---- + +This feature has been retained for backwards compatibility with previous versions of Boost.Unordered: users are encouraged to update their code to use `std::piecewise_construct` and ``std::tuple``s instead. + +=== Swap + +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 thrown from their copy constructor. + +== Open-addressing Containers + +The C++ standard does not currently provide any open-addressing container specification to adhere to, so `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` take inspiration from `std::unordered_set` and `std::unordered_map`, respectively, and depart from their interface where convenient or as dictated by their internal data structure, which is radically different from that imposed by the standard (closed addressing). + +Open-addressing containers provided by Boost.Unordered only work with reasonably compliant C++11 (or later) compilers. Language-level features such as move semantics and variadic template parameters are then not emulated. The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. + + +The main differences with C++ unordered associative containers are: + +* In general: +** `begin()` is not constant-time. ** `erase(iterator)` does not return an iterator to the following element, but a proxy object that converts to that iterator if requested; this avoids a potentially costly iterator increment operation when not needed. ** There is no API for bucket handling (except `bucket_count`). ** The maximum load factor of the container is managed internally and can't be set by the user. The maximum load, exposed through the public function `max_load`, may decrease on erasure under high-load conditions. +* Flat containers (`boost::unordered_flat_set` and `boost::unordered_flat_map`): +** `value_type` must be move-constructible. ** Pointer stability is not kept under rehashing. ** There is no API for node extraction/insertion. + +== Concurrent Containers + +There is currently no specification in the C++ standard for this or any other type of concurrent data structure. The APIs of `boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map` are modelled after `std::unordered_flat_set` and `std::unordered_flat_map`, respectively, with the crucial difference that iterators are not provided due to their inherent problems in concurrent scenarios (high contention, prone to deadlocking): so, Boost.Unordered concurrent containers are technically not models of https://en.cppreference.com/w/cpp/named_req/Container[Container^], although they meet all the requirements of https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] containers (including https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointer^] support) except those implying iterators. + +In a non-concurrent unordered container, iterators serve two main purposes: + +* Access to an element previously located via lookup. +* Container traversal. + +In place of iterators, Boost.Unordered concurrent containers use _internal visitation_ facilities as a thread-safe substitute. Classical operations returning an iterator to an element already existing in the container, like for instance: + +[source,c++] +---- +iterator find(const key_type& k); +std::pair insert(const value_type& obj); +---- + +are transformed to accept a _visitation function_ that is passed such element: + +[source,c++] +---- +template size_t visit(const key_type& k, F f); +template bool insert_or_visit(const value_type& obj, F f); +---- + +(In the second case `f` is only invoked if there's an equivalent element to `obj` in the table, not if insertion is successful). Container traversal is served by: + +[source,c++] +---- +template size_t visit_all(F f); +---- + +of which there are parallelized versions in C++17 compilers with parallel algorithm support. In general, the interface of concurrent containers is derived from that of their non-concurrent counterparts by a fairly straightforward process of replacing iterators with visitation where applicable. If for regular maps `iterator` and `const_iterator` provide mutable and const access to elements, respectively, here visitation is granted mutable or const access depending on the constness of the member function used (there are also `*cvisit` overloads for explicit const visitation); In the case of `boost::concurrent_flat_set`, visitation is always const. + +One notable operation not provided by `boost::concurrent_flat_map`/`boost::concurrent_node_map` is `operator[]`/`at`, which can be replaced, if in a more convoluted manner, by `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_visit]`. + +//- From 0ff366e3adc4e63ad19e39dfbc4b80ea8ecafd97 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:18:30 +0000 Subject: [PATCH 14/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/changes_zh_Hans.adoc | 392 ++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 doc/modules/ROOT/pages/changes_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/changes_zh_Hans.adoc b/doc/modules/ROOT/pages/changes_zh_Hans.adoc new file mode 100644 index 0000000..e47730f --- /dev/null +++ b/doc/modules/ROOT/pages/changes_zh_Hans.adoc @@ -0,0 +1,392 @@ +[#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.89.0 + +* Deprecated `boost::unordered::hash_is_avalanching` is now a using-declaration of +`boost::hash_is_avalanching` in ``. Use that header directly instead. `` will be removed in the future. +* Added `pull(const_iterator)` to open-addressing containers. This operation +allows for efficient removal and retrieval of an element via move construction. + +== Release 1.88.0 + +* Migrated the documentation to a multipage format using Antora. + +== Release 1.87.0 - Major update + +* Added concurrent, node-based containers `boost::concurrent_node_map` and `boost::concurrent_node_set`. +* Added `insert_and_visit(x, f1, f2)` and similar operations to concurrent containers, which +allow for visitation of an element right after insertion (by contrast, `insert_or_visit(x, f)` only visits the element if insertion did _not_ take place). +* Made visitation exclusive-locked within certain +`boost::concurrent_flat_set` operations to allow for safe mutable modification of elements ({github-pr-url}/265[PR#265^]). +* In Visual Studio Natvis, supported any container with an allocator that uses fancy pointers. This applies to any fancy pointer type, as long as the proper Natvis customization point "Intrinsic" functions are written for the fancy pointer type. +* Added GDB pretty-printers for all containers and iterators. For a container with an allocator that uses fancy pointers, these only work if the proper pretty-printer is written for the fancy pointer type itself. +* Fixed `std::initializer_list` assignment issues for open-addressing containers +({github-pr-url}/277[PR#277^]). +* Allowed non-copyable callables to be passed to the `std::initializer_list` overloads of `insert_{and|or}_[c]visit` for concurrent containers, by internally passing a `std::reference_wrapper` of the callable to the iterator-pair overloads. + + +== Release 1.86.0 + +* Added container `pmr` aliases when header `` is available. The alias `boost::unordered::pmr::[container]` refers to `boost::unordered::[container]` with a `std::pmr::polymorphic_allocator` allocator type. +* Equipped open-addressing and concurrent containers to internally calculate and provide statistical metrics affected by the quality of the hash function. This functionality is enabled by the global macro `BOOST_UNORDERED_ENABLE_STATS`. +* Avalanching hash functions must now be marked via an `is_avalanching` typedef with an embedded `value` constant set to `true` (typically, defining `is_avalanching` as `std::true_type`). `using is_avalanching = void` is deprecated but allowed for backwards compatibility. +* Added Visual Studio Natvis framework custom visualizations for containers and iterators. This works for all containers with an allocator using raw pointers. In this release, containers and iterators are not supported if their allocator uses fancy pointers. This may be addressed in later releases. + +== Release 1.85.0 + +* Optimized `emplace()` for a `value_type` or `init_type` (if applicable) argument to bypass creating an intermediate object. The argument is already the same type as the would-be intermediate object. +* Optimized `emplace()` for `k,v` arguments on map containers to delay constructing the object until it is certain that an element should be inserted. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. +* Fixed support for allocators with `explicit` copy constructors ({github-pr-url}/234[PR#234^]). +* Fixed bug in the `const` version of `unordered_multimap::find(k, hash, eq)` ({github-pr-url}/238[PR#238^]). + +== Release 1.84.0 - Major update + +* Added `boost::concurrent_flat_set`. +* Added `[c]visit_while` operations to concurrent containers, +with serial and parallel variants. +* Added efficient move construction of `boost::unordered_flat_(map|set)` from +`boost::concurrent_flat_(map|set)` and vice versa. +* Added bulk visitation to concurrent containers for increased lookup performance. +* Added debug-mode mechanisms for detecting illegal reentrancies into +a concurrent container from user code. +* Added Boost.Serialization support to all containers and their (non-local) iterator types. +* Added support for fancy pointers to open-addressing and concurrent containers. +This enables scenarios like the use of Boost.Interprocess allocators to construct containers in shared memory. +* Fixed bug in member of pointer operator for local iterators of closed-addressing +containers ({github-pr-url}/221[PR#221^], credit goes to GitHub user vslashg for finding and fixing this issue). +* Starting with this release, `boost::unordered_[multi]set` and `boost::unordered_[multi]map` +only work with C++11 onwards. + +== Release 1.83.0 - Major update + +* Added `boost::concurrent_flat_map`, a fast, thread-safe hashmap based on open addressing. +* Sped up iteration of open-addressing containers. +* In open-addressing containers, `erase(iterator)`, which previously returned nothing, now +returns a proxy object convertible to an iterator to the next element. This enables the typical `it = c.erase(it)` idiom without incurring any performance penalty when the returned proxy is not used. + +== Release 1.82.0 - Major update + +* {cpp}03 support is planned for deprecation. Boost 1.84.0 will no longer support +{cpp}03 mode and {cpp}11 will become the new minimum for using the library. +* Added node-based, open-addressing containers +`boost::unordered_node_map` and `boost::unordered_node_set`. +* Extended heterogeneous lookup to more member functions as specified in +https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html[P2363]. +* Replaced the previous post-mixing process for open-addressing containers with +a new algorithm based on extended multiplication by a constant. +* Fixed bug in internal emplace() impl where stack-local types were not properly +constructed using the Allocator of the container which breaks uses-allocator construction. + +== Release 1.81.0 - Major update + +* Added fast containers `boost::unordered_flat_map` and `boost::unordered_flat_set` +based on open addressing. +* Added CTAD deduction guides for all containers. +* Added missing constructors as specified in https://cplusplus.github.io/LWG/issue2713[LWG issue 2713]. + +== 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:compliance.adoc[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 `` and +``. +* 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. From 5150cebd7ab26b601c911f8f105af4ebaab3d13e Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:18:44 +0000 Subject: [PATCH 15/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/buckets_zh_Hans.adoc | 101 ++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 doc/modules/ROOT/pages/buckets_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/buckets_zh_Hans.adoc b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc new file mode 100644 index 0000000..0b7c2a0 --- /dev/null +++ b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc @@ -0,0 +1,101 @@ +[#buckets] +:idprefix: buckets_ + += Basics of Hash Tables + +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 a `xref:reference/unordered_set.adoc#unordered_set[boost::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 sets 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 xref:hash_equality.adoc#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. + +If instead of `boost::unordered_set` we had used `xref:reference/unordered_flat_set.adoc[boost::unordered_flat_set]`, the diagram would look as follows: + +image::buckets-oa.png[] + +In open-addressing containers, buckets can hold at most one element; if a collision happens (like is the case of `D` in the example), the element uses some other available bucket in the vicinity of the original position. Given this simpler scenario, Boost.Unordered open-addressing containers offer a very limited API for accessing buckets. + +[caption=, title='Table {counter:table-counter}. Methods for Accessing Buckets'] +[cols="1,.^1", frame=all, grid=rows] +|=== +2+^h| *All containers* h|*Method* h|*Description* + +|`size_type bucket_count() const` +|The number of buckets. + +2+^h| *Closed-addressing containers only* h|*Method* h|*Description* + +|`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 collisions 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 number of elements divided by the number of buckets. 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] +|=== +2+^h| *All containers* h|*Method* h|*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. + +**Open-addressing and concurrent containers:** this function does nothing: users are not allowed to change the maximum load factor. + +|`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. + +2+^h| *Open-addressing and concurrent containers only* h|*Method* h|*Description* + +|`size_type max_load() const` +|Returns the maximum number of allowed elements in the container before rehash. + +|=== + +A note on `max_load` for open-addressing and concurrent containers: the maximum load will be (`max_load_factor() * bucket_count()`) right after `rehash` or on container creation, but may slightly decrease when erasing elements in high-load situations. For instance, if we have a `xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map]` with `size()` almost at `max_load()` level and then erase 1,000 elements, `max_load()` may decrease by around a few dozen elements. This is done internally by Boost.Unordered in order to keep its performance stable, and must be taken into account when planning for rehash-free insertions. From ba6531f6fd1069050b8f68ca0a26588c7e8cd2c9 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:18:58 +0000 Subject: [PATCH 16/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Compliance (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-compliance-adoc/ --- doc/modules/ROOT/pages/compliance_zh_Hans.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc index b787095..b895e29 100644 --- a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc @@ -52,7 +52,7 @@ The main differences with C++ unordered associative containers are: * In general: ** `begin()` is not constant-time. ** `erase(iterator)` does not return an iterator to the following element, but a proxy object that converts to that iterator if requested; this avoids a potentially costly iterator increment operation when not needed. ** There is no API for bucket handling (except `bucket_count`). ** The maximum load factor of the container is managed internally and can't be set by the user. The maximum load, exposed through the public function `max_load`, may decrease on erasure under high-load conditions. -* Flat containers (`boost::unordered_flat_set` and `boost::unordered_flat_map`): +* `begin()` is not constant-time. ** `erase(iterator)` does not return an iterator to the following element, but a proxy object that converts to that iterator if requested; this avoids a potentially costly iterator increment operation when not needed. ** There is no API for bucket handling (except `bucket_count`). ** The maximum load factor of the container is managed internally and can't be set by the user. The maximum load, exposed through the public function `max_load`, may decrease on erasure under high-load conditions. ** `value_type` must be move-constructible. ** Pointer stability is not kept under rehashing. ** There is no API for node extraction/insertion. == Concurrent Containers From accb84aa97a9e74b635537f0976b074c5981ad8d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:18:58 +0000 Subject: [PATCH 17/60] Added translation using Weblate (Chinese (Simplified Han script)) --- doc/modules/ROOT/pages/bibliography_zh_Hans.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 doc/modules/ROOT/pages/bibliography_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc b/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc new file mode 100644 index 0000000..020d3c0 --- /dev/null +++ b/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc @@ -0,0 +1,12 @@ +[#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 introduction to the standard unordered containers. +* _Wikipedia_. https://en.wikipedia.org/wiki/Hash_table[Hash table^]. + +An introduction to hash table implementations. Discusses the differences between closed-addressing and open-addressing approaches. +* Peter Dimov, 2022. https://pdimov.github.io/articles/unordered_dev_plan.html[Development Plan for Boost.Unordered^]. + From 1ac5efe82b54b4b716f78571c4e4712916894477 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:05 +0000 Subject: [PATCH 18/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/benchmarks_zh_Hans.adoc | 553 ++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc new file mode 100644 index 0000000..c3d2c6e --- /dev/null +++ b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc @@ -0,0 +1,553 @@ +[#benchmarks] +:idprefix: benchmarks_ + += Benchmarks + +== boost::unordered_[multi]set + +All benchmarks were created using `unordered_set` (non-duplicate) and `unordered_multiset` (duplicate). The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_set[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. Erasure by key uses `erase(const key_type&)` to remove entire groups of equivalent elements in each operation. + +The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order. + +The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value. + +=== GCC 12 + libstdc++-v3, x64 + +==== Insertion + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/gcc/running insertion.xlsx.practice.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice.png,window=_blank] +|image::benchmarks-set/gcc/running insertion.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice non-unique.png,window=_blank] +|image::benchmarks-set/gcc/running insertion.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/running insertion.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-set/gcc/running insertion.xlsx.practice norehash.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice norehash.png,window=_blank] +|image::benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique.png,window=_blank] +|image::benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/running insertion.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-set/gcc/scattered erasure.xlsx.practice.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice.png,window=_blank] +|image::benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique.png,window=_blank] +|image::benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique 5.png,window=_blank] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +| +|image::benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] +|image::benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] + +| +h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 + +|=== + +==== Successful Lookup + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.xlsx.practice.png] +|image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.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-set/gcc/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice.png] +|image::benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +|=== + +=== Clang 15 + libc++, x64 + +==== Insertion + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice.png] +|image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique.png] +|image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique 5.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.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-set/clang_libcpp/running insertion.xlsx.practice norehash.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash.png] +|image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique.png] +|image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.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-set/clang_libcpp/scattered erasure.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice.png] +|image::benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique.png] +|image::benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique 5.png] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +| +|image::benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] +|image::benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] + +| +h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 + +|=== + +==== Successful lookup + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice.png] +|image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.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-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice.png] +|image::benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +|=== + +=== Visual Studio 2022 + Dinkumware, x64 + +==== Insertion + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/vs/running insertion.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice.png] +|image::benchmarks-set/vs/running insertion.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice non-unique.png] +|image::benchmarks-set/vs/running insertion.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.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-set/vs/running insertion.xlsx.practice norehash.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice norehash.png] +|image::benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique.png] +|image::benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.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-set/vs/scattered erasure.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice.png] +|image::benchmarks-set/vs/scattered erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice non-unique.png] +|image::benchmarks-set/vs/scattered erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice non-unique 5.png] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +| +|image::benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] +|image::benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] + +| +h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 + +|=== + +==== Successful lookup + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-set/vs/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.xlsx.practice.png] +|image::benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.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-set/vs/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice.png] +|image::benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique.png] +|image::benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] + +h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 + +|=== + +== boost::unordered_(flat|node)_map + +All benchmarks were created using: + +* `https://abseil.io/docs/cpp/guides/container[absl::flat_hash_map^]` +* `boost::unordered_map` +* `boost::unordered_flat_map` +* `boost::unordered_node_map` + +The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_flat_map[found here^]. + +The insertion benchmarks insert `n` random values, where `n` is between 10,000 and 10 million. + +The erasure benchmarks erase traverse the `n` elements and erase those with odd key (50% on average). + +The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order. + +The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value. + + +=== GCC 12, x64 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/gcc-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x64/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== Clang 15, x64 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/clang-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x64/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== Visual Studio 2022, x64 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/vs-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x64/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== Clang 12, ARM64 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/clang-arm64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/clang-arm64/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/clang-arm64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/clang-arm64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== GCC 12, x86 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/gcc-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x86/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/gcc-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== Clang 15, x86 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/clang-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x86/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/clang-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +=== Visual Studio 2022, x86 + + +[caption=] +[cols="4*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-flat_map/vs-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Running insertion.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x86/Running erasure.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Running erasure.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Scattered successful looukp.xlsx.plot.png] +|image::benchmarks-flat_map/vs-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Scattered unsuccessful looukp.xlsx.plot.png] + +h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup + +|=== + +== boost::concurrent_(flat|node)_map + +All benchmarks were created using: + +* `https://spec.oneapi.io/versions/latest/elements/oneTBB/source/containers/concurrent_hash_map_cls.html[oneapi::tbb::concurrent_hash_map^]` +* `https://github.com/greg7mdp/gtl/blob/main/docs/phmap.md[gtl::parallel_flat_hash_map^]` with 64 submaps +* `boost::concurrent_flat_map` +* `boost::concurrent_node_map` + +The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_concurrent_flat_map[found here^]. + +The benchmarks exercise a number of threads _T_ (between 1 and 16) concurrently performing operations randomly chosen among **update**, **successful lookup** and **unsuccessful lookup**. The keys used in the operations follow a https://en.wikipedia.org/wiki/Zipf%27s_law#Formal_definition[Zipf distribution^] with different _skew_ parameters: the higher the skew, the more concentrated are the keys in the lower values of the covered range. + +`boost::concurrent_flat_map` and `boost::concurrent_node_map` are exercised using both regular and xref:concurrent.adoc#concurrent_bulk_visitation[bulk visitation]: in the latter case, lookup keys are buffered in a local array and then processed at once each time the buffer reaches `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_constants[bulk_visit_size]`. + +=== GCC 12, x64 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== Clang 15, x64 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== Visual Studio 2022, x64 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== Clang 12, ARM64 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== GCC 12, x86 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== Clang 15, x86 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== + +=== Visual Studio 2022, x86 + + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.01.png"] +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.5.png"] +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.99.png"] + +h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== + +[caption=] +[cols="3*^.^a", frame=all, grid=all] +|=== + +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.01.png"] +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.5.png"] +|image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.99.png"] + +h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== From 17166e408cf9049c7f0e2016672e8c889f135204 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:13 +0000 Subject: [PATCH 19/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_set_zh_Hans.adoc | 1177 +++++++++++++++++ 1 file changed, 1177 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc new file mode 100644 index 0000000..28bba85 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc @@ -0,0 +1,1177 @@ +[#unordered_set] +== Class Template unordered_set + +:idprefix: unordered_set_ + +`boost::unordered_set` — An unordered associative container that stores unique values. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_set.adoc[] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class unordered_set { + public: + // types + using key_type = Key; + using value_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + using local_iterator = _implementation-defined_; + using const_local_iterator = _implementation-defined_; + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + // construct/copy/destroy + xref:#unordered_set_default_constructor[unordered_set](); + explicit xref:#unordered_set_bucket_count_constructor[unordered_set](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_set_iterator_range_constructor[unordered_set](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_set_copy_constructor[unordered_set](const unordered_set& other); + xref:#unordered_set_move_constructor[unordered_set](unordered_set&& other); + template + xref:#unordered_set_iterator_range_constructor_with_allocator[unordered_set](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_set_allocator_constructor[unordered_set](const Allocator& a); + xref:#unordered_set_copy_constructor_with_allocator[unordered_set](const unordered_set& other, const Allocator& a); + xref:#unordered_set_move_constructor_with_allocator[unordered_set](unordered_set&& other, const Allocator& a); + xref:#unordered_set_initializer_list_constructor[unordered_set](std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_set_bucket_count_constructor_with_allocator[unordered_set](size_type n, const allocator_type& a); + xref:#unordered_set_bucket_count_constructor_with_hasher_and_allocator[unordered_set](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_set_iterator_range_constructor_with_bucket_count_and_allocator[unordered_set](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_set_iterator_range_constructor_with_bucket_count_and_hasher[unordered_set](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_set_initializer_list_constructor_with_allocator[unordered_set](std::initializer_list il, const allocator_type& a); + xref:#unordered_set_initializer_list_constructor_with_bucket_count_and_allocator[unordered_set](std::initializer_list il, size_type n, const allocator_type& a); + xref:#unordered_set_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_set](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_set_destructor[~unordered_set](); + unordered_set& xref:#unordered_set_copy_assignment[operator++=++](const unordered_set& other); + unordered_set& xref:#unordered_set_move_assignment[operator++=++](unordered_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + unordered_set& xref:#unordered_set_initializer_list_assignment[operator++=++](std::initializer_list il); + allocator_type xref:#unordered_set_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_set_begin[begin]() noexcept; + const_iterator xref:#unordered_set_begin[begin]() const noexcept; + iterator xref:#unordered_set_end[end]() noexcept; + const_iterator xref:#unordered_set_end[end]() const noexcept; + const_iterator xref:#unordered_set_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_set_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_set_empty[empty]() const noexcept; + size_type xref:#unordered_set_size[size]() const noexcept; + size_type xref:#unordered_set_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_set_emplace[emplace](Args&&... args); + template iterator xref:#unordered_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_set_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_set_move_insert[insert](value_type&& obj); + template std::pair xref:#unordered_set_transparent_insert[insert](K&& k); + iterator xref:#unordered_set_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_set_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template iterator xref:#unordered_set_transparent_insert_with_hint[insert](const_iterator hint, K&& k); + template void xref:#unordered_set_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_set_insert_initializer_list[insert](std::initializer_list); + + node_type xref:#unordered_set_extract_by_iterator[extract](const_iterator position); + node_type xref:#unordered_set_extract_by_value[extract](const key_type& k); + template node_type xref:#unordered_set_extract_by_value[extract](K&& k); + insert_return_type xref:#unordered_set_insert_with_node_handle[insert](node_type&& nh); + iterator xref:#unordered_set_insert_with_hint_and_node_handle[insert](const_iterator hint, node_type&& nh); + + iterator xref:#unordered_set_erase_by_position[erase](iterator position); + iterator xref:#unordered_set_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_set_erase_by_value[erase](const key_type& k); + template size_type xref:#unordered_set_erase_by_value[erase](K&& k); + iterator xref:#unordered_set_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_set_quick_erase[quick_erase](const_iterator position); + void xref:#unordered_set_erase_return_void[erase_return_void](const_iterator position); + void xref:#unordered_set_swap[swap](unordered_set& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); + void xref:#unordered_set_clear[clear]() noexcept; + + template + void xref:#unordered_set_merge[merge](unordered_set& source); + template + void xref:#unordered_set_merge[merge](unordered_set&& source); + template + void xref:#unordered_set_merge[merge](unordered_multiset& source); + template + void xref:#unordered_set_merge[merge](unordered_multiset&& source); + + // observers + hasher xref:#unordered_set_hash_function[hash_function]() const; + key_equal xref:#unordered_set_key_eq[key_eq]() const; + + // set operations + iterator xref:#unordered_set_find[find](const key_type& k); + const_iterator xref:#unordered_set_find[find](const key_type& k) const; + template + iterator xref:#unordered_set_find[find](const K& k); + template + const_iterator xref:#unordered_set_find[find](const K& k) const; + template + iterator xref:#unordered_set_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); + template + const_iterator xref:#unordered_set_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; + size_type xref:#unordered_set_count[count](const key_type& k) const; + template + size_type xref:#unordered_set_count[count](const K& k) const; + bool xref:#unordered_set_contains[contains](const key_type& k) const; + template + bool xref:#unordered_set_contains[contains](const K& k) const; + std::pair xref:#unordered_set_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_set_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_set_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_set_equal_range[equal_range](const K& k) const; + + // bucket interface + size_type xref:#unordered_set_bucket_count[bucket_count]() const noexcept; + size_type xref:#unordered_set_max_bucket_count[max_bucket_count]() const noexcept; + size_type xref:#unordered_set_bucket_size[bucket_size](size_type n) const; + size_type xref:#unordered_set_bucket[bucket](const key_type& k) const; + template size_type xref:#unordered_set_bucket[bucket](const K& k) const; + local_iterator xref:#unordered_set_begin_2[begin](size_type n); + const_local_iterator xref:#unordered_set_begin_2[begin](size_type n) const; + local_iterator xref:#unordered_set_end_2[end](size_type n); + const_local_iterator xref:#unordered_set_end_2[end](size_type n) const; + const_local_iterator xref:#unordered_set_cbegin_2[cbegin](size_type n) const; + const_local_iterator xref:#unordered_set_cend_2[cend](size_type n) const; + + // hash policy + float xref:#unordered_set_load_factor[load_factor]() const noexcept; + float xref:#unordered_set_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_set_set_max_load_factor[max_load_factor](float z); + void xref:#unordered_set_rehash[rehash](size_type n); + void xref:#unordered_set_reserve[reserve](size_type n); + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_set(InputIterator, InputIterator, typename xref:#unordered_set_deduction_guides[__see below__]::size_type = xref:#unordered_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + unordered_set(std::initializer_list, typename xref:#unordered_set_deduction_guides[__see below__]::size_type = xref:#unordered_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_set; + + template + unordered_set(InputIterator, InputIterator, typename xref:#unordered_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_set(InputIterator, InputIterator, Allocator) + -> unordered_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_set(InputIterator, InputIterator, typename xref:#unordered_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_set, Hash, + std::equal_to>, Allocator>; + + template + unordered_set(std::initializer_list, typename xref:#unordered_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_set, std::equal_to, Allocator>; + + template + unordered_set(std::initializer_list, Allocator) + -> unordered_set, std::equal_to, Allocator>; + + template + unordered_set(std::initializer_list, typename xref:#unordered_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_set, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. + +The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. + +=== Configuration macros + +==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` + +Globally define this macro to support loading of ``unordered_set``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ local_iterator; +---- + +An iterator with the same value type, difference type and pointer and reference type as iterator. + +A `local_iterator` object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_local_iterator; +---- + +A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. + +A const_local_iterator object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_set(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_set(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_set(const unordered_set& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_set(unordered_set&& other); ``` + +The move constructor. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_set(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_set(const Allocator& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_set(const unordered_set& other, const Allocator& a); ``` + +Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_set(unordered_set&& other, const Allocator& a); ``` + +Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_set(std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_set(size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_set(size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- +template + unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_set(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_set(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_set(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_set& operator=(const unordered_set& other); ``` + +The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. + +If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Assignment +```c++ unordered_set& operator=(unordered_set&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. + +If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is move constructible. + +--- + +==== Initializer List Assignment +```c++ unordered_set& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. + +--- + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent value. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent value. + +`position` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Transparent Insert +```c++ template std::pair insert(K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Transparent Insert with Hint +```c++ template iterator insert(const_iterator hint, K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Extract by Iterator +```c++ node_type extract(const_iterator position); ``` + +Removes the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` owning the element. Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multiset`, but that is not supported yet. + +--- + +==== Extract by Value +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Removes an element with key equivalent to `k`. + +[horizontal] +Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multiset`, but that is not supported yet. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert with `node_handle` +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns an `insert_return_type` with: `inserted` equal to `false`, `position` equal to `end()` and `node` empty. + + Otherwise if there was already an element with an equivalent key, returns an `insert_return_type` with: `inserted` equal to `false`, `position` pointing to a matching element and `node` contains the node from `nh`. + + Otherwise if the insertion succeeded, returns an `insert_return_type` with: `inserted` equal to `true`, `position` pointing to the newly inserted element and `node` empty. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + In C++17 this can be used to insert a node extracted from a compatible `unordered_multiset`, but that is not supported yet. + +--- + +==== Insert with Hint and `node_handle` +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. + +If there is already an element in the container with an equivalent key has no effect on `nh` (i.e. `nh` still contains the node.) + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty returns `end()`. + + If there was already an element in the container with an equivalent key returns an iterator pointing to that. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multiset`. + +--- + +==== Erase by Position + +```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. + +--- + +==== Erase by Value +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. + +--- + +==== quick_erase +```c++ void quick_erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== erase_return_void +```c++ void erase_return_void(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== swap +```c++ void swap(unordered_set& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0` Throws:;; Never throws an exception. + +--- + +==== merge +```c++ template void merge(unordered_set& source); template void merge(unordered_set&& source); template void merge(unordered_multiset& source); template void merge(unordered_multiset&& source); ``` + +Attempt to "merge" two containers by iterating `source` and extracting any node in `source` that is not contained in `*this` and then inserting it into `*this`. + +Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. + +The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. + +This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. + +[horizontal] +Notes:;; + -- +* Pointers and references to transferred elements remain valid. +* Invalidates iterators to transferred elements. +* Invalidates iterators belonging to `*this`. +* Iterators to non-transferred elements in `source` remain valid. +-- + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const; ``` + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq + +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; ``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The number of buckets. + +--- + +==== max_bucket_count +```c++ size_type max_bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; An upper bound on the number of buckets. + +--- + +==== bucket_size +```c++ size_type bucket_size(size_type n) const; ``` + +[horizontal] +Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. + +--- + +==== bucket +```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` + +[horizontal] +Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== begin + +```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. + +--- + +==== end +```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +==== cbegin +```c++ const_local_iterator cbegin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. + +--- + +==== cend +```c++ const_local_iterator cend(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; The average number of elements per bucket. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the current maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Changes the container's maximum load factor, using `z` as a hint. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_set& x, const unordered_set& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_set& x, const unordered_set& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +=== erase_if +```c++ template typename unordered_set::size_type erase_if(unordered_set& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + +=== Serialization + +``unordered_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_set to an archive + +Saves all the elements of an `unordered_set` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_set from an archive + +Deletes all preexisting elements of an `unordered_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_set` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From da842d105979079d83f4ac69876a81fb748caef1 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:19:17 +0000 Subject: [PATCH 20/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Changes (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-changes-adoc/ --- doc/modules/ROOT/pages/changes_zh_Hans.adoc | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/modules/ROOT/pages/changes_zh_Hans.adoc b/doc/modules/ROOT/pages/changes_zh_Hans.adoc index e47730f..a6297f3 100644 --- a/doc/modules/ROOT/pages/changes_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/changes_zh_Hans.adoc @@ -97,35 +97,35 @@ 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: +allocate ({github-pr-url}/59[PR#59^]). +* 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. ** All containers have been updated to support heterogeneous `erase` and `extract`. -* Changed behavior of `reserve` to eagerly +* Improved {cpp}23 support: allocate ({github-pr-url}/59[PR#59^]). +* All containers have been updated to support heterogeneous `erase` and `extract`. +* Changed behavior of `reserve` to eagerly * 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. +will work. +* Improved {cpp}20 support: +and other uses of the Dinkumware standard library, now using Boost.Predef to check compiler and library versions. * Improved {cpp}20 support: -** Use `boost::to_address`, which has the proposed {cpp}20 semantics, rather than the old custom implementation. +in order to remove dependency on Boost.Iterator. +* Use `boost::to_address`, which has the proposed {cpp}20 semantics, rather than the old custom implementation. +deprecated in {cpp}17, thanks to Daniela Engert ({github-pr-url}/7[PR#7^]). * Add `element_type` to iterators, so that `std::pointer_traits` -will work. +in order to remove dependency on Boost.Iterator. * 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. +deprecated in {cpp}17, thanks to Daniela Engert ({github-pr-url}/7[PR#7^]). * 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 From 82963051a866d7a35a1bfb828c998958768a091e Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:28 +0000 Subject: [PATCH 21/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_node_set_zh_Hans.adoc | 1104 +++++++++++++++++ 1 file changed, 1104 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc new file mode 100644 index 0000000..e1e5e27 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc @@ -0,0 +1,1104 @@ +[#unordered_node_set] +== Class Template unordered_node_set + +:idprefix: unordered_node_set_ + +`boost::unordered_node_set` — A node-based, open-addressing unordered associative container that stores unique values. + +`boost::unordered_node_set` uses an open-addressing layout like `boost::unordered_flat_set`, but, being node-based, it provides pointer stability and node handling functionalities. Its performance lies between those of `boost::unordered_set` and `boost::unordered_flat_set`. + +As a result of its using open addressing, the interface of `boost::unordered_node_set` deviates in a number of aspects from that of `boost::unordered_set`/`std::unordered_set`: + +- `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`). - The maximum load factor of the container is managed internally and can't be set by the user. + +Other than this, `boost::unordered_node_set` is mostly a drop-in replacement of standard unordered associative containers. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_node_set.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class unordered_node_set { + public: + // types + using key_type = Key; + using value_type = Key; + using init_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled] + + // construct/copy/destroy + xref:#unordered_node_set_default_constructor[unordered_node_set](); + explicit xref:#unordered_node_set_bucket_count_constructor[unordered_node_set](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_node_set_iterator_range_constructor[unordered_node_set](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_node_set_copy_constructor[unordered_node_set](const unordered_node_set& other); + xref:#unordered_node_set_move_constructor[unordered_node_set](unordered_node_set&& other); + template + xref:#unordered_node_set_iterator_range_constructor_with_allocator[unordered_node_set](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_node_set_allocator_constructor[unordered_node_set](const Allocator& a); + xref:#unordered_node_set_copy_constructor_with_allocator[unordered_node_set](const unordered_node_set& other, const Allocator& a); + xref:#unordered_node_set_move_constructor_with_allocator[unordered_node_set](unordered_node_set&& other, const Allocator& a); + xref:#unordered_node_set_move_constructor_from_concurrent_node_set[unordered_node_set](concurrent_node_set&& other); + xref:#unordered_node_set_initializer_list_constructor[unordered_node_set](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_node_set_bucket_count_constructor_with_allocator[unordered_node_set](size_type n, const allocator_type& a); + xref:#unordered_node_set_bucket_count_constructor_with_hasher_and_allocator[unordered_node_set](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_node_set_iterator_range_constructor_with_bucket_count_and_allocator[unordered_node_set](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_node_set_iterator_range_constructor_with_bucket_count_and_hasher[unordered_node_set](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_node_set_initializer_list_constructor_with_allocator[unordered_node_set](std::initializer_list il, const allocator_type& a); + xref:#unordered_node_set_initializer_list_constructor_with_bucket_count_and_allocator[unordered_node_set](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#unordered_node_set_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_node_set](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_node_set_destructor[~unordered_node_set](); + unordered_node_set& xref:#unordered_node_set_copy_assignment[operator++=++](const unordered_node_set& other); + unordered_node_set& xref:#unordered_node_set_move_assignment[operator++=++](unordered_node_set&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + unordered_node_set& xref:#unordered_node_set_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#unordered_node_set_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_node_set_begin[begin]() noexcept; + const_iterator xref:#unordered_node_set_begin[begin]() const noexcept; + iterator xref:#unordered_node_set_end[end]() noexcept; + const_iterator xref:#unordered_node_set_end[end]() const noexcept; + const_iterator xref:#unordered_node_set_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_node_set_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_node_set_empty[empty]() const noexcept; + size_type xref:#unordered_node_set_size[size]() const noexcept; + size_type xref:#unordered_node_set_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_node_set_emplace[emplace](Args&&... args); + template iterator xref:#unordered_node_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_node_set_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_node_set_move_insert[insert](value_type&& obj); + template std::pair xref:#unordered_node_set_transparent_insert[insert](K&& k); + iterator xref:#unordered_node_set_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_node_set_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template iterator xref:#unordered_node_set_transparent_insert_with_hint[insert](const_iterator hint, K&& k); + template void xref:#unordered_node_set_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_node_set_insert_initializer_list[insert](std::initializer_list); + insert_return_type xref:#unordered_node_set_insert_node[insert](node_type&& nh); + iterator xref:#unordered_node_set_insert_node_with_hint[insert](const_iterator hint, node_type&& nh); + + _convertible-to-iterator_ xref:#unordered_node_set_erase_by_position[erase](iterator position); + _convertible-to-iterator_ xref:#unordered_node_set_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_node_set_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_node_set_erase_by_key[erase](K&& k); + iterator xref:#unordered_node_set_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_node_set_swap[swap](unordered_node_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + node_type xref:#unordered_node_set_extract_by_position[extract](const_iterator position); + node_type xref:#unordered_node_set_extract_by_key[extract](const key_type& key); + template node_type xref:#unordered_node_set_extract_by_key[extract](K&& key); + init_type xref:#unordered_node_set_pull[pull](const_iterator position); + void xref:#unordered_node_set_clear[clear]() noexcept; + + template + void xref:#unordered_node_set_merge[merge](unordered_node_set& source); + template + void xref:#unordered_node_set_merge[merge](unordered_node_set&& source); + + // observers + hasher xref:#unordered_node_set_hash_function[hash_function]() const; + key_equal xref:#unordered_node_set_key_eq[key_eq]() const; + + // set operations + iterator xref:#unordered_node_set_find[find](const key_type& k); + const_iterator xref:#unordered_node_set_find[find](const key_type& k) const; + template + iterator xref:#unordered_node_set_find[find](const K& k); + template + const_iterator xref:#unordered_node_set_find[find](const K& k) const; + size_type xref:#unordered_node_set_count[count](const key_type& k) const; + template + size_type xref:#unordered_node_set_count[count](const K& k) const; + bool xref:#unordered_node_set_contains[contains](const key_type& k) const; + template + bool xref:#unordered_node_set_contains[contains](const K& k) const; + std::pair xref:#unordered_node_set_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_node_set_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_node_set_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_node_set_equal_range[equal_range](const K& k) const; + + // bucket interface + size_type xref:#unordered_node_set_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#unordered_node_set_load_factor[load_factor]() const noexcept; + float xref:#unordered_node_set_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_node_set_set_max_load_factor[max_load_factor](float z); + size_type xref:#unordered_node_set_max_load[max_load]() const noexcept; + void xref:#unordered_node_set_rehash[rehash](size_type n); + void xref:#unordered_node_set_reserve[reserve](size_type n); + + // statistics (if xref:unordered_node_set_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_node_set_get_stats[get_stats]() const; + void xref:#unordered_node_set_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_node_set(InputIterator, InputIterator, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type = xref:#unordered_node_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_node_set, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + unordered_node_set(std::initializer_list, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type = xref:#unordered_node_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_node_set; + + template + unordered_node_set(InputIterator, InputIterator, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_node_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_node_set(InputIterator, InputIterator, Allocator) + -> unordered_node_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_node_set(InputIterator, InputIterator, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_node_set, Hash, + std::equal_to>, Allocator>; + + template + unordered_node_set(std::initializer_list, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_node_set, std::equal_to, Allocator>; + + template + unordered_node_set(std::initializer_list, Allocator) + -> unordered_node_set, std::equal_to, Allocator>; + + template + unordered_node_set(std::initializer_list, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_node_set, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The element nodes of the container are held into an internal _bucket array_. A node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_node_set(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_node_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_node_set(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_node_set(unordered_node_set const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_node_set(unordered_node_set&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_node_set(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_node_set(Allocator const& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_node_set(unordered_node_set const& other, Allocator const& a); ``` + +Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_node_set(unordered_node_set&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Move Constructor from concurrent_node_set + +```c++ unordered_node_set(concurrent_node_set&& other); ``` + +Move construction from a xref:#concurrent_node_set[`concurrent_node_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; Constant time. Concurrency:;; Blocking on `other`. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_node_set(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_node_set(size_type n, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_node_set(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_node_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + unordered_node_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_node_set(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_node_set(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_node_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_node_set(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_node_set& operator=(unordered_node_set const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +--- + +==== Move Assignment +```c++ unordered_node_set& operator=(unordered_node_set&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Initializer List Assignment +```c++ unordered_node_set& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +`position` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Transparent Insert +```c++ template std::pair insert(K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Transparent Insert with Hint +```c++ template std::pair insert(const_iterator hint, K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Node +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.value()`. `nh` is empty when the function returns. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `position`, `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false`, `position` is `end()`, and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true, `position` points to the inserted element, and `node` is empty. +* If the insertion failed, `inserted` is false, `node` has the previous value of `nh`, and `position` points to an element with a key equivalent to `nh.value()`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== Insert Node with Hint +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.value()`. `nh` becomes empty if insertion took place, otherwise it is not changed. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; The iterator returned is `end()` if `nh` is empty. If insertion took place, then the iterator points to the newly inserted element; otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== Erase by Position + +[source,c++,subs=+quotes] +---- +_convertible-to-iterator_ erase(iterator position); +_convertible-to-iterator_ erase(const_iterator position); +---- + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). + +--- + +==== swap +```c++ void swap(unordered_node_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +==== Extract by Position +```c++ node_type extract(const_iterator position); ``` + +Extracts the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element. Throws:;; Nothing. + +--- + +==== Extract by Key +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Extracts the element with key equivalent to `k`, if it exists. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== pull +```c++ init_type pull(const_iterator position); ``` + +Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` + +--- + +==== merge +```c++ template void merge(unordered_node_set& source); template void merge(unordered_node_set&& source); ``` + +Transfers all the element nodes from `source` whose key is not already present in `*this`. + +[horizontal] +Requires:;; `this\->get_allocator() == source.get_allocator()`. Notes:;; Invalidates iterators to the elements transferred. If the resulting size of `*this` is greater than its original maximum load, invalidates all iterators associated to `*this`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The container's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the container's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. + +Invalidates iterators and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_node_set& x, const unordered_node_set& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_node_set& x, const unordered_node_set& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +=== Swap +```c++ template void swap(unordered_node_set& x, unordered_node_set& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +=== erase_if +```c++ template typename unordered_node_set::size_type erase_if(unordered_node_set& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + +=== Serialization + +``unordered_node_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_node_set to an archive + +Saves all the elements of an `unordered_node_set` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_node_set from an archive + +Deletes all preexisting elements of an `unordered_node_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_node_set` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_node_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_node_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From d927e6adfaf6bbb93320526432c21353753a1dbb Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:37 +0000 Subject: [PATCH 22/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_node_map_zh_Hans.adoc | 1262 +++++++++++++++++ 1 file changed, 1262 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc new file mode 100644 index 0000000..d8b0f72 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc @@ -0,0 +1,1262 @@ +[#unordered_node_map] +== Class Template unordered_node_map + +:idprefix: unordered_node_map_ + +`boost::unordered_node_map` — A node-based, open-addressing unordered associative container that associates unique keys with another value. + +`boost::unordered_node_map` uses an open-addressing layout like `boost::unordered_flat_map`, but, being node-based, it provides pointer stability and node handling functionalities. Its performance lies between those of `boost::unordered_map` and `boost::unordered_flat_map`. + +As a result of its using open addressing, the interface of `boost::unordered_node_map` deviates in a number of aspects from that of `boost::unordered_map`/`std::unordered_map`: + +- `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`). - The maximum load factor of the container is managed internally and can't be set by the user. + +Other than this, `boost::unordered_node_map` is mostly a drop-in replacement of standard unordered associative containers. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_node_map.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class unordered_node_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using init_type = std::pair< + typename std::remove_const::type, + typename std::remove_const::type + >; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled] + + // construct/copy/destroy + xref:#unordered_node_map_default_constructor[unordered_node_map](); + explicit xref:#unordered_node_map_bucket_count_constructor[unordered_node_map](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_node_map_iterator_range_constructor[unordered_node_map](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_node_map_copy_constructor[unordered_node_map](const unordered_node_map& other); + xref:#unordered_node_map_move_constructor[unordered_node_map](unordered_node_map&& other); + template + xref:#unordered_node_map_iterator_range_constructor_with_allocator[unordered_node_map](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_node_map_allocator_constructor[unordered_node_map](const Allocator& a); + xref:#unordered_node_map_copy_constructor_with_allocator[unordered_node_map](const unordered_node_map& other, const Allocator& a); + xref:#unordered_node_map_move_constructor_with_allocator[unordered_node_map](unordered_node_map&& other, const Allocator& a); + xref:#unordered_node_map_move_constructor_from_concurrent_node_map[unordered_node_map](concurrent_node_map&& other); + xref:#unordered_node_map_initializer_list_constructor[unordered_node_map](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_node_map_bucket_count_constructor_with_allocator[unordered_node_map](size_type n, const allocator_type& a); + xref:#unordered_node_map_bucket_count_constructor_with_hasher_and_allocator[unordered_node_map](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_node_map_iterator_range_constructor_with_bucket_count_and_allocator[unordered_node_map](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_node_map_iterator_range_constructor_with_bucket_count_and_hasher[unordered_node_map](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_node_map_initializer_list_constructor_with_allocator[unordered_node_map](std::initializer_list il, const allocator_type& a); + xref:#unordered_node_map_initializer_list_constructor_with_bucket_count_and_allocator[unordered_node_map](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#unordered_node_map_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_node_map](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_node_map_destructor[~unordered_node_map](); + unordered_node_map& xref:#unordered_node_map_copy_assignment[operator++=++](const unordered_node_map& other); + unordered_node_map& xref:#unordered_node_map_move_assignment[operator++=++](unordered_node_map&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + unordered_node_map& xref:#unordered_node_map_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#unordered_node_map_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_node_map_begin[begin]() noexcept; + const_iterator xref:#unordered_node_map_begin[begin]() const noexcept; + iterator xref:#unordered_node_map_end[end]() noexcept; + const_iterator xref:#unordered_node_map_end[end]() const noexcept; + const_iterator xref:#unordered_node_map_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_node_map_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_node_map_empty[empty]() const noexcept; + size_type xref:#unordered_node_map_size[size]() const noexcept; + size_type xref:#unordered_node_map_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_node_map_emplace[emplace](Args&&... args); + template iterator xref:#unordered_node_map_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_node_map_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_node_map_copy_insert[insert](const init_type& obj); + std::pair xref:#unordered_node_map_move_insert[insert](value_type&& obj); + std::pair xref:#unordered_node_map_move_insert[insert](init_type&& obj); + iterator xref:#unordered_node_map_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_node_map_copy_insert_with_hint[insert](const_iterator hint, const init_type& obj); + iterator xref:#unordered_node_map_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + iterator xref:#unordered_node_map_copy_insert_with_hint[insert](const_iterator hint, init_type&& obj); + template void xref:#unordered_node_map_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_node_map_insert_initializer_list[insert](std::initializer_list); + insert_return_type xref:#unordered_node_map_insert_node[insert](node_type&& nh); + iterator xref:#unordered_node_map_insert_node_with_hint[insert](const_iterator hint, node_type&& nh); + + template + std::pair xref:#unordered_node_map_try_emplace[try_emplace](const key_type& k, Args&&... args); + template + std::pair xref:#unordered_node_map_try_emplace[try_emplace](key_type&& k, Args&&... args); + template + std::pair xref:#unordered_node_map_try_emplace[try_emplace](K&& k, Args&&... args); + template + iterator xref:#unordered_node_map_try_emplace_with_hint[try_emplace](const_iterator hint, const key_type& k, Args&&... args); + template + iterator xref:#unordered_node_map_try_emplace_with_hint[try_emplace](const_iterator hint, key_type&& k, Args&&... args); + template + iterator xref:#unordered_node_map_try_emplace_with_hint[try_emplace](const_iterator hint, K&& k, Args&&... args); + template + std::pair xref:#unordered_node_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj); + template + std::pair xref:#unordered_node_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj); + template + std::pair xref:#unordered_node_map_insert_or_assign[insert_or_assign](K&& k, M&& obj); + template + iterator xref:#unordered_node_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, const key_type& k, M&& obj); + template + iterator xref:#unordered_node_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, key_type&& k, M&& obj); + template + iterator xref:#unordered_node_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj); + + _convertible-to-iterator_ xref:#unordered_node_map_erase_by_position[erase](iterator position); + _convertible-to-iterator_ xref:#unordered_node_map_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_node_map_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_node_map_erase_by_key[erase](K&& k); + iterator xref:#unordered_node_map_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_node_map_swap[swap](unordered_node_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + node_type xref:#unordered_node_map_extract_by_position[extract](const_iterator position); + node_type xref:#unordered_node_map_extract_by_key[extract](const key_type& key); + template node_type xref:#unordered_node_map_extract_by_key[extract](K&& key); + init_type xref:#unordered_node_map_pull[pull](const_iterator position); + void xref:#unordered_node_map_clear[clear]() noexcept; + + template + void xref:#unordered_node_map_merge[merge](unordered_node_map& source); + template + void xref:#unordered_node_map_merge[merge](unordered_node_map&& source); + + // observers + hasher xref:#unordered_node_map_hash_function[hash_function]() const; + key_equal xref:#unordered_node_map_key_eq[key_eq]() const; + + // map operations + iterator xref:#unordered_node_map_find[find](const key_type& k); + const_iterator xref:#unordered_node_map_find[find](const key_type& k) const; + template + iterator xref:#unordered_node_map_find[find](const K& k); + template + const_iterator xref:#unordered_node_map_find[find](const K& k) const; + size_type xref:#unordered_node_map_count[count](const key_type& k) const; + template + size_type xref:#unordered_node_map_count[count](const K& k) const; + bool xref:#unordered_node_map_contains[contains](const key_type& k) const; + template + bool xref:#unordered_node_map_contains[contains](const K& k) const; + std::pair xref:#unordered_node_map_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_node_map_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_node_map_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_node_map_equal_range[equal_range](const K& k) const; + + // element access + mapped_type& xref:#unordered_node_map_operator[operator[+]+](const key_type& k); + mapped_type& xref:#unordered_node_map_operator[operator[+]+](key_type&& k); + template mapped_type& xref:#unordered_node_map_operator[operator[+]+](K&& k); + mapped_type& xref:#unordered_node_map_at[at](const key_type& k); + const mapped_type& xref:#unordered_node_map_at[at](const key_type& k) const; + template mapped_type& xref:#unordered_node_map_at[at](const K& k); + template const mapped_type& xref:#unordered_node_map_at[at](const K& k) const; + + // bucket interface + size_type xref:#unordered_node_map_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#unordered_node_map_load_factor[load_factor]() const noexcept; + float xref:#unordered_node_map_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_node_map_set_max_load_factor[max_load_factor](float z); + size_type xref:#unordered_node_map_max_load[max_load]() const noexcept; + void xref:#unordered_node_map_rehash[rehash](size_type n); + void xref:#unordered_node_map_reserve[reserve](size_type n); + + // statistics (if xref:unordered_node_map_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_node_map_get_stats[get_stats]() const; + void xref:#unordered_node_map_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_node_map(InputIterator, InputIterator, typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type = xref:#unordered_node_map_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_node_map, xref:#unordered_node_map_iter_mapped_type[__iter-mapped-type__], Hash, + Pred, Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + unordered_node_map(std::initializer_list>, + typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type = xref:#unordered_node_map_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_node_map; + + template + unordered_node_map(InputIterator, InputIterator, typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_node_map, xref:#unordered_node_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_node_map(InputIterator, InputIterator, Allocator) + -> unordered_node_map, xref:#unordered_node_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_node_map(InputIterator, InputIterator, typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_node_map, xref:#unordered_node_map_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + unordered_node_map(std::initializer_list>, typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type, + Allocator) + -> unordered_node_map, std::equal_to, Allocator>; + + template + unordered_node_map(std::initializer_list>, Allocator) + -> unordered_node_map, std::equal_to, Allocator>; + + template + unordered_node_map(std::initializer_list>, typename xref:#unordered_node_map_deduction_guides[__see below__]::size_type, + Hash, Allocator) + -> unordered_node_map, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +.2+|`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] +into the container from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_T_ + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The element nodes of the container are held into an internal _bucket array_. A node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +An iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_node_map(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_node_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_node_map(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_node_map(unordered_node_map const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +--- + +==== Move Constructor +```c++ unordered_node_map(unordered_node_map&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_node_map(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_node_map(Allocator const& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_node_map(unordered_node_map const& other, Allocator const& a); ``` + +Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_node_map(unordered_node_map&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Move Constructor from concurrent_node_map + +```c++ unordered_node_map(concurrent_node_map&& other); ``` + +Move construction from a xref:#concurrent_node_map[`concurrent_node_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; Constant time. Concurrency:;; Blocking on `other`. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_node_map(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_node_map(size_type n, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_node_map(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_node_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + unordered_node_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_node_map(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_node_map(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_node_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_node_map(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_node_map& operator=(unordered_node_map const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +--- + +==== Move Assignment +```c++ unordered_node_map& operator=(unordered_node_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Initializer List Assignment +```c++ unordered_node_map& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when `key_type` is move constructible or when the `k` argument is a `key_type`. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +`position` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when `key_type` is move constructible or when the `k` argument is a `key_type`. + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Node +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.key()`. `nh` is empty when the function returns. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `position`, `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false`, `position` is `end()`, and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true, `position` points to the inserted element, and `node` is empty. +* If the insertion failed, `inserted` is false, `node` has the previous value of `nh`, and `position` points to an element with a key equivalent to `nh.key()`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== Insert Node with Hint +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.key()`. `nh` becomes empty if insertion took place, otherwise it is not changed. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; The iterator returned is `end()` if `nh` is empty. If insertion took place, then the iterator points to the newly inserted element; otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== try_emplace +```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args); ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +[horizontal] +Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_node_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#unordered_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. + +Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace with Hint +```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_node_map_emplace_hint[emplace_hint], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#unordered_node_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. + +Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== insert_or_assign +```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +[horizontal] +Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== insert_or_assign with Hint +```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + + +==== Erase by Position + +[source,c++,subs=+quotes] +---- +_convertible-to-iterator_ erase(iterator position); +_convertible-to-iterator_ erase(const_iterator position); +---- + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). + +--- + +==== swap +```c++ void swap(unordered_node_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +==== Extract by Position +```c++ node_type extract(const_iterator position); ``` + +Extracts the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element. Throws:;; Nothing. + +--- + +==== Extract by Key +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Extracts the element with key equivalent to `k`, if it exists. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== pull +```c++ init_type pull(const_iterator position); ``` + +Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` + +--- + +==== merge +```c++ template void merge(unordered_node_map& source); template void merge(unordered_node_map&& source); ``` + +Transfers all the element nodes from `source` whose key is not already present in `*this`. + +[horizontal] +Requires:;; `this\->get_allocator() == source.get_allocator()`. Notes:;; Invalidates iterators to the elements transferred. If the resulting size of `*this` is greater than its original maximum load, invalidates all iterators associated to `*this`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The container's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== operator++[++++]++ +```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` + +[horizontal] +Effects:;; If the container does not already contain an element with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== at +```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` + +[horizontal] +Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the container's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. + +Invalidates iterators and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#unordered_node_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#unordered_node_map_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#unordered_node_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_node_map& x, const unordered_node_map& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_node_map& x, const unordered_node_map& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +=== Swap +```c++ template void swap(unordered_node_map& x, unordered_node_map& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +=== erase_if +```c++ template typename unordered_node_map::size_type erase_if(unordered_node_map& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. + +=== Serialization + +``unordered_node_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_node_map to an archive + +Saves all the elements of an `unordered_node_map` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_node_map from an archive + +Deletes all preexisting elements of an `unordered_node_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_node_map` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `key_type` and `mapped_type` are constructible from `std::remove_const::type&&` and `std::remove_const::type&&`, respectively. `x.key_equal()` is functionally equivalent to `other.key_equal()`. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_node_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_node_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From 6d0c31ee324dee516647b24e86e3e43436de2c59 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:43 +0000 Subject: [PATCH 23/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_multiset_zh_Hans.adoc | 1134 +++++++++++++++++ 1 file changed, 1134 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc new file mode 100644 index 0000000..a8433d8 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc @@ -0,0 +1,1134 @@ +[#unordered_multiset] +== Class Template unordered_multiset + +:idprefix: unordered_multiset_ + +`boost::unordered_multiset` — An unordered associative container that stores values. The same key can be stored multiple times. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_set.adoc[] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class unordered_multiset { + public: + // types + using key_type = Key; + using value_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + using local_iterator = _implementation-defined_; + using const_local_iterator = _implementation-defined_; + using node_type = _implementation-defined_; + + // construct/copy/destroy + xref:#unordered_multiset_default_constructor[unordered_multiset](); + explicit xref:#unordered_multiset_bucket_count_constructor[unordered_multiset](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_multiset_iterator_range_constructor[unordered_multiset](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_multiset_copy_constructor[unordered_multiset](const unordered_multiset& other); + xref:#unordered_multiset_move_constructor[unordered_multiset](unordered_multiset&& other); + template + xref:#unordered_multiset_iterator_range_constructor_with_allocator[unordered_multiset](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_multiset_allocator_constructor[unordered_multiset](const Allocator& a); + xref:#unordered_multiset_copy_constructor_with_allocator[unordered_multiset](const unordered_multiset& other, const Allocator& a); + xref:#unordered_multiset_move_constructor_with_allocator[unordered_multiset](unordered_multiset&& other, const Allocator& a); + xref:#unordered_multiset_initializer_list_constructor[unordered_multiset](std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_multiset_bucket_count_constructor_with_allocator[unordered_multiset](size_type n, const allocator_type& a); + xref:#unordered_multiset_bucket_count_constructor_with_hasher_and_allocator[unordered_multiset](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_multiset_iterator_range_constructor_with_bucket_count_and_allocator[unordered_multiset](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_multiset_iterator_range_constructor_with_bucket_count_and_hasher[unordered_multiset](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_multiset_initializer_list_constructor_with_allocator[unordered_multiset](std::initializer_list il, const allocator_type& a); + xref:#unordered_multiset_initializer_list_constructor_with_bucket_count_and_allocator[unordered_multiset](std::initializer_list il, size_type n, + const allocator_type& a) + xref:#unordered_multiset_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_multiset](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_multiset_destructor[~unordered_multiset()]; + unordered_multiset& xref:#unordered_multiset_copy_assignment[operator++=++](const unordered_multiset& other); + unordered_multiset& xref:#unordered_multiset_move_assignment[operator++=++](unordered_multiset&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + unordered_multiset& xref:#unordered_multiset_initializer_list_assignment[operator++=++](std::initializer_list il); + allocator_type xref:#unordered_multiset_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_multiset_begin[begin]() noexcept; + const_iterator xref:#unordered_multiset_begin[begin]() const noexcept; + iterator xref:#unordered_multiset_end[end]() noexcept; + const_iterator xref:#unordered_multiset_end[end]() const noexcept; + const_iterator xref:#unordered_multiset_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_multiset_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_multiset_empty[empty]() const noexcept; + size_type xref:#unordered_multiset_size[size]() const noexcept; + size_type xref:#unordered_multiset_max_size[max_size]() const noexcept; + + // modifiers + template iterator xref:#unordered_multiset_emplace[emplace](Args&&... args); + template iterator xref:#unordered_multiset_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + iterator xref:#unordered_multiset_copy_insert[insert](const value_type& obj); + iterator xref:#unordered_multiset_move_insert[insert](value_type&& obj); + iterator xref:#unordered_multiset_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_multiset_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template void xref:#unordered_multiset_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_multiset_insert_initializer_list[insert](std::initializer_list il); + + node_type xref:#unordered_multiset_extract_by_iterator[extract](const_iterator position); + node_type xref:#unordered_multiset_extract_by_value[extract](const key_type& k); + template node_type xref:#unordered_multiset_extract_by_value[extract](K&& k); + iterator xref:#unordered_multiset_insert_with_node_handle[insert](node_type&& nh); + iterator xref:#unordered_multiset_insert_with_hint_and_node_handle[insert](const_iterator hint, node_type&& nh); + + iterator xref:#unordered_multiset_erase_by_position[erase](iterator position); + iterator xref:#unordered_multiset_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_multiset_erase_by_value[erase](const key_type& k); + template size_type xref:#unordered_multiset_erase_by_value[erase](K&& x); + iterator xref:#unordered_multiset_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_multiset_quick_erase[quick_erase](const_iterator position); + void xref:#unordered_multiset_erase_return_void[erase_return_void](const_iterator position); + void xref:#unordered_multiset_swap[swap](unordered_multiset&) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); + void xref:#unordered_multiset_clear[clear]() noexcept; + + template + void xref:#unordered_multiset_merge[merge](unordered_multiset& source); + template + void xref:#unordered_multiset_merge[merge](unordered_multiset&& source); + template + void xref:#unordered_multiset_merge[merge](unordered_set& source); + template + void xref:#unordered_multiset_merge[merge](unordered_set&& source); + + // observers + hasher xref:#unordered_multiset_hash_function[hash_function]() const; + key_equal xref:#unordered_multiset_key_eq[key_eq]() const; + + // set operations + iterator xref:#unordered_multiset_find[find](const key_type& k); + const_iterator xref:#unordered_multiset_find[find](const key_type& k) const; + template + iterator xref:#unordered_multiset_find[find](const K& k); + template + const_iterator xref:#unordered_multiset_find[find](const K& k) const; + template + iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, + CompatiblePredicate const&); + template + const_iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, + CompatiblePredicate const&) const; + size_type xref:#unordered_multiset_count[count](const key_type& k) const; + template + size_type xref:#unordered_multiset_count[count](const K& k) const; + bool xref:#unordered_multiset_contains[contains](const key_type& k) const; + template + bool xref:#unordered_multiset_contains[contains](const K& k) const; + std::pair xref:#unordered_multiset_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_multiset_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_multiset_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_multiset_equal_range[equal_range](const K& k) const; + + // bucket interface + size_type xref:#unordered_multiset_bucket_count[bucket_count]() const noexcept; + size_type xref:#unordered_multiset_max_bucket_count[max_bucket_count]() const noexcept; + size_type xref:#unordered_multiset_bucket_size[bucket_size](size_type n) const; + size_type xref:#unordered_multiset_bucket[bucket](const key_type& k) const; + template size_type xref:#unordered_multiset_bucket[bucket](const K& k) const; + local_iterator xref:#unordered_multiset_begin_2[begin](size_type n); + const_local_iterator xref:#unordered_multiset_begin_2[begin](size_type n) const; + local_iterator xref:#unordered_multiset_end_2[end](size_type n); + const_local_iterator xref:#unordered_multiset_end_2[end](size_type n) const; + const_local_iterator xref:#unordered_multiset_cbegin_2[cbegin](size_type n) const; + const_local_iterator xref:#unordered_multiset_cend_2[cend](size_type n) const; + + // hash policy + float xref:#unordered_multiset_load_factor[load_factor]() const noexcept; + float xref:#unordered_multiset_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_multiset_set_max_load_factor[max_load_factor](float z); + void xref:#unordered_multiset_rehash[rehash](size_type n); + void xref:#unordered_multiset_reserve[reserve](size_type n); + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_multiset(InputIterator, InputIterator, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type = xref:#unordered_multiset_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + unordered_multiset(std::initializer_list, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type = xref:#unordered_multiset_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multiset; + + template + unordered_multiset(InputIterator, InputIterator, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_multiset, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_multiset(InputIterator, InputIterator, Allocator) + -> unordered_multiset, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_multiset(InputIterator, InputIterator, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_multiset, Hash, + std::equal_to>, Allocator>; + + template + unordered_multiset(std::initializer_list, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_multiset, std::equal_to, Allocator>; + + template + unordered_multiset(std::initializer_list, Allocator) + -> unordered_multiset, std::equal_to, Allocator>; + + template + unordered_multiset(std::initializer_list, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_multiset, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements are organized into buckets. Keys with the same hash code are stored in the same bucket and elements with equivalent keys are stored next to each other. + +The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. + +=== Configuration macros + +==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` + +Globally define this macro to support loading of ``unordered_multiset``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ local_iterator; +---- + +An iterator with the same value type, difference type and pointer and reference type as iterator. + +A `local_iterator` object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_local_iterator; +---- + +A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. + +A const_local_iterator object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +See node_handle_set for details. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_multiset(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_multiset(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_multiset(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_multiset(const unordered_multiset& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_multiset(unordered_multiset&& other); ``` + +The move constructor. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_multiset(const Allocator& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_multiset(const unordered_multiset& other, const Allocator& a); ``` + +Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_multiset(unordered_multiset&& other, const Allocator& a); ``` + +Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_multiset(std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_multiset(size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- +template + unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_multiset(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_multiset(std::initializer_list il, size_type n, const allocator_type& a) ``` + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_multiset(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_multiset(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_multiset& operator=(const unordered_multiset& other); ``` + +The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. + +If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Assignment +```c++ unordered_multiset& operator=(unordered_multiset&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. + +If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is move constructible. + +--- + +==== Initializer List Assignment +```c++ unordered_multiset& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. + +--- + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template iterator emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments args, in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments args, in the container. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Copy Insert +```c++ iterator insert(const value_type& obj); ``` + +Inserts `obj` in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert +```c++ iterator insert(value_type&& obj); ``` + +Inserts `obj` in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` + +Inserts `obj` in the container. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list il); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Extract by Iterator +```c++ node_type extract(const_iterator position); ``` + +Removes the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. + +--- + +==== Extract by Value +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Removes an element with key equivalent to `k`. + +[horizontal] +Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert with `node_handle` +```c++ iterator insert(node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh`. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_set`. + +--- + +==== Insert with Hint and `node_handle` +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh`. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_set`. + +--- + +==== Erase by Position + +```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. + +--- + +==== Erase by Value +```c++ size_type erase(const key_type& k); template size_type erase(K&& x); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. + +--- + +==== quick_erase +```c++ void quick_erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== erase_return_void +```c++ void erase_return_void(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== swap +```c++ void swap(unordered_multiset&) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0` Throws:;; Never throws an exception. + +--- + +==== merge +```c++ template void merge(unordered_multiset& source); template void merge(unordered_multiset&& source); template void merge(unordered_set& source); template void merge(unordered_set&& source); ``` + +Attempt to "merge" two containers by iterating `source` and extracting all nodes in `source` and inserting them into `*this`. + +Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. + +The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. + +This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. + +[horizontal] +Notes:;; + -- +* Pointers and references to transferred elements remain valid. +* Invalidates iterators to transferred elements. +* Invalidates iterators belonging to `*this`. +* Iterators to non-transferred elements in `source` remain valid. +-- + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq + +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&); template const_iterator find(CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&) const; ``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The number of buckets. + +--- + +==== max_bucket_count +```c++ size_type max_bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; An upper bound on the number of buckets. + +--- + +==== bucket_size +```c++ size_type bucket_size(size_type n) const; ``` + +[horizontal] +Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. + +--- + +==== bucket +```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` + +[horizontal] +Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== begin + +```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. + +--- + +==== end +```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +==== cbegin +```c++ const_local_iterator cbegin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. + +--- + +==== cend +```c++ const_local_iterator cend(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; The average number of elements per bucket. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the current maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Changes the container's maximum load factor, using `z` as a hint. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_multiset& x, const unordered_multiset& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_multiset& x, const unordered_multiset& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +=== erase_if +```c++ template typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + +=== Serialization + +``unordered_multiset``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_multiset to an archive + +Saves all the elements of an `unordered_multiset` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_multiset from an archive + +Deletes all preexisting elements of an `unordered_multiset` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_multiset` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_multiset` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_multiset` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From 18904368e4363915933177e2ebc654a7a1ab2c78 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:19:56 +0000 Subject: [PATCH 24/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_multimap_zh_Hans.adoc | 1193 +++++++++++++++++ 1 file changed, 1193 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc new file mode 100644 index 0000000..851edeb --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc @@ -0,0 +1,1193 @@ +[#unordered_multimap] +== Class Template unordered_multimap + +:idprefix: unordered_multimap_ + +`boost::unordered_multimap` — An unordered associative container that associates keys with another value. The same key can be stored multiple times. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_map.adoc[] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class unordered_multimap { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + using local_iterator = _implementation-defined_; + using const_local_iterator = _implementation-defined_; + using node_type = _implementation-defined_; + + // construct/copy/destroy + xref:#unordered_multimap_default_constructor[unordered_multimap](); + explicit xref:#unordered_multimap_bucket_count_constructor[unordered_multimap](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_multimap_iterator_range_constructor[unordered_multimap](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_multimap_copy_constructor[unordered_multimap](const unordered_multimap& other); + xref:#unordered_multimap_move_constructor[unordered_multimap](unordered_multimap&& other); + template + xref:#unordered_multimap_iterator_range_constructor_with_allocator[unordered_multimap](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_multimap_allocator_constructor[unordered_multimap](const Allocator& a); + xref:#unordered_multimap_copy_constructor_with_allocator[unordered_multimap](const unordered_multimap& other, const Allocator& a); + xref:#unordered_multimap_move_constructor_with_allocator[unordered_multimap](unordered_multimap&& other, const Allocator& a); + xref:#unordered_multimap_initializer_list_constructor[unordered_multimap](std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_multimap_bucket_count_constructor_with_allocator[unordered_multimap](size_type n, const allocator_type& a); + xref:#unordered_multimap_bucket_count_constructor_with_hasher_and_allocator[unordered_multimap](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_multimap_iterator_range_constructor_with_bucket_count_and_allocator[unordered_multimap](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_multimap_iterator_range_constructor_with_bucket_count_and_hasher[unordered_multimap](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_multimap_initializer_list_constructor_with_allocator[unordered_multimap](std::initializer_list il, const allocator_type& a); + xref:#unordered_multimap_initializer_list_constructor_with_bucket_count_and_allocator[unordered_multimap](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#unordered_multimap_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_multimap](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_multimap_destructor[~unordered_multimap](); + unordered_multimap& xref:#unordered_multimap_copy_assignment[operator++=++](const unordered_multimap& other); + unordered_multimap& xref:#unordered_multimap_move_assignment[operator++=++](unordered_multimap&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + unordered_multimap& xref:#unordered_multimap_initializer_list_assignment[operator++=++](std::initializer_list il); + allocator_type xref:#unordered_multimap_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_multimap_begin[begin]() noexcept; + const_iterator xref:#unordered_multimap_begin[begin]() const noexcept; + iterator xref:#unordered_multimap_end[end]() noexcept; + const_iterator xref:#unordered_multimap_end[end]() const noexcept; + const_iterator xref:#unordered_multimap_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_multimap_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_multimap_empty[empty]() const noexcept; + size_type xref:#unordered_multimap_size[size]() const noexcept; + size_type xref:#unordered_multimap_max_size[max_size]() const noexcept; + + // modifiers + template iterator xref:#unordered_multimap_emplace[emplace](Args&&... args); + template iterator xref:#unordered_multimap_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + iterator xref:#unordered_multimap_copy_insert[insert](const value_type& obj); + iterator xref:#unordered_multimap_move_insert[insert](value_type&& obj); + template iterator xref:#unordered_multimap_emplace_insert[insert](P&& obj); + iterator xref:#unordered_multimap_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_multimap_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template iterator xref:#unordered_multimap_emplace_insert_with_hint[insert](const_iterator hint, P&& obj); + template void xref:#unordered_multimap_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_multimap_insert_initializer_list[insert](std::initializer_list il); + + node_type xref:#unordered_multimap_extract_by_iterator[extract](const_iterator position); + node_type xref:#unordered_multimap_extract_by_key[extract](const key_type& k); + template node_type xref:#unordered_multimap_extract_by_key[extract](K&& k); + iterator xref:#unordered_multimap_insert_with_node_handle[insert](node_type&& nh); + iterator xref:#unordered_multimap_insert_with_hint_and_node_handle[insert](const_iterator hint, node_type&& nh); + + iterator xref:#unordered_multimap_erase_by_position[erase](iterator position); + iterator xref:#unordered_multimap_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_multimap_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_multimap_erase_by_key[erase](K&& k); + iterator xref:#unordered_multimap_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_multimap_quick_erase[quick_erase](const_iterator position); + void xref:#unordered_multimap_erase_return_void[erase_return_void](const_iterator position); + void xref:#unordered_multimap_swap[swap](unordered_multimap& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); + void xref:#unordered_multimap_clear[clear]() noexcept; + + template + void xref:#unordered_multimap_merge[merge](unordered_multimap& source); + template + void xref:#unordered_multimap_merge[merge](unordered_multimap&& source); + template + void xref:#unordered_multimap_merge[merge](unordered_map& source); + template + void xref:#unordered_multimap_merge[merge](unordered_map&& source); + + // observers + hasher xref:#unordered_multimap_hash_function[hash_function]() const; + key_equal xref:#unordered_multimap_key_eq[key_eq]() const; + + // map operations + iterator xref:#unordered_multimap_find[find](const key_type& k); + const_iterator xref:#unordered_multimap_find[find](const key_type& k) const; + template + iterator xref:#unordered_multimap_find[find](const K& k); + template + const_iterator xref:#unordered_multimap_find[find](const K& k) const; + template + iterator xref:#unordered_multimap_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); + template + const_iterator xref:#unordered_multimap_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; + size_type xref:#unordered_multimap_count[count](const key_type& k) const; + template + size_type xref:#unordered_multimap_count[count](const K& k) const; + bool xref:#unordered_multimap_contains[contains](const key_type& k) const; + template + bool xref:#unordered_multimap_contains[contains](const K& k) const; + std::pair xref:#unordered_multimap_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_multimap_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_multimap_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_multimap_equal_range[equal_range](const K& k) const; + + // bucket interface + size_type xref:#unordered_multimap_bucket_count[bucket_count]() const noexcept; + size_type xref:#unordered_multimap_max_bucket_count[max_bucket_count]() const noexcept; + size_type xref:#unordered_multimap_bucket_size[bucket_size](size_type n) const; + size_type xref:#unordered_multimap_bucket[bucket](const key_type& k) const; + template size_type xref:#unordered_multimap_bucket[bucket](const K& k) const; + local_iterator xref:#unordered_multimap_begin_2[begin](size_type n); + const_local_iterator xref:#unordered_multimap_begin_2[begin](size_type n) const; + local_iterator xref:#unordered_multimap_end_2[end](size_type n); + const_local_iterator xref:#unordered_multimap_end_2[end](size_type n) const; + const_local_iterator xref:#unordered_multimap_cbegin_2[cbegin](size_type n) const; + const_local_iterator xref:#unordered_multimap_cend_2[cend](size_type n) const; + + // hash policy + float xref:#unordered_multimap_load_factor[load_factor]() const noexcept; + float xref:#unordered_multimap_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_multimap_max_load_factor[max_load_factor](float z); + void xref:#unordered_multimap_rehash[rehash](size_type n); + void xref:#unordered_multimap_reserve[reserve](size_type n); + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_multimap(InputIterator, InputIterator, typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type = xref:#unordered_multimap_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap, xref:#unordered_multimap_iter_mapped_type[__iter-mapped-type__], Hash, + Pred, Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + unordered_multimap(std::initializer_list>, + typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type = xref:#unordered_multimap_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_multimap; + + template + unordered_multimap(InputIterator, InputIterator, typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_multimap, xref:#unordered_multimap_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, Allocator) + -> unordered_multimap, xref:#unordered_multimap_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_multimap(InputIterator, InputIterator, typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_multimap, xref:#unordered_multimap_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + unordered_multimap(std::initializer_list>, typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type, + Allocator) + -> unordered_multimap, std::equal_to, Allocator>; + + template + unordered_multimap(std::initializer_list>, Allocator) + -> unordered_multimap, std::equal_to, Allocator>; + + template + unordered_multimap(std::initializer_list>, typename xref:#unordered_multimap_deduction_guides[__see below__]::size_type, + Hash, Allocator) + -> unordered_multimap, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_T_ +|`T` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. + +The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. + +=== Configuration macros + +==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` + +Globally define this macro to support loading of ``unordered_multimap``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +An iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ local_iterator; +---- + +An iterator with the same value type, difference type and pointer and reference type as iterator. + +A `local_iterator` object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_local_iterator; +---- + +A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. + +A const_local_iterator object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +See node_handle_map for details. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_multimap(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_multimap(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template +unordered_multimap(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_multimap(const unordered_multimap& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_multimap(unordered_multimap&& other); ``` + +The move constructor. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_multimap(const Allocator& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_multimap(const unordered_multimap& other, const Allocator& a); ``` + +Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_multimap(unordered_multimap&& other, const Allocator& a); ``` + +Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_multimap(std::initializer_list il, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- +==== Bucket Count Constructor with Allocator +```c++ unordered_multimap(size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_multimap(size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- +template + unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_multimap(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_multimap(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_multimap(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_multimap(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_multimap& operator=(const unordered_multimap& other); ``` + +The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. + +If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Assignment +```c++ unordered_multimap& operator=(unordered_multimap&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. + +If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is move constructible. + +--- + +==== Initializer List Assignment +```c++ unordered_multimap& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template iterator emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments args, in the container. + +`position` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Copy Insert +```c++ iterator insert(const value_type& obj); ``` + +Inserts `obj` in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert +```c++ iterator insert(value_type&& obj); ``` + +Inserts `obj` in the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Emplace Insert +```c++ template iterator insert(P&& obj); ``` + +Inserts an element into the container by performing `emplace(std::forward

(value))`. + +Only participates in overload resolution if `std::is_constructible::value` is `true`. + +[horizontal] +Returns:;; An iterator pointing to the inserted element. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Emplace Insert with Hint +```c++ template iterator insert(const_iterator hint, P&& obj); ``` + +Inserts an element into the container by performing `emplace_hint(hint, std::forward

(value))`. + +Only participates in overload resolution if `std::is_constructible::value` is `true`. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Returns:;; An iterator pointing to the inserted element. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list il); ``` + +Inserts a range of elements into the container. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Extract by Iterator +```c++ node_type extract(const_iterator position); ``` + +Removes the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. + +--- + +==== Extract by Key +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Removes an element with key equivalent to `k`. + +[horizontal] +Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert with `node_handle` +```c++ iterator insert(node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh`. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_map`. + +--- + +==== Insert with Hint and `node_handle` +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh`. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_map`. + +--- + +==== Erase by Position + +```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. + +--- + +==== quick_erase +```c++ void quick_erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== erase_return_void +```c++ void erase_return_void(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== swap +```c++ void swap(unordered_multimap& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0` Throws:;; Never throws an exception. + +--- + +==== merge +```c++ template void merge(unordered_multimap& source); template void merge(unordered_multimap&& source); template void merge(unordered_map& source); template void merge(unordered_map&& source); ``` + +Attempt to "merge" two containers by iterating `source` and extracting all nodes in `source` and inserting them into `*this`. + +Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. + +The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. + +This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. + +[horizontal] +Notes:;; + -- +* Pointers and references to transferred elements remain valid. +* Invalidates iterators to transferred elements. +* Invalidates iterators belonging to `*this`. +* Iterators to non-transferred elements in `source` remain valid. +-- + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const; ``` + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The number of buckets. + +--- + +==== max_bucket_count +```c++ size_type max_bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; An upper bound on the number of buckets. + +--- + +==== bucket_size +```c++ size_type bucket_size(size_type n) const; ``` + +[horizontal] +Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. + +--- + +==== bucket +```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` + +[horizontal] +Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== begin + +```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. + +--- + +==== end +```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +==== cbegin +```c++ const_local_iterator cbegin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. + +--- + +==== cend +```c++ const_local_iterator cend(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; The average number of elements per bucket. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the current maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Changes the container's maximum load factor, using `z` as a hint. + +--- + + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#unordered_multimap_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#unordered_multimap_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#unordered_multimap_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_multimap& x, const unordered_multimap& y); ``` + +Return `true` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_multimap& x, const unordered_multimap& y); ``` + +Return `false` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +=== erase_if +```c++ template typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. + +=== Serialization + +``unordered_multimap``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_multimap to an archive + +Saves all the elements of an `unordered_multimap` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_multimap from an archive + +Deletes all preexisting elements of an `unordered_multimap` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_multimap` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `(std::remove_const::type&&, std::remove_const::type&&)`. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_multimap` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_multimap` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From 27b2e02112301b99fa316e78899d0793bc1b2257 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:20:16 +0000 Subject: [PATCH 25/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_map_zh_Hans.adoc | 1358 +++++++++++++++++ 1 file changed, 1358 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc new file mode 100644 index 0000000..74585c9 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc @@ -0,0 +1,1358 @@ +[#unordered_map] +== Class Template unordered_map + +:idprefix: unordered_map_ + +`boost::unordered_map` — An unordered associative container that associates unique keys with another value. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_map.adoc[] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class unordered_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + using local_iterator = _implementation-defined_; + using const_local_iterator = _implementation-defined_; + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + // construct/copy/destroy + xref:#unordered_map_default_constructor[unordered_map](); + explicit xref:#unordered_map_bucket_count_constructor[unordered_map](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_map_iterator_range_constructor[unordered_map](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_map_copy_constructor[unordered_map](const unordered_map& other); + xref:#unordered_map_move_constructor[unordered_map](unordered_map&& other); + template + xref:#unordered_map_iterator_range_constructor_with_allocator[unordered_map](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_map_allocator_constructor[unordered_map](const Allocator& a); + xref:#unordered_map_copy_constructor_with_allocator[unordered_map](const unordered_map& other, const Allocator& a); + xref:#unordered_map_move_constructor_with_allocator[unordered_map](unordered_map&& other, const Allocator& a); + xref:#unordered_map_initializer_list_constructor[unordered_map](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_map_bucket_count_constructor_with_allocator[unordered_map](size_type n, const allocator_type& a); + xref:#unordered_map_bucket_count_constructor_with_hasher_and_allocator[unordered_map](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_map_iterator_range_constructor_with_bucket_count_and_allocator[unordered_map](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_map_iterator_range_constructor_with_bucket_count_and_hasher[unordered_map](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_map_initializer_list_constructor_with_allocator[unordered_map](std::initializer_list il, const allocator_type& a); + xref:#unordered_map_initializer_list_constructor_with_bucket_count_and_allocator[unordered_map](std::initializer_list il, size_type n, const allocator_type& a); + xref:#unordered_map_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_map](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_map_destructor[~unordered_map](); + unordered_map& xref:#unordered_map_copy_assignment[operator++=++](const unordered_map& other); + unordered_map& xref:#unordered_map_move_assignment[operator++=++](unordered_map&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + unordered_map& xref:#unordered_map_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#unordered_map_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_map_begin[begin]() noexcept; + const_iterator xref:#unordered_map_begin[begin]() const noexcept; + iterator xref:#unordered_map_end[end]() noexcept; + const_iterator xref:#unordered_map_end[end]() const noexcept; + const_iterator xref:#unordered_map_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_map_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_map_empty[empty]() const noexcept; + size_type xref:#unordered_map_size[size]() const noexcept; + size_type xref:#unordered_map_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_map_emplace[emplace](Args&&... args); + template iterator xref:#unordered_map_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_map_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_map_move_insert[insert](value_type&& obj); + template std::pair xref:#unordered_map_emplace_insert[insert](P&& obj); + iterator xref:#unordered_map_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_map_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template iterator xref:#unordered_map_emplace_insert_with_hint[insert](const_iterator hint, P&& obj); + template void xref:#unordered_map_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_map_insert_initializer_list[insert](std::initializer_list); + + template + std::pair xref:#unordered_map_try_emplace[try_emplace](const key_type& k, Args&&... args); + template + std::pair xref:#unordered_map_try_emplace[try_emplace](key_type&& k, Args&&... args); + template + std::pair xref:#unordered_map_try_emplace[try_emplace](K&& k, Args&&... args); + template + iterator xref:#unordered_map_try_emplace_with_hint[try_emplace](const_iterator hint, const key_type& k, Args&&... args); + template + iterator xref:#unordered_map_try_emplace_with_hint[try_emplace](const_iterator hint, key_type&& k, Args&&... args); + template + iterator xref:#unordered_map_try_emplace_with_hint[try_emplace](const_iterator hint, K&& k, Args&&... args); + template + std::pair xref:#unordered_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj); + template + std::pair xref:#unordered_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj); + template + std::pair xref:#unordered_map_insert_or_assign[insert_or_assign](K&& k, M&& obj); + template + iterator xref:#unordered_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, const key_type& k, M&& obj); + template + iterator xref:#unordered_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, key_type&& k, M&& obj); + template + iterator xref:#unordered_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj); + + node_type xref:#unordered_map_extract_by_iterator[extract](const_iterator position); + node_type xref:#unordered_map_extract_by_key[extract](const key_type& k); + template node_type xref:#unordered_map_extract_by_key[extract](K&& k); + insert_return_type xref:#unordered_map_insert_with_node_handle[insert](node_type&& nh); + iterator xref:#unordered_map_insert_with_hint_and_node_handle[insert](const_iterator hint, node_type&& nh); + + iterator xref:#unordered_map_erase_by_position[erase](iterator position); + iterator xref:#unordered_map_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_map_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_map_erase_by_key[erase](K&& k); + iterator xref:#unordered_map_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_map_quick_erase[quick_erase](const_iterator position); + void xref:#unordered_map_erase_return_void[erase_return_void](const_iterator position); + void xref:#unordered_map_swap[swap](unordered_map& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); + void xref:#unordered_map_clear[clear]() noexcept; + + template + void xref:#unordered_map_merge[merge](unordered_map& source); + template + void xref:#unordered_map_merge[merge](unordered_map&& source); + template + void xref:#unordered_map_merge[merge](unordered_multimap& source); + template + void xref:#unordered_map_merge[merge](unordered_multimap&& source); + + // observers + hasher xref:#unordered_map_hash_function[hash_function]() const; + key_equal xref:#unordered_map_key_eq[key_eq]() const; + + // map operations + iterator xref:#unordered_map_find[find](const key_type& k); + const_iterator xref:#unordered_map_find[find](const key_type& k) const; + template + iterator xref:#unordered_map_find[find](const K& k); + template + const_iterator xref:#unordered_map_find[find](const K& k) const; + template + iterator xref:#unordered_map_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); + template + const_iterator xref:#unordered_map_find[find](CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; + size_type xref:#unordered_map_count[count](const key_type& k) const; + template + size_type xref:#unordered_map_count[count](const K& k) const; + bool xref:#unordered_map_contains[contains](const key_type& k) const; + template + bool xref:#unordered_map_contains[contains](const K& k) const; + std::pair xref:#unordered_map_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_map_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_map_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_map_equal_range[equal_range](const K& k) const; + + // element access + mapped_type& xref:#unordered_map_operator[operator[+]+](const key_type& k); + mapped_type& xref:#unordered_map_operator[operator[+]+](key_type&& k); + template mapped_type& xref:#unordered_map_operator[operator[+]+](K&& k); + mapped_type& xref:#unordered_map_at[at](const key_type& k); + const mapped_type& xref:#unordered_map_at[at](const key_type& k) const; + template mapped_type& xref:#unordered_map_at[at](const K& k); + template const mapped_type& xref:#unordered_map_at[at](const K& k) const; + + // bucket interface + size_type xref:#unordered_map_bucket_count[bucket_count]() const noexcept; + size_type xref:#unordered_map_max_bucket_count[max_bucket_count]() const noexcept; + size_type xref:#unordered_map_bucket_size[bucket_size](size_type n) const; + size_type xref:#unordered_map_bucket[bucket](const key_type& k) const; + template size_type xref:#unordered_map_bucket[bucket](const K& k) const; + local_iterator xref:#unordered_map_begin_2[begin](size_type n); + const_local_iterator xref:#unordered_map_begin_2[begin](size_type n) const; + local_iterator xref:#unordered_map_end_2[end](size_type n); + const_local_iterator xref:#unordered_map_end_2[end](size_type n) const; + const_local_iterator xref:#unordered_map_cbegin_2[cbegin](size_type n) const; + const_local_iterator xref:#unordered_map_cend_2[cend](size_type n) const; + + // hash policy + float xref:#unordered_map_load_factor[load_factor]() const noexcept; + float xref:#unordered_map_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_map_set_max_load_factor[max_load_factor](float z); + void xref:#unordered_map_rehash[rehash](size_type n); + void xref:#unordered_map_reserve[reserve](size_type n); + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_map(InputIterator, InputIterator, typename xref:#unordered_map_deduction_guides[__see below__]::size_type = xref:#unordered_map_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_map, xref:#unordered_map_iter_mapped_type[__iter-mapped-type__], Hash, Pred, + Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + unordered_map(std::initializer_list>, + typename xref:#unordered_map_deduction_guides[__see below__]::size_type = xref:#unordered_map_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_map; + + template + unordered_map(InputIterator, InputIterator, typename xref:#unordered_map_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_map, xref:#unordered_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_map(InputIterator, InputIterator, Allocator) + -> unordered_map, xref:#unordered_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_map(InputIterator, InputIterator, typename xref:#unordered_map_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_map, xref:#unordered_map_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + unordered_map(std::initializer_list>, typename xref:#unordered_map_deduction_guides[__see below__]::size_type, + Allocator) + -> unordered_map, std::equal_to, Allocator>; + + template + unordered_map(std::initializer_list>, Allocator) + -> unordered_map, std::equal_to, Allocator>; + + template + unordered_map(std::initializer_list>, typename xref:#unordered_map_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_map, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_T_ +|`T` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. + +The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. + +=== Configuration macros + +==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` + +Globally define this macro to support loading of ``unordered_map``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +An iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ local_iterator; +---- + +An iterator with the same value type, difference type and pointer and reference type as iterator. + +A `local_iterator` object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_local_iterator; +---- + +A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. + +A const_local_iterator object can be used to iterate through a single bucket. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + Iterator position; + bool inserted; + NodeType node; +}; +---- + +with `Iterator` = `iterator` and `NodeType` = `node_type`. + +--- + +=== Constructors + +==== Default Constructor +```c++ unordered_map(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_map(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_map(unordered_map const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_map(unordered_map&& other); ``` + +The move constructor. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_map(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_map(Allocator const& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_map(unordered_map const& other, Allocator const& a); ``` + +Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_map(unordered_map&& other, Allocator const& a); ``` + +Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. + +[horizontal] +Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_map(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_map(size_type n, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_map(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_map(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_map(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_map(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_map& operator=(unordered_map const& other); ``` + +The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. + +If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Assignment +```c++ unordered_map& operator=(unordered_map&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. + +If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. + +[horizontal] +Requires:;; `value_type` is move constructible. + +--- + +==== Initializer List Assignment +```c++ unordered_map& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +`position` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Emplace Insert +```c++ template std::pair insert(P&& obj); ``` + +Inserts an element into the container by performing `emplace(std::forward

(value))`. + +Only participates in overload resolution if `std::is_constructible::value` is `true`. + +[horizontal] +Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Emplace Insert with Hint + +```c++ template iterator insert(const_iterator hint, P&& obj); ``` + +Inserts an element into the container by performing `emplace_hint(hint, std::forward

(value))`. + +Only participates in overload resolution if `std::is_constructible::value` is `true`. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + +--- + +==== try_emplace +```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args) ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +[horizontal] +Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_map_emplace[emplace] except the `value_type` is constructed using: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +instead of xref:#unordered_map_emplace[emplace] which simply forwards all arguments to ``value_type``'s constructor. + +Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + +Pointers and references to elements are never invalidated. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. -- + +--- + +==== try_emplace with Hint +```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_map_emplace_hint[emplace_hint] except the `value_type` is constructed using: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +instead of xref:#unordered_map_emplace_hint[emplace_hint] which simply forwards all arguments to ``value_type``'s constructor. + +The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + +Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + +Pointers and references to elements are never invalidated. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. -- + +--- + +==== insert_or_assign +```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +[horizontal] +Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== insert_or_assign with Hint +```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Extract by Iterator +```c++ node_type extract(const_iterator position); ``` + +Removes the element pointed to by `position`. + +[horizontal] +Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. + +--- + +==== Extract by Key +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Removes an element with key equivalent to `k`. + +[horizontal] +Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert with `node_handle` +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns an `insert_return_type` with: `inserted` equal to `false`, `position` equal to `end()` and `node` empty. + + Otherwise if there was already an element with an equivalent key, returns an `insert_return_type` with: `inserted` equal to `false`, `position` pointing to a matching element and `node` contains the node from `nh`. + + Otherwise if the insertion succeeded, returns an `insert_return_type` with: `inserted` equal to `true`, `position` pointing to the newly inserted element and `node` empty. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multimap`. + +--- + +==== Insert with Hint and `node_handle` +```c++ iterator insert(const_iterator hint, node_type&& nh); ``` + +If `nh` is empty, has no effect. + +Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. + +If there is already an element in the container with an equivalent key has no effect on `nh` (i.e. `nh` still contains the node.) + +`hint` is a suggestion to where the element should be inserted. + +[horizontal] +Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty returns `end()`. + + If there was already an element in the container with an equivalent key returns an iterator pointing to that. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multimap`. + +--- + +==== Erase by Position + +```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. + +--- + +==== quick_erase +```c++ void quick_erase(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== erase_return_void +```c++ void erase_return_void(const_iterator position); ``` + +Erase the element pointed to by `position`. + +[horizontal] +Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. + +--- + +==== swap +```c++ void swap(unordered_map& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +==== clear +```c++ void clear(); ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0` Throws:;; Never throws an exception. + +--- + +==== merge +```c++ template void merge(unordered_map& source); template void merge(unordered_map&& source); template void merge(unordered_multimap& source); template void merge(unordered_multimap&& source); ``` + +Attempt to "merge" two containers by iterating `source` and extracting any node in `source` that is not contained in `*this` and then inserting it into `*this`. + +Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. + +The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. + +This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. + +[horizontal] +Notes:;; + -- +* Pointers and references to transferred elements remain valid. +* Invalidates iterators to transferred elements. +* Invalidates iterators belonging to `*this`. +* Iterators to non-transferred elements in `source` remain valid. +-- + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const; ``` + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== operator++[++++]++ +```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` + +[horizontal] +Effects:;; If the container does not already contain an elements with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== at +```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` + +[horizontal] +Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The number of buckets. + +--- + +==== max_bucket_count +```c++ size_type max_bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; An upper bound on the number of buckets. + +--- + +==== bucket_size +```c++ size_type bucket_size(size_type n) const; ``` + +[horizontal] +Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. + +--- + +==== bucket +```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` + +[horizontal] +Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== begin + +```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. + +--- + +==== end +```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +==== cbegin +```c++ const_local_iterator cbegin(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. + +--- + +==== cend +```c++ const_local_iterator cend(size_type n) const; ``` + +[horizontal] +Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; The average number of elements per bucket. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the current maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Changes the container's maximum load factor, using `z` as a hint. + +--- + + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_map& x, const unordered_map& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_map& x, const unordered_map& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +=== Swap +```c++ template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. + +--- + +=== erase_if +```c++ template typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. + +=== Serialization + +``unordered_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_map to an archive + +Saves all the elements of an `unordered_map` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_map from an archive + +Deletes all preexisting elements of an `unordered_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_map` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `(std::remove_const::type&&, std::remove_const::type&&)`. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From d8122e0414bfea2b27d2264be85df9807fac02d1 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:20:26 +0000 Subject: [PATCH 26/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_flat_set_zh_Hans.adoc | 1014 +++++++++++++++++ 1 file changed, 1014 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc new file mode 100644 index 0000000..9411234 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc @@ -0,0 +1,1014 @@ +[#unordered_flat_set] +== Class Template unordered_flat_set + +:idprefix: unordered_flat_set_ + +`boost::unordered_flat_set` — An open-addressing unordered associative container that stores unique values. + +The performance of `boost::unordered_flat_set` is much better than that of `boost::unordered_set` or other implementations of `std::unordered_set`. Unlike standard unordered associative containers, which are node-based, the elements of a `boost::unordered_flat_set` are held directly in the bucket array, and insertions into an already occupied bucket are diverted to available buckets in the vicinity of the original position. This type of data layout is known as _open addressing_. + +As a result of its using open addressing, the interface of `boost::unordered_flat_set` deviates in a number of aspects from that of `boost::unordered_flat_set`/`std::unordered_flat_set`: + +- `value_type` must be move-constructible. - Pointer stability is not kept under rehashing. - `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - The maximum load factor of the container is managed internally and can't be set by the user. + +Other than this, `boost::unordered_flat_set` is mostly a drop-in replacement of node-based standard unordered associative containers. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_flat_set.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class unordered_flat_set { + public: + // types + using key_type = Key; + using value_type = Key; + using init_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled] + + // construct/copy/destroy + xref:#unordered_flat_set_default_constructor[unordered_flat_set](); + explicit xref:#unordered_flat_set_bucket_count_constructor[unordered_flat_set](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_flat_set_iterator_range_constructor[unordered_flat_set](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_flat_set_copy_constructor[unordered_flat_set](const unordered_flat_set& other); + xref:#unordered_flat_set_move_constructor[unordered_flat_set](unordered_flat_set&& other); + template + xref:#unordered_flat_set_iterator_range_constructor_with_allocator[unordered_flat_set](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_flat_set_allocator_constructor[unordered_flat_set](const Allocator& a); + xref:#unordered_flat_set_copy_constructor_with_allocator[unordered_flat_set](const unordered_flat_set& other, const Allocator& a); + xref:#unordered_flat_set_move_constructor_from_concurrent_flat_set[unordered_flat_set](concurrent_flat_set&& other); + xref:#unordered_flat_set_initializer_list_constructor[unordered_flat_set](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_flat_set_bucket_count_constructor_with_allocator[unordered_flat_set](size_type n, const allocator_type& a); + xref:#unordered_flat_set_bucket_count_constructor_with_hasher_and_allocator[unordered_flat_set](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_flat_set_iterator_range_constructor_with_bucket_count_and_allocator[unordered_flat_set](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_flat_set_iterator_range_constructor_with_bucket_count_and_hasher[unordered_flat_set](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_flat_set_initializer_list_constructor_with_allocator[unordered_flat_set](std::initializer_list il, const allocator_type& a); + xref:#unordered_flat_set_initializer_list_constructor_with_bucket_count_and_allocator[unordered_flat_set](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#unordered_flat_set_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_flat_set](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_flat_set_destructor[~unordered_flat_set](); + unordered_flat_set& xref:#unordered_flat_set_copy_assignment[operator++=++](const unordered_flat_set& other); + unordered_flat_set& xref:#unordered_flat_set_move_assignment[operator++=++](unordered_flat_set&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + unordered_flat_set& xref:#unordered_flat_set_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#unordered_flat_set_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_flat_set_begin[begin]() noexcept; + const_iterator xref:#unordered_flat_set_begin[begin]() const noexcept; + iterator xref:#unordered_flat_set_end[end]() noexcept; + const_iterator xref:#unordered_flat_set_end[end]() const noexcept; + const_iterator xref:#unordered_flat_set_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_flat_set_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_flat_set_empty[empty]() const noexcept; + size_type xref:#unordered_flat_set_size[size]() const noexcept; + size_type xref:#unordered_flat_set_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_flat_set_emplace[emplace](Args&&... args); + template iterator xref:#unordered_flat_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_flat_set_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_flat_set_move_insert[insert](value_type&& obj); + template std::pair xref:#unordered_flat_set_transparent_insert[insert](K&& k); + iterator xref:#unordered_flat_set_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_flat_set_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + template iterator xref:#unordered_flat_set_transparent_insert_with_hint[insert](const_iterator hint, K&& k); + template void xref:#unordered_flat_set_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_flat_set_insert_initializer_list[insert](std::initializer_list); + + _convertible-to-iterator_ xref:#unordered_flat_set_erase_by_position[erase](iterator position); + _convertible-to-iterator_ xref:#unordered_flat_set_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_flat_set_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_flat_set_erase_by_key[erase](K&& k); + iterator xref:#unordered_flat_set_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_flat_set_swap[swap](unordered_flat_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + init_type xref:#unordered_flat_set_pull[pull](const_iterator position); + void xref:#unordered_flat_set_clear[clear]() noexcept; + + template + void xref:#unordered_flat_set_merge[merge](unordered_flat_set& source); + template + void xref:#unordered_flat_set_merge[merge](unordered_flat_set&& source); + + // observers + hasher xref:#unordered_flat_set_hash_function[hash_function]() const; + key_equal xref:#unordered_flat_set_key_eq[key_eq]() const; + + // set operations + iterator xref:#unordered_flat_set_find[find](const key_type& k); + const_iterator xref:#unordered_flat_set_find[find](const key_type& k) const; + template + iterator xref:#unordered_flat_set_find[find](const K& k); + template + const_iterator xref:#unordered_flat_set_find[find](const K& k) const; + size_type xref:#unordered_flat_set_count[count](const key_type& k) const; + template + size_type xref:#unordered_flat_set_count[count](const K& k) const; + bool xref:#unordered_flat_set_contains[contains](const key_type& k) const; + template + bool xref:#unordered_flat_set_contains[contains](const K& k) const; + std::pair xref:#unordered_flat_set_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_flat_set_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_flat_set_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_flat_set_equal_range[equal_range](const K& k) const; + + // bucket interface + size_type xref:#unordered_flat_set_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#unordered_flat_set_load_factor[load_factor]() const noexcept; + float xref:#unordered_flat_set_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_flat_set_set_max_load_factor[max_load_factor](float z); + size_type xref:#unordered_flat_set_max_load[max_load]() const noexcept; + void xref:#unordered_flat_set_rehash[rehash](size_type n); + void xref:#unordered_flat_set_reserve[reserve](size_type n); + + // statistics (if xref:unordered_flat_set_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_flat_set_get_stats[get_stats]() const; + void xref:#unordered_flat_set_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_flat_set(InputIterator, InputIterator, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type = xref:#unordered_flat_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_flat_set, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + unordered_flat_set(std::initializer_list, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type = xref:#unordered_flat_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_flat_set; + + template + unordered_flat_set(InputIterator, InputIterator, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_flat_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_flat_set(InputIterator, InputIterator, Allocator) + -> unordered_flat_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_flat_set(InputIterator, InputIterator, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_flat_set, Hash, + std::equal_to>, Allocator>; + + template + unordered_flat_set(std::initializer_list, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_flat_set, std::equal_to, Allocator>; + + template + unordered_flat_set(std::initializer_list, Allocator) + -> unordered_flat_set, std::equal_to, Allocator>; + + template + unordered_flat_set(std::initializer_list, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> unordered_flat_set, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container +and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements of the container are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +=== Constructors + +==== Default Constructor +```c++ unordered_flat_set(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_flat_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_flat_set(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_flat_set(unordered_flat_set const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_flat_set(unordered_flat_set&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_flat_set(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_flat_set(Allocator const& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_flat_set(unordered_flat_set const& other, Allocator const& a); ``` + +Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_flat_set(unordered_flat_set&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Move Constructor from concurrent_flat_set + +```c++ unordered_flat_set(concurrent_flat_set&& other); ``` + +Move construction from a xref:#concurrent_flat_set[`concurrent_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; Constant time. Concurrency:;; Blocking on `other`. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_flat_set(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_flat_set(size_type n, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_flat_set(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_flat_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + unordered_flat_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_flat_set(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_flat_set(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_flat_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_flat_set(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_flat_set& operator=(unordered_flat_set const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +--- + +==== Move Assignment +```c++ unordered_flat_set& operator=(unordered_flat_set&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Initializer List Assignment +```c++ unordered_flat_set& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +`position` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Transparent Insert +```c++ template std::pair insert(K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Transparent Insert with Hint +```c++ template std::pair insert(const_iterator hint, K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Erase by Position + +[source,c++,subs=+quotes] +---- +_convertible-to-iterator_ erase(iterator position); +_convertible-to-iterator_ erase(const_iterator position); +---- + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). + +--- + +==== swap +```c++ void swap(unordered_flat_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +==== pull +```c++ init_type pull(const_iterator position); ``` + +Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` + +--- + +==== merge +```c++ template void merge(unordered_flat_set& source); template void merge(unordered_flat_set&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The container's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the container's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. + +Invalidates iterators, pointers and references, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, pointers and references, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_flat_set& x, const unordered_flat_set& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_flat_set& x, const unordered_flat_set& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +=== Swap +```c++ template void swap(unordered_flat_set& x, unordered_flat_set& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +=== erase_if +```c++ template typename unordered_flat_set::size_type erase_if(unordered_flat_set& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + +=== Serialization + +``unordered_flat_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_flat_set to an archive + +Saves all the elements of an `unordered_flat_set` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_flat_set from an archive + +Deletes all preexisting elements of an `unordered_flat_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_flat_set` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_flat_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_flat_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From a37d9c6309fe66f00902cf091118d815c03e6009 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:20:36 +0000 Subject: [PATCH 27/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/unordered_flat_map_zh_Hans.adoc | 1175 +++++++++++++++++ 1 file changed, 1175 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc new file mode 100644 index 0000000..262590d --- /dev/null +++ b/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc @@ -0,0 +1,1175 @@ +[#unordered_flat_map] +== Class Template unordered_flat_map + +:idprefix: unordered_flat_map_ + +`boost::unordered_flat_map` — An open-addressing unordered associative container that associates unique keys with another value. + +The performance of `boost::unordered_flat_map` is much better than that of `boost::unordered_map` or other implementations of `std::unordered_map`. Unlike standard unordered associative containers, which are node-based, the elements of a `boost::unordered_flat_map` are held directly in the bucket array, and insertions into an already occupied bucket are diverted to available buckets in the vicinity of the original position. This type of data layout is known as _open addressing_. + +As a result of its using open addressing, the interface of `boost::unordered_flat_map` deviates in a number of aspects from that of `boost::unordered_map`/`std::unordered_map`: + +- `value_type` must be move-constructible. - Pointer stability is not kept under rehashing. - `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - The maximum load factor of the container is managed internally and can't be set by the user. + +Other than this, `boost::unordered_flat_map` is mostly a drop-in replacement of node-based standard unordered associative containers. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_unordered_flat_map.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class unordered_flat_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using init_type = std::pair< + typename std::remove_const::type, + typename std::remove_const::type + >; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using iterator = _implementation-defined_; + using const_iterator = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled] + + // construct/copy/destroy + xref:#unordered_flat_map_default_constructor[unordered_flat_map](); + explicit xref:#unordered_flat_map_bucket_count_constructor[unordered_flat_map](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#unordered_flat_map_iterator_range_constructor[unordered_flat_map](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_flat_map_copy_constructor[unordered_flat_map](const unordered_flat_map& other); + xref:#unordered_flat_map_move_constructor[unordered_flat_map](unordered_flat_map&& other); + template + xref:#unordered_flat_map_iterator_range_constructor_with_allocator[unordered_flat_map](InputIterator f, InputIterator l, const allocator_type& a); + explicit xref:#unordered_flat_map_allocator_constructor[unordered_flat_map](const Allocator& a); + xref:#unordered_flat_map_copy_constructor_with_allocator[unordered_flat_map](const unordered_flat_map& other, const Allocator& a); + xref:#unordered_flat_map_move_constructor_with_allocator[unordered_flat_map](unordered_flat_map&& other, const Allocator& a); + xref:#unordered_flat_map_move_constructor_from_concurrent_flat_map[unordered_flat_map](concurrent_flat_map&& other); + xref:#unordered_flat_map_initializer_list_constructor[unordered_flat_map](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#unordered_flat_map_bucket_count_constructor_with_allocator[unordered_flat_map](size_type n, const allocator_type& a); + xref:#unordered_flat_map_bucket_count_constructor_with_hasher_and_allocator[unordered_flat_map](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#unordered_flat_map_iterator_range_constructor_with_bucket_count_and_allocator[unordered_flat_map](InputIterator f, InputIterator l, size_type n, const allocator_type& a); + template + xref:#unordered_flat_map_iterator_range_constructor_with_bucket_count_and_hasher[unordered_flat_map](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_flat_map_initializer_list_constructor_with_allocator[unordered_flat_map](std::initializer_list il, const allocator_type& a); + xref:#unordered_flat_map_initializer_list_constructor_with_bucket_count_and_allocator[unordered_flat_map](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#unordered_flat_map_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[unordered_flat_map](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#unordered_flat_map_destructor[~unordered_flat_map](); + unordered_flat_map& xref:#unordered_flat_map_copy_assignment[operator++=++](const unordered_flat_map& other); + unordered_flat_map& xref:#unordered_flat_map_move_assignment[operator++=++](unordered_flat_map&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + unordered_flat_map& xref:#unordered_flat_map_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#unordered_flat_map_get_allocator[get_allocator]() const noexcept; + + // iterators + iterator xref:#unordered_flat_map_begin[begin]() noexcept; + const_iterator xref:#unordered_flat_map_begin[begin]() const noexcept; + iterator xref:#unordered_flat_map_end[end]() noexcept; + const_iterator xref:#unordered_flat_map_end[end]() const noexcept; + const_iterator xref:#unordered_flat_map_cbegin[cbegin]() const noexcept; + const_iterator xref:#unordered_flat_map_cend[cend]() const noexcept; + + // capacity + ++[[nodiscard]]++ bool xref:#unordered_flat_map_empty[empty]() const noexcept; + size_type xref:#unordered_flat_map_size[size]() const noexcept; + size_type xref:#unordered_flat_map_max_size[max_size]() const noexcept; + + // modifiers + template std::pair xref:#unordered_flat_map_emplace[emplace](Args&&... args); + template iterator xref:#unordered_flat_map_emplace_hint[emplace_hint](const_iterator position, Args&&... args); + std::pair xref:#unordered_flat_map_copy_insert[insert](const value_type& obj); + std::pair xref:#unordered_flat_map_copy_insert[insert](const init_type& obj); + std::pair xref:#unordered_flat_map_move_insert[insert](value_type&& obj); + std::pair xref:#unordered_flat_map_move_insert[insert](init_type&& obj); + iterator xref:#unordered_flat_map_copy_insert_with_hint[insert](const_iterator hint, const value_type& obj); + iterator xref:#unordered_flat_map_copy_insert_with_hint[insert](const_iterator hint, const init_type& obj); + iterator xref:#unordered_flat_map_move_insert_with_hint[insert](const_iterator hint, value_type&& obj); + iterator xref:#unordered_flat_map_copy_insert_with_hint[insert](const_iterator hint, init_type&& obj); + template void xref:#unordered_flat_map_insert_iterator_range[insert](InputIterator first, InputIterator last); + void xref:#unordered_flat_map_insert_initializer_list[insert](std::initializer_list); + + template + std::pair xref:#unordered_flat_map_try_emplace[try_emplace](const key_type& k, Args&&... args); + template + std::pair xref:#unordered_flat_map_try_emplace[try_emplace](key_type&& k, Args&&... args); + template + std::pair xref:#unordered_flat_map_try_emplace[try_emplace](K&& k, Args&&... args); + template + iterator xref:#unordered_flat_map_try_emplace_with_hint[try_emplace](const_iterator hint, const key_type& k, Args&&... args); + template + iterator xref:#unordered_flat_map_try_emplace_with_hint[try_emplace](const_iterator hint, key_type&& k, Args&&... args); + template + iterator xref:#unordered_flat_map_try_emplace_with_hint[try_emplace](const_iterator hint, K&& k, Args&&... args); + template + std::pair xref:#unordered_flat_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj); + template + std::pair xref:#unordered_flat_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj); + template + std::pair xref:#unordered_flat_map_insert_or_assign[insert_or_assign](K&& k, M&& obj); + template + iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, const key_type& k, M&& obj); + template + iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, key_type&& k, M&& obj); + template + iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj); + + _convertible-to-iterator_ xref:#unordered_flat_map_erase_by_position[erase](iterator position); + _convertible-to-iterator_ xref:#unordered_flat_map_erase_by_position[erase](const_iterator position); + size_type xref:#unordered_flat_map_erase_by_key[erase](const key_type& k); + template size_type xref:#unordered_flat_map_erase_by_key[erase](K&& k); + iterator xref:#unordered_flat_map_erase_range[erase](const_iterator first, const_iterator last); + void xref:#unordered_flat_map_swap[swap](unordered_flat_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + init_type xref:#unordered_flat_map_pull[pull](const_iterator position); + void xref:#unordered_flat_map_clear[clear]() noexcept; + + template + void xref:#unordered_flat_map_merge[merge](unordered_flat_map& source); + template + void xref:#unordered_flat_map_merge[merge](unordered_flat_map&& source); + + // observers + hasher xref:#unordered_flat_map_hash_function[hash_function]() const; + key_equal xref:#unordered_flat_map_key_eq[key_eq]() const; + + // map operations + iterator xref:#unordered_flat_map_find[find](const key_type& k); + const_iterator xref:#unordered_flat_map_find[find](const key_type& k) const; + template + iterator xref:#unordered_flat_map_find[find](const K& k); + template + const_iterator xref:#unordered_flat_map_find[find](const K& k) const; + size_type xref:#unordered_flat_map_count[count](const key_type& k) const; + template + size_type xref:#unordered_flat_map_count[count](const K& k) const; + bool xref:#unordered_flat_map_contains[contains](const key_type& k) const; + template + bool xref:#unordered_flat_map_contains[contains](const K& k) const; + std::pair xref:#unordered_flat_map_equal_range[equal_range](const key_type& k); + std::pair xref:#unordered_flat_map_equal_range[equal_range](const key_type& k) const; + template + std::pair xref:#unordered_flat_map_equal_range[equal_range](const K& k); + template + std::pair xref:#unordered_flat_map_equal_range[equal_range](const K& k) const; + + // element access + mapped_type& xref:#unordered_flat_map_operator[operator[+]+](const key_type& k); + mapped_type& xref:#unordered_flat_map_operator[operator[+]+](key_type&& k); + template mapped_type& xref:#unordered_flat_map_operator[operator[+]+](K&& k); + mapped_type& xref:#unordered_flat_map_at[at](const key_type& k); + const mapped_type& xref:#unordered_flat_map_at[at](const key_type& k) const; + template mapped_type& xref:#unordered_flat_map_at[at](const K& k); + template const mapped_type& xref:#unordered_flat_map_at[at](const K& k) const; + + // bucket interface + size_type xref:#unordered_flat_map_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#unordered_flat_map_load_factor[load_factor]() const noexcept; + float xref:#unordered_flat_map_max_load_factor[max_load_factor]() const noexcept; + void xref:#unordered_flat_map_set_max_load_factor[max_load_factor](float z); + size_type xref:#unordered_flat_map_max_load[max_load]() const noexcept; + void xref:#unordered_flat_map_rehash[rehash](size_type n); + void xref:#unordered_flat_map_reserve[reserve](size_type n); + + // statistics (if xref:unordered_flat_map_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_flat_map_get_stats[get_stats]() const; + void xref:#unordered_flat_map_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + unordered_flat_map(InputIterator, InputIterator, typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type = xref:#unordered_flat_map_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> unordered_flat_map, xref:#unordered_flat_map_iter_mapped_type[__iter-mapped-type__], Hash, + Pred, Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + unordered_flat_map(std::initializer_list>, + typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type = xref:#unordered_flat_map_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> unordered_flat_map; + + template + unordered_flat_map(InputIterator, InputIterator, typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type, Allocator) + -> unordered_flat_map, xref:#unordered_flat_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_flat_map(InputIterator, InputIterator, Allocator) + -> unordered_flat_map, xref:#unordered_flat_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + unordered_flat_map(InputIterator, InputIterator, typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> unordered_flat_map, xref:#unordered_flat_map_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + unordered_flat_map(std::initializer_list>, typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type, + Allocator) + -> unordered_flat_map, std::equal_to, Allocator>; + + template + unordered_flat_map(std::initializer_list>, Allocator) + -> unordered_flat_map, std::equal_to, Allocator>; + + template + unordered_flat_map(std::initializer_list>, typename xref:#unordered_flat_map_deduction_guides[__see below__]::size_type, + Hash, Allocator) + -> unordered_flat_map, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +.2+|`Key` and `T` must be https://en.cppreference.com/w/cpp/named_req/MoveConstructible[MoveConstructible^]. +`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_T_ + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the container's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements of the container are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ iterator; +---- + +An iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +Convertible to `const_iterator`. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ const_iterator; +---- + +A constant iterator whose value type is `value_type`. + +The iterator category is at least a forward iterator. + +=== Constructors + +==== Default Constructor +```c++ unordered_flat_map(); ``` + +Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit unordered_flat_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + unordered_flat_map(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ unordered_flat_map(unordered_flat_map const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible + +--- + +==== Move Constructor +```c++ unordered_flat_map(unordered_flat_map&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template unordered_flat_map(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit unordered_flat_map(Allocator const& a); ``` + +Constructs an empty container, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ unordered_flat_map(unordered_flat_map const& other, Allocator const& a); ``` + +Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +--- + +==== Move Constructor with Allocator +```c++ unordered_flat_map(unordered_flat_map&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Move Constructor from concurrent_flat_map + +```c++ unordered_flat_map(concurrent_flat_map&& other); ``` + +Move construction from a xref:#concurrent_flat_map[`concurrent_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; Constant time. Concurrency:;; Blocking on `other`. + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +unordered_flat_map(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ unordered_flat_map(size_type n, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ unordered_flat_map(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + unordered_flat_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + unordered_flat_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ unordered_flat_map(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ unordered_flat_map(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ unordered_flat_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~unordered_flat_map(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ unordered_flat_map& operator=(unordered_flat_map const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +--- + +==== Move Assignment +```c++ unordered_flat_map& operator=(unordered_flat_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +--- + +==== Initializer List Assignment +```c++ unordered_flat_map& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] + +=== Iterators + +==== begin +```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` + +[horizontal] +Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== end +```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` + +[horizontal] +Returns:;; An iterator which refers to the past-the-end value for the container. + +--- + +==== cbegin +```c++ const_iterator cbegin() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) + +--- + +==== cend +```c++ const_iterator cend() const noexcept; ``` + +[horizontal] +Returns:;; A `const_iterator` which refers to the past-the-end value for the container. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; `std::distance(begin(), end())` + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible container. + +--- + +=== Modifiers + +==== emplace +```c++ template std::pair emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. + +--- + +==== emplace_hint +```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. + +`position` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. + +--- + +==== Copy Insert +```c++ std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert +```c++ std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Copy Insert with Hint +```c++ iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert with Hint +```c++ iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); ``` + +Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Insert Iterator Range +```c++ template void insert(InputIterator first, InputIterator last); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== Insert Initializer List +```c++ void insert(std::initializer_list); ``` + +Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +--- + +==== try_emplace +```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args); ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +[horizontal] +Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_flat_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#unordered_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. + +Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace with Hint +```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` + +Inserts a new element into the container if there is no existing element with key `k` contained within it. + +If there is an existing element with key `k` this function does nothing. + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_flat_map_emplace_hint[emplace_hint], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#unordered_flat_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. + +Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== insert_or_assign +```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +[horizontal] +Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== insert_or_assign with Hint +```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` + +Inserts a new element into the container or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the container as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +`hint` is a suggestion to where the element should be inserted. This implementation ignores it. + +[horizontal] +Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + + +==== Erase by Position + +[source,c++,subs=+quotes] +---- +_convertible-to-iterator_ erase(iterator position); +_convertible-to-iterator_ erase(const_iterator position); +---- + +Erase the element pointed to by `position`. + +[horizontal] +Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. + +--- + +==== Erase by Key +```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` + +Erase all elements with key equivalent to `k`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Erase Range + +```c++ iterator erase(const_iterator first, const_iterator last); ``` + +Erases the elements in the range from `first` to `last`. + +[horizontal] +Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). + +--- + +==== swap +```c++ void swap(unordered_flat_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the container with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +==== pull +```c++ init_type pull(const_iterator position); ``` + +Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the container. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` + +--- + +==== merge +```c++ template void merge(unordered_flat_map& source); template void merge(unordered_flat_map&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The container's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The container's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The container's key equality predicate + +--- + +=== Lookup + +==== find +```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); + +``` + +[horizontal] +Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== equal_range +```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` + +[horizontal] +Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== operator++[++++]++ +```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` + +[horizontal] +Effects:;; If the container does not already contain an element with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== at +```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` + +[horizontal] +Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the container's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. + +Invalidates iterators, pointers and references, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. + +Invalidates iterators, pointers and references, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#unordered_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#unordered_flat_map_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#unordered_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const unordered_flat_map& x, const unordered_flat_map& y); ``` + +Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const unordered_flat_map& x, const unordered_flat_map& y); ``` + +Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. + +=== Swap +```c++ template void swap(unordered_flat_map& x, unordered_flat_map& y) noexcept(noexcept(x.swap(y))); ``` + +Swaps the contents of `x` and `y`. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. + +--- + +=== erase_if +```c++ template typename unordered_flat_map::size_type erase_if(unordered_flat_map& c, Predicate pred); ``` + +Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. + +[horizontal] +Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. + +=== Serialization + +``unordered_flat_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an unordered_flat_map to an archive + +Saves all the elements of an `unordered_flat_map` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). + +--- + +==== Loading an unordered_flat_map from an archive + +Deletes all preexisting elements of an `unordered_flat_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_flat_map` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. + +--- + +==== Saving an iterator/const_iterator to an archive + +Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. + +[horizontal] +Requires:;; The `unordered_flat_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. + +--- + +==== Loading an iterator/const_iterator from an archive + +Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. + +[horizontal] +Requires:;; If `x` is the `unordered_flat_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. From e15a16348f2fbae3de8e4fb4d0c89725c49e0d78 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:20:41 +0000 Subject: [PATCH 28/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../ROOT/pages/reference/stats_zh_Hans.adoc | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc new file mode 100644 index 0000000..5079ace --- /dev/null +++ b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc @@ -0,0 +1,62 @@ +[#stats] +== Statistics + +:idprefix: stats_ + +Open-addressing and concurrent containers can be configured to keep running statistics of some internal operations affected by the quality of the supplied hash function. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +struct xref:#stats_stats_summary_type[__stats-summary-type__] +{ + double average; + double variance; + double deviation; +}; + +struct xref:#stats_insertion_stats_type[__insertion-stats-type__] +{ + std::size_t count; + xref:#stats_stats_summary_type[__stats-summary-type__] probe_length; +}; + +struct xref:stats_lookup_stats_type[__lookup-stats-type__] +{ + std::size_t count; + xref:#stats_stats_summary_type[__stats-summary-type__] probe_length; + xref:#stats_stats_summary_type[__stats-summary-type__] num_comparisons; +}; + +struct xref:reference/stats.adoc#stats_stats_type[__stats-type__] +{ + xref:#stats_insertion_stats_type[__insertion-stats-type__] insertion; + xref:stats_lookup_stats_type[__lookup-stats-type__] successful_lookup, + unsuccessful_lookup; +}; +----- + +==== __stats-summary-type__ + +Provides the average value, variance and standard deviation of a sequence of numerical values. + +==== __insertion-stats-type__ + +Provides the number of insertion operations performed by a container and statistics on the associated __probe length__ (number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed per operation). + +==== __lookup-stats-type__ + +For successful (element found) or unsuccessful (not found) lookup, provides the number of operations performed by a container and statistics on the associated __probe length__ (number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed) and number of element comparisons per operation. + +==== __stats-type__ + +Provides statistics on insertion, successful and unsuccessful lookups performed by a container. If the supplied hash function has good quality, then: + +* Average probe lenghts should be close to 1.0. +* For successful lookups, the average number of element comparisons should be close to 1.0. +* For unsuccessful lookups, the average number of element comparisons should be close to 0.0. + +These statistics can be used to determine if a given hash function can be marked as link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[__avalanching__]. + +--- From eefc8deaff13a1dd5b80fb05627dc0b17c2136fa Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:20:52 +0000 Subject: [PATCH 29/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_set_top_zh_Hans.adoc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc new file mode 100644 index 0000000..78728a4 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc @@ -0,0 +1,9 @@ +[#header_unordered_set_fwd_top] +== `` Synopsis + +:idprefix: header_unordered_set_top_ + +[listing,subs="+macros,+quotes"] +----- +#include xref:reference/header_unordered_set.adoc[] +----- From f3452a7795bc1e9a7edf6d7b0602a90b20791abc Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:03 +0000 Subject: [PATCH 30/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../pages/reference/header_unordered_set_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc new file mode 100644 index 0000000..0548ba8 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_set_fwd] +== `` Synopsis + +:idprefix: header_unordered_set_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_set.adoc[``]. From 999e18da0e320ce89cad7c902f6b2f3f82887510 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:12 +0000 Subject: [PATCH 31/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_set_zh_Hans.adoc | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc new file mode 100644 index 0000000..8b3b4a1 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc @@ -0,0 +1,89 @@ +[#header_unordered_set] +== `` Synopsis + +:idprefix: header_unordered_set_ + +Defines `xref:reference/unordered_set.adoc#unordered_set[boost::unordered_set]`, `xref:reference/unordered_multiset.adoc#unordered_multiset[boost::unordered_multiset]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/unordered_set.adoc#unordered_set[unordered_set]; + + // Equality Comparisons + template + bool xref:reference/unordered_set.adoc#unordered_set_operator[operator++==++](const unordered_set& x, + const unordered_set& y); + + template + bool xref:reference/unordered_set.adoc#unordered_set_operator_2[operator!=](const unordered_set& x, + const unordered_set& y); + + // swap + template + void xref:reference/unordered_set.adoc#unordered_set_swap_2[swap](unordered_set& x, + unordered_set& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_set::size_type + xref:reference/unordered_set.adoc#unordered_set_erase_if[erase_if](unordered_set& c, Predicate pred); + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/unordered_multiset.adoc#unordered_multiset[unordered_multiset]; + + // Equality Comparisons + template + bool xref:reference/unordered_multiset.adoc#unordered_multiset_operator[operator++==++](const unordered_multiset& x, + const unordered_multiset& y); + + template + bool xref:reference/unordered_multiset.adoc#unordered_multiset_operator_2[operator!=](const unordered_multiset& x, + const unordered_multiset& y); + + // swap + template + void xref:reference/unordered_multiset.adoc#unordered_multiset_swap_2[swap](unordered_multiset& x, + unordered_multiset& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_multiset::size_type + xref:reference/unordered_multiset.adoc#unordered_multiset_erase_if[erase_if](unordered_multiset& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_set = + boost::unordered::unordered_set>; + + template, + class Pred = std::equal_to> + using unordered_multiset = + boost::unordered::unordered_multiset>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_set; +using unordered::unordered_multiset; + +} // namespace boost +----- From 87632aea731e4f8ef32ca1dc041e656e34c7b21c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:17 +0000 Subject: [PATCH 32/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_node_set_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc new file mode 100644 index 0000000..5a6aa95 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_node_set_fwd] +== `` Synopsis + +:idprefix: header_unordered_node_set_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_node_set.adoc[``]. From f34ba7db4dad73eb2dd0673b1ba599eceb7b2688 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:22 +0000 Subject: [PATCH 33/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_node_set_zh_Hans.adoc | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc new file mode 100644 index 0000000..fe822cd --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc @@ -0,0 +1,55 @@ +[#header_unordered_node_set] +== `` Synopsis + +:idprefix: header_unordered_node_set_ + +Defines `xref:reference/unordered_node_set.adoc#unordered_node_set[boost::unordered_node_set]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/unordered_node_set.adoc#unordered_node_set[unordered_node_set]; + + // Equality Comparisons + template + bool xref:reference/unordered_node_set.adoc#unordered_node_set_operator[operator++==++](const unordered_node_set& x, + const unordered_node_set& y); + + template + bool xref:reference/unordered_node_set.adoc#unordered_node_set_operator_2[operator!=](const unordered_node_set& x, + const unordered_node_set& y); + + // swap + template + void xref:reference/unordered_node_set.adoc#unordered_node_set_swap_2[swap](unordered_node_set& x, + unordered_node_set& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_node_set::size_type + xref:reference/unordered_node_set.adoc#unordered_node_set_erase_if[erase_if](unordered_node_set& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_node_set = + boost::unordered::unordered_node_set>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_node_set; + +} // namespace boost +----- From c79c0b2d2888ceacf19f3774c1b7fcdf708c2e81 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:32 +0000 Subject: [PATCH 34/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_node_map_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc new file mode 100644 index 0000000..d9f06f3 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_node_map_fwd] +== `` Synopsis + +:idprefix: header_unordered_node_map_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_node_map.adoc[``]. From 39464e5398690c4e679c97e14686758551e21be2 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:36 +0000 Subject: [PATCH 35/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_node_map_zh_Hans.adoc | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc new file mode 100644 index 0000000..26af620 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc @@ -0,0 +1,57 @@ +[#header_unordered_node_map] +== `` Synopsis + +:idprefix: header_unordered_node_map_ + +Defines `xref:reference/unordered_node_map.adoc#unordered_node_map[boost::unordered_node_map]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/unordered_node_map.adoc#unordered_node_map[unordered_node_map]; + + // Equality Comparisons + template + bool xref:reference/unordered_node_map.adoc#unordered_node_map_operator_2[operator++==++](const unordered_node_map& x, + const unordered_node_map& y); + + template + bool xref:reference/unordered_node_map.adoc#unordered_node_map_operator_3[operator!=](const unordered_node_map& x, + const unordered_node_map& y); + + // swap + template + void xref:reference/unordered_node_map.adoc#unordered_node_map_swap_2[swap](unordered_node_map& x, + unordered_node_map& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_node_map::size_type + xref:reference/unordered_node_map.adoc#unordered_node_map_erase_if[erase_if](unordered_node_map& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_node_map = + boost::unordered::unordered_node_map>>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_node_map; + +} // namespace boost +----- From 621d809dbf7bb40a66a4bd3ee80521fef1458e57 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:21:50 +0000 Subject: [PATCH 36/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_map_top_zh_Hans.adoc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc new file mode 100644 index 0000000..129b0fc --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc @@ -0,0 +1,9 @@ +[#header_unordered_map_fwd_top] +== `` Synopsis + +:idprefix: header_unordered_map_top_ + +[listing,subs="+macros,+quotes"] +----- +#include xref:reference/header_unordered_map.adoc[] +----- From 41eb741c82ace4bfc72bc64fef7893584c1e4181 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:00 +0000 Subject: [PATCH 37/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../pages/reference/header_unordered_map_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc new file mode 100644 index 0000000..7367ae9 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_map_fwd] +== `` Synopsis + +:idprefix: header_unordered_map_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_map.adoc[``]. From 4477352fa44f2482da54db7c8c4434b6c957c1de Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:08 +0000 Subject: [PATCH 38/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_map_zh_Hans.adoc | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc new file mode 100644 index 0000000..8e1a206 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc @@ -0,0 +1,93 @@ +[#header_unordered_map] +== `` Synopsis + +:idprefix: header_unordered_map_ + +Defines `xref:reference/unordered_map.adoc#unordered_map[boost::unordered_map]`, `xref:reference/unordered_multimap.adoc#unordered_multimap[boost::unordered_multimap]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/unordered_map.adoc#unordered_map[unordered_map]; + + // Equality Comparisons + template + bool xref:reference/unordered_map.adoc#unordered_map_operator_2[operator++==++](const unordered_map& x, + const unordered_map& y); + + template + bool xref:reference/unordered_map.adoc#unordered_map_operator_3[operator!=](const unordered_map& x, + const unordered_map& y); + + // swap + template + void xref:reference/unordered_map.adoc#unordered_map_swap_2[swap](unordered_map& x, + unordered_map& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_map::size_type + xref:reference/unordered_map.adoc#unordered_map_erase_if[erase_if](unordered_map& c, Predicate pred); + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/unordered_multimap.adoc#unordered_multimap[unordered_multimap]; + + // Equality Comparisons + template + bool xref:reference/unordered_multimap.adoc#unordered_multimap_operator[operator++==++](const unordered_multimap& x, + const unordered_multimap& y); + + template + bool xref:reference/unordered_multimap.adoc#unordered_multimap_operator_2[operator!=](const unordered_multimap& x, + const unordered_multimap& y); + + // swap + template + void xref:reference/unordered_multimap.adoc#unordered_multimap_swap_2[swap](unordered_multimap& x, + unordered_multimap& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_multimap::size_type + xref:reference/unordered_multimap.adoc#unordered_multimap_erase_if[erase_if](unordered_multimap& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_map = + boost::unordered::unordered_map>>; + + template, + class Pred = std::equal_to> + using unordered_multimap = + boost::unordered::unordered_multimap>>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_map; +using unordered::unordered_multimap; + +} // namespace boost +----- From 5dfadc5dc64418b10be3a1e077a9358c6e4c6f93 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:11 +0000 Subject: [PATCH 39/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_flat_set_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc new file mode 100644 index 0000000..68f6891 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_flat_set_fwd] +== `` Synopsis + +:idprefix: header_unordered_flat_set_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_flat_set.adoc[``]. From 565af6674e54ee08ca6fdfd7bccc0efba7e0a562 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:22 +0000 Subject: [PATCH 40/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_flat_set_zh_Hans.adoc | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc new file mode 100644 index 0000000..443c74a --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc @@ -0,0 +1,55 @@ +[#header_unordered_flat_set] +== `` Synopsis + +:idprefix: header_unordered_flat_set_ + +Defines `xref:reference/unordered_flat_set.adoc#unordered_flat_set[boost::unordered_flat_set]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/unordered_flat_set.adoc#unordered_flat_set[unordered_flat_set]; + + // Equality Comparisons + template + bool xref:reference/unordered_flat_set.adoc#unordered_flat_set_operator[operator++==++](const unordered_flat_set& x, + const unordered_flat_set& y); + + template + bool xref:reference/unordered_flat_set.adoc#unordered_flat_set_operator_2[operator!=](const unordered_flat_set& x, + const unordered_flat_set& y); + + // swap + template + void xref:reference/unordered_flat_set.adoc#unordered_flat_set_swap_2[swap](unordered_flat_set& x, + unordered_flat_set& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_flat_set::size_type + xref:reference/unordered_flat_set.adoc#unordered_flat_set_erase_if[erase_if](unordered_flat_set& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_flat_set = + boost::unordered::unordered_flat_set>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_flat_set; + +} // namespace boost +----- From 1f2acd689c0643f494761f8522ef815e8a32bc42 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:27 +0000 Subject: [PATCH 41/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_unordered_flat_map_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc new file mode 100644 index 0000000..94b123c --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_unordered_flat_map_fwd] +== `` Synopsis + +:idprefix: header_unordered_flat_map_fwd_ + +Forward declares all the definitions in xref:reference/header_unordered_flat_map.adoc[``]. From 515b8937c742fe38d6393d845d8e2281e1117c4e Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:33 +0000 Subject: [PATCH 42/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_unordered_flat_map_zh_Hans.adoc | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc new file mode 100644 index 0000000..2a9f51e --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc @@ -0,0 +1,57 @@ +[#header_unordered_flat_map] +== `` Synopsis + +:idprefix: header_unordered_flat_map_ + +Defines `xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/unordered_flat_map.adoc#unordered_flat_map[unordered_flat_map]; + + // Equality Comparisons + template + bool xref:reference/unordered_flat_map.adoc#unordered_flat_map_operator_2[operator++==++](const unordered_flat_map& x, + const unordered_flat_map& y); + + template + bool xref:reference/unordered_flat_map.adoc#unordered_flat_map_operator_3[operator!=](const unordered_flat_map& x, + const unordered_flat_map& y); + + // swap + template + void xref:reference/unordered_flat_map.adoc#unordered_flat_map_swap_2[swap](unordered_flat_map& x, + unordered_flat_map& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename unordered_flat_map::size_type + xref:reference/unordered_flat_map.adoc#unordered_flat_map_erase_if[erase_if](unordered_flat_map& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using unordered_flat_map = + boost::unordered::unordered_flat_map>>; + } // namespace pmr + +} // namespace unordered + +using unordered::unordered_flat_map; + +} // namespace boost +----- From 54b5fee72e82fc7794c19f996a096f217d9cbd93 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:43 +0000 Subject: [PATCH 43/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_concurrent_node_set_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc new file mode 100644 index 0000000..2778990 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_concurrent_node_set_fwd] +== `` Synopsis + +:idprefix: header_concurrent_node_set_fwd_ + +Forward declares all the definitions in xref:reference/header_concurrent_node_set.adoc[``]. From 6ffb3270c200a5b8e73c19285f1f48b1b90e37bf Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:48 +0000 Subject: [PATCH 44/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_concurrent_node_set_zh_Hans.adoc | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc new file mode 100644 index 0000000..236963a --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc @@ -0,0 +1,55 @@ +[#header_concurrent_node_set] +== `` Synopsis + +:idprefix: header_concurrent_node_set_ + +Defines `xref:reference/concurrent_node_set.adoc#concurrent_node_set[boost::concurrent_node_set]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/concurrent_node_set.adoc#concurrent_node_set[concurrent_node_set]; + + // Equality Comparisons + template + bool xref:reference/concurrent_node_set.adoc#concurrent_node_set_operator[operator++==++](const concurrent_node_set& x, + const concurrent_node_set& y); + + template + bool xref:reference/concurrent_node_set.adoc#concurrent_node_set_operator_2[operator!=](const concurrent_node_set& x, + const concurrent_node_set& y); + + // swap + template + void xref:reference/concurrent_node_set.adoc#concurrent_node_set_swap_2[swap](concurrent_node_set& x, + concurrent_node_set& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename concurrent_node_set::size_type + xref:reference/concurrent_node_set.adoc#concurrent_node_set_erase_if[erase_if](concurrent_node_set& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using concurrent_node_set = + boost::unordered::concurrent_node_set>; + } // namespace pmr + +} // namespace unordered + +using unordered::concurrent_node_set; + +} // namespace boost +----- From 0f0d5e2871c555ae0157751cac63a91458d4b101 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:22:54 +0000 Subject: [PATCH 45/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_concurrent_node_map_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc new file mode 100644 index 0000000..aabdc20 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_concurrent_node_map_fwd] +== `` Synopsis + +:idprefix: header_concurrent_node_map_fwd_ + +Forward declares all the definitions in xref:reference/header_concurrent_node_map.adoc[``]. From cb790391ccfb35fa2e20491b3c678aefae4ab256 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:04 +0000 Subject: [PATCH 46/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_concurrent_node_map_zh_Hans.adoc | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc new file mode 100644 index 0000000..0a0c8ce --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc @@ -0,0 +1,57 @@ +[#header_concurrent_node_map] +== `` Synopsis + +:idprefix: header_concurrent_node_map_ + +Defines `xref:reference/concurrent_node_map.adoc#concurrent_node_map[boost::concurrent_node_map]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/concurrent_node_map.adoc#concurrent_node_map[concurrent_node_map]; + + // Equality Comparisons + template + bool xref:reference/concurrent_node_map.adoc#concurrent_node_map_operator[operator++==++](const concurrent_node_map& x, + const concurrent_node_map& y); + + template + bool xref:reference/concurrent_node_map.adoc#concurrent_node_map_operator_2[operator!=](const concurrent_node_map& x, + const concurrent_node_map& y); + + // swap + template + void xref:reference/concurrent_node_map.adoc#concurrent_node_map_swap_2[swap](concurrent_node_map& x, + concurrent_node_map& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename concurrent_node_map::size_type + xref:reference/concurrent_node_map.adoc#concurrent_node_map_erase_if[erase_if](concurrent_node_map& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using concurrent_node_map = + boost::unordered::concurrent_node_map>>; + } // namespace pmr + +} // namespace unordered + +using unordered::concurrent_node_map; + +} // namespace boost +----- From 8f8654b96056f6a07a93d913ea8e1b30375c9c13 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:08 +0000 Subject: [PATCH 47/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_concurrent_flat_set_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc new file mode 100644 index 0000000..a0c0fa3 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_concurrent_flat_set_fwd] +== `` Synopsis + +:idprefix: header_concurrent_flat_set_fwd_ + +Forward declares all the definitions in xref:reference/header_concurrent_flat_set.adoc[``]. From cb7f4ec0b39db6a72980dddf82dda98422672f8b Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:15 +0000 Subject: [PATCH 48/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_concurrent_flat_set_zh_Hans.adoc | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc new file mode 100644 index 0000000..4d6ad6d --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc @@ -0,0 +1,55 @@ +[#header_concurrent_flat_set] +== `` Synopsis + +:idprefix: header_concurrent_flat_set_ + +Defines `xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[boost::concurrent_flat_set]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[concurrent_flat_set]; + + // Equality Comparisons + template + bool xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_operator[operator++==++](const concurrent_flat_set& x, + const concurrent_flat_set& y); + + template + bool xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_operator_2[operator!=](const concurrent_flat_set& x, + const concurrent_flat_set& y); + + // swap + template + void xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_swap_2[swap](concurrent_flat_set& x, + concurrent_flat_set& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename concurrent_flat_set::size_type + xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_erase_if[erase_if](concurrent_flat_set& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using concurrent_flat_set = + boost::unordered::concurrent_flat_set>; + } // namespace pmr + +} // namespace unordered + +using unordered::concurrent_flat_set; + +} // namespace boost +----- From 4fd2e33cde83e11ee41ba8d9a557664bb9cc5065 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:26 +0000 Subject: [PATCH 49/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../reference/header_concurrent_flat_map_fwd_zh_Hans.adoc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc new file mode 100644 index 0000000..6261316 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc @@ -0,0 +1,6 @@ +[#header_concurrent_flat_map_fwd] +== `` Synopsis + +:idprefix: header_concurrent_flat_map_fwd_ + +Forward declares all the definitions in xref:reference/header_concurrent_flat_map.adoc[``]. From 20954e8cf804ef5189021d8b82f1a4deb69f19f2 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:36 +0000 Subject: [PATCH 50/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../header_concurrent_flat_map_zh_Hans.adoc | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc new file mode 100644 index 0000000..902cc6f --- /dev/null +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc @@ -0,0 +1,57 @@ +[#header_concurrent_flat_map] +== `` Synopsis + +:idprefix: header_concurrent_flat_map_ + +Defines `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[boost::concurrent_flat_map]` and associated functions and alias templates. + +[listing,subs="+macros,+quotes"] +----- + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[concurrent_flat_map]; + + // Equality Comparisons + template + bool xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_operator[operator++==++](const concurrent_flat_map& x, + const concurrent_flat_map& y); + + template + bool xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_operator_2[operator!=](const concurrent_flat_map& x, + const concurrent_flat_map& y); + + // swap + template + void xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_swap_2[swap](concurrent_flat_map& x, + concurrent_flat_map& y) + noexcept(noexcept(x.swap(y))); + + // Erasure + template + typename concurrent_flat_map::size_type + xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_erase_if[erase_if](concurrent_flat_map& c, Predicate pred); + + // Pmr aliases (C++17 and up) + namespace pmr { + template, + class Pred = std::equal_to> + using concurrent_flat_map = + boost::unordered::concurrent_flat_map>>; + } // namespace pmr + +} // namespace unordered + +using unordered::concurrent_flat_map; + +} // namespace boost +----- From e030a66fc1a004363056639d4151209861409a3d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:43 +0000 Subject: [PATCH 51/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../pages/reference/hash_traits_zh_Hans.adoc | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc new file mode 100644 index 0000000..72aa9f2 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc @@ -0,0 +1,26 @@ +[#hash_traits] +== Hash Traits + +:idprefix: hash_traits_ + +=== `` Synopsis + +[listing,subs="+macros,+quotes"] +----- +#include + +namespace boost { +namespace unordered { + +using boost::hash_is_avalanching; + +} // namespace unordered +} // namespace boost +----- + +[horizontal] +Note:;; This header is deprecated. Use instead `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[boost::hash_is_avalanching]` defined in `link:../../../../../container_hash/doc/html/hash.html#ref_boostcontainer_hashhash_is_avalanching_hpp[]`. + +Open-addressing and concurrent containers use the provided hash function `Hash` as-is if `hash_is_avalanching::value` is `true`; otherwise, they implement a bit-mixing post-processing stage to increase the quality of hashing at the expense of extra computational cost. + +--- From 3ceb8a6cc7709bb2b79fa8871d190450f6981166 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:23:56 +0000 Subject: [PATCH 52/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../concurrent_node_set_zh_Hans.adoc | 1291 +++++++++++++++++ 1 file changed, 1291 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc new file mode 100644 index 0000000..912fb8f --- /dev/null +++ b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc @@ -0,0 +1,1291 @@ +[#concurrent_node_set] +== Class Template concurrent_node_set + +:idprefix: concurrent_node_set_ + +`boost::concurrent_node_set` — A node-based hash table that stores unique values and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. + +Even though it acts as a container, `boost::concurrent_node_set` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access is done through user-provided _visitation functions_ that are passed to `concurrent_node_set` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. + +The internal data structure of `boost::concurrent_node_set` is similar to that of `boost::unordered_node_set`. Unlike `boost::concurrent_flat_set`, pointer stability and node handling functionalities are provided, at the expense of potentially lower performance. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_concurrent_node_set.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class concurrent_node_set { + public: + // types + using key_type = Key; + using value_type = Key; + using init_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled] + + // constants + static constexpr size_type xref:#concurrent_node_set_constants[bulk_visit_size] = _implementation-defined_; + + // construct/copy/destroy + xref:#concurrent_node_set_default_constructor[concurrent_node_set](); + explicit xref:#concurrent_node_set_bucket_count_constructor[concurrent_node_set](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#concurrent_node_set_iterator_range_constructor[concurrent_node_set](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_node_set_copy_constructor[concurrent_node_set](const concurrent_node_set& other); + xref:#concurrent_node_set_move_constructor[concurrent_node_set](concurrent_node_set&& other); + template + xref:#concurrent_node_set_iterator_range_constructor_with_allocator[concurrent_node_set](InputIterator f, InputIterator l,const allocator_type& a); + explicit xref:#concurrent_node_set_allocator_constructor[concurrent_node_set](const Allocator& a); + xref:#concurrent_node_set_copy_constructor_with_allocator[concurrent_node_set](const concurrent_node_set& other, const Allocator& a); + xref:#concurrent_node_set_move_constructor_with_allocator[concurrent_node_set](concurrent_node_set&& other, const Allocator& a); + xref:#concurrent_node_set_move_constructor_from_unordered_node_set[concurrent_node_set](unordered_node_set&& other); + xref:#concurrent_node_set_initializer_list_constructor[concurrent_node_set](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_node_set_bucket_count_constructor_with_allocator[concurrent_node_set](size_type n, const allocator_type& a); + xref:#concurrent_node_set_bucket_count_constructor_with_hasher_and_allocator[concurrent_node_set](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#concurrent_node_set_iterator_range_constructor_with_bucket_count_and_allocator[concurrent_node_set](InputIterator f, InputIterator l, size_type n, + const allocator_type& a); + template + xref:#concurrent_node_set_iterator_range_constructor_with_bucket_count_and_hasher[concurrent_node_set](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_node_set_initializer_list_constructor_with_allocator[concurrent_node_set](std::initializer_list il, const allocator_type& a); + xref:#concurrent_node_set_initializer_list_constructor_with_bucket_count_and_allocator[concurrent_node_set](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#concurrent_node_set_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[concurrent_node_set](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_node_set_destructor[~concurrent_node_set](); + concurrent_node_set& xref:#concurrent_node_set_copy_assignment[operator++=++](const concurrent_node_set& other); + concurrent_node_set& xref:#concurrent_node_set_move_assignment[operator++=++](concurrent_node_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value); + concurrent_node_set& xref:#concurrent_node_set_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#concurrent_node_set_get_allocator[get_allocator]() const noexcept; + + + // visitation + template size_t xref:#concurrent_node_set_cvisit[visit](const key_type& k, F f); + template size_t xref:#concurrent_node_set_cvisit[visit](const key_type& k, F f) const; + template size_t xref:#concurrent_node_set_cvisit[cvisit](const key_type& k, F f) const; + template size_t xref:#concurrent_node_set_cvisit[visit](const K& k, F f); + template size_t xref:#concurrent_node_set_cvisit[visit](const K& k, F f) const; + template size_t xref:#concurrent_node_set_cvisit[cvisit](const K& k, F f) const; + + template + size_t xref:concurrent_node_set_bulk_visit[visit](FwdIterator first, FwdIterator last, F f); + template + size_t xref:concurrent_node_set_bulk_visit[visit](FwdIterator first, FwdIterator last, F f) const; + template + size_t xref:concurrent_node_set_bulk_visit[cvisit](FwdIterator first, FwdIterator last, F f) const; + + template size_t xref:#concurrent_node_set_cvisit_all[visit_all](F f); + template size_t xref:#concurrent_node_set_cvisit_all[visit_all](F f) const; + template size_t xref:#concurrent_node_set_cvisit_all[cvisit_all](F f) const; + template + void xref:#concurrent_node_set_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f); + template + void xref:#concurrent_node_set_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f) const; + template + void xref:#concurrent_node_set_parallel_cvisit_all[cvisit_all](ExecutionPolicy&& policy, F f) const; + + template bool xref:#concurrent_node_set_cvisit_while[visit_while](F f); + template bool xref:#concurrent_node_set_cvisit_while[visit_while](F f) const; + template bool xref:#concurrent_node_set_cvisit_while[cvisit_while](F f) const; + template + bool xref:#concurrent_node_set_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f); + template + bool xref:#concurrent_node_set_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f) const; + template + bool xref:#concurrent_node_set_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; + + // capacity + ++[[nodiscard]]++ bool xref:#concurrent_node_set_empty[empty]() const noexcept; + size_type xref:#concurrent_node_set_size[size]() const noexcept; + size_type xref:#concurrent_node_set_max_size[max_size]() const noexcept; + + // modifiers + template bool xref:#concurrent_node_set_emplace[emplace](Args&&... args); + bool xref:#concurrent_node_set_copy_insert[insert](const value_type& obj); + bool xref:#concurrent_node_set_move_insert[insert](value_type&& obj); + template bool xref:#concurrent_node_set_transparent_insert[insert](K&& k); + template size_type xref:#concurrent_node_set_insert_iterator_range[insert](InputIterator first, InputIterator last); + size_type xref:#concurrent_node_set_insert_initializer_list[insert](std::initializer_list il); + insert_return_type xref:#concurrent_node_set_insert_node[insert](node_type&& nh); + + template bool xref:#concurrent_node_set_emplace_or_cvisit[emplace_or_visit](Args&&... args, F&& f); + template bool xref:#concurrent_node_set_emplace_or_cvisit[emplace_or_cvisit](Args&&... args, F&& f); + template bool xref:#concurrent_node_set_copy_insert_or_cvisit[insert_or_visit](const value_type& obj, F f); + template bool xref:#concurrent_node_set_copy_insert_or_cvisit[insert_or_cvisit](const value_type& obj, F f); + template bool xref:#concurrent_node_set_move_insert_or_cvisit[insert_or_visit](value_type&& obj, F f); + template bool xref:#concurrent_node_set_move_insert_or_cvisit[insert_or_cvisit](value_type&& obj, F f); + template bool xref:#concurrent_node_set_transparent_insert_or_cvisit[insert_or_visit](K&& k, F f); + template bool xref:#concurrent_node_set_transparent_insert_or_cvisit[insert_or_cvisit](K&& k, F f); + template + size_type xref:#concurrent_node_set_insert_iterator_range_or_visit[insert_or_visit](InputIterator first, InputIterator last, F f); + template + size_type xref:#concurrent_node_set_insert_iterator_range_or_visit[insert_or_cvisit](InputIterator first, InputIterator last, F f); + template size_type xref:#concurrent_node_set_insert_initializer_list_or_visit[insert_or_visit](std::initializer_list il, F f); + template size_type xref:#concurrent_node_set_insert_initializer_list_or_visit[insert_or_cvisit](std::initializer_list il, F f); + template insert_return_type xref:#concurrent_node_set_insert_node_or_visit[insert_or_visit](node_type&& nh, F f); + template insert_return_type xref:#concurrent_node_set_insert_node_or_visit[insert_or_cvisit](node_type&& nh, F f); + + template + bool xref:#concurrent_node_set_emplace_and_cvisit[emplace_and_visit](Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_set_emplace_and_cvisit[emplace_and_cvisit](Args&&... args, F1&& f1, F2&& f2); + template bool xref:#concurrent_node_set_copy_insert_and_cvisit[insert_and_visit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_set_copy_insert_and_cvisit[insert_and_cvisit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_set_move_insert_and_cvisit[insert_and_visit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_set_move_insert_and_cvisit[insert_and_cvisit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_set_transparent_insert_and_cvisit[insert_and_visit](K&& k, F1 f1, F2 f2); + template bool xref:#concurrent_node_set_transparent_insert_and_cvisit[insert_and_cvisit](K&& k, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_set_insert_iterator_range_and_visit[insert_and_visit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_set_insert_iterator_range_and_visit[insert_and_cvisit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_set_insert_initializer_list_and_visit[insert_and_visit](std::initializer_list il, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_set_insert_initializer_list_and_visit[insert_and_cvisit](std::initializer_list il, F1 f1, F2 f2); + template + insert_return_type xref:#concurrent_node_set_insert_node_and_visit[insert_and_visit](node_type&& nh, F1 f1, F2 f2); + template + insert_return_type xref:#concurrent_node_set_insert_node_and_visit[insert_and_cvisit](node_type&& nh, F1 f1, F2 f2); + + size_type xref:#concurrent_node_set_erase[erase](const key_type& k); + template size_type xref:#concurrent_node_set_erase[erase](const K& k); + + template size_type xref:#concurrent_node_set_erase_if_by_key[erase_if](const key_type& k, F f); + template size_type xref:#concurrent_node_set_erase_if_by_key[erase_if](const K& k, F f); + template size_type xref:#concurrent_node_set_erase_if[erase_if](F f); + template void xref:#concurrent_node_set_parallel_erase_if[erase_if](ExecutionPolicy&& policy, F f); + + void xref:#concurrent_node_set_swap[swap](concurrent_node_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + + node_type xref:#concurrent_node_set_extract[extract](const key_type& k); + template node_type xref:#concurrent_node_set_extract[extract](const K& k); + + template node_type xref:#concurrent_node_set_extract_if[extract_if](const key_type& k, F f); + template node_type xref:#concurrent_node_set_extract[extract_if](const K& k, F f); + + void xref:#concurrent_node_set_clear[clear]() noexcept; + + template + size_type xref:#concurrent_node_set_merge[merge](concurrent_node_set& source); + template + size_type xref:#concurrent_node_set_merge[merge](concurrent_node_set&& source); + + // observers + hasher xref:#concurrent_node_set_hash_function[hash_function]() const; + key_equal xref:#concurrent_node_set_key_eq[key_eq]() const; + + // set operations + size_type xref:#concurrent_node_set_count[count](const key_type& k) const; + template + size_type xref:#concurrent_node_set_count[count](const K& k) const; + bool xref:#concurrent_node_set_contains[contains](const key_type& k) const; + template + bool xref:#concurrent_node_set_contains[contains](const K& k) const; + + // bucket interface + size_type xref:#concurrent_node_set_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#concurrent_node_set_load_factor[load_factor]() const noexcept; + float xref:#concurrent_node_set_max_load_factor[max_load_factor]() const noexcept; + void xref:#concurrent_node_set_set_max_load_factor[max_load_factor](float z); + size_type xref:#concurrent_node_set_max_load[max_load]() const noexcept; + void xref:#concurrent_node_set_rehash[rehash](size_type n); + void xref:#concurrent_node_set_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_node_set_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_node_set_get_stats[get_stats]() const; + void xref:#concurrent_node_set_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + concurrent_node_set(InputIterator, InputIterator, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type = xref:#concurrent_node_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_node_set, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + concurrent_node_set(std::initializer_list, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type = xref:#concurrent_node_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_node_set; + + template + concurrent_node_set(InputIterator, InputIterator, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_node_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_node_set(InputIterator, InputIterator, Allocator) + -> concurrent_node_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_node_set(InputIterator, InputIterator, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> concurrent_node_set, Hash, + std::equal_to>, Allocator>; + + template + concurrent_node_set(std::initializer_list, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_node_set, std::equal_to, Allocator>; + + template + concurrent_node_set(std::initializer_list, Allocator) + -> concurrent_node_set, std::equal_to, Allocator>; + + template + concurrent_node_set(std::initializer_list, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> concurrent_node_set, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container +and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the table's value type. +`std::allocator_traits::pointer` and `std::allocator_traits::const_pointer` must be convertible to/from `value_type*` and `const value_type*`, respectively. + +|=== + +The element nodes of the table are held into an internal _bucket array_. An node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Concurrency Requirements and Guarantees + +Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: + +* Copy construction from `al` of an allocator rebound from `Alloc` +* `std::allocator_traits::allocate` +* `std::allocator_traits::deallocate` +* `std::allocator_traits::construct` +* `std::allocator_traits::destroy` + +In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. + +With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_node_set` do not introduce data races — that is, they are thread-safe. + +If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_node_set`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_node_set` execute sequentially in a multithreaded scenario. + +An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. + +When executed internally by a `boost::concurrent_node_set`, the following operations by a user-provided visitation function on the element passed do not introduce data races: + +* Read access to the element. +* Non-mutable modification of the element. +* Mutable modification of the element: +** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. + +Any `boost::concurrent_node_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. + +Visitation functions executed by a `boost::concurrent_node_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` + +In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. + +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted table elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + bool inserted; + NodeType node; +}; +---- + +with `NodeType` = `node_type`. + +--- + +=== Constants + +```cpp static constexpr size_type bulk_visit_size; ``` + +Chunk size internally used in xref:concurrent_node_set_bulk_visit[bulk visit] operations. + +=== Constructors + +==== Default Constructor +```c++ concurrent_node_set(); ``` + +Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit concurrent_node_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + concurrent_node_set(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ concurrent_node_set(concurrent_node_set const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor +```c++ concurrent_node_set(concurrent_node_set&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template concurrent_node_set(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit concurrent_node_set(Allocator const& a); ``` + +Constructs an empty table, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ concurrent_node_set(concurrent_node_set const& other, Allocator const& a); ``` + +Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor with Allocator +```c++ concurrent_node_set(concurrent_node_set&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor from unordered_node_set + +```c++ concurrent_node_set(unordered_node_set&& other); ``` + +Move construction from a xref:#unordered_node_set[`unordered_node_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; O(`bucket_count()`) + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +concurrent_node_set(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ concurrent_node_set(size_type n, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ concurrent_node_set(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + concurrent_node_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + concurrent_node_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ concurrent_node_set(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ concurrent_node_set(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ concurrent_node_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~concurrent_node_set(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ concurrent_node_set& operator=(concurrent_node_set const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Move Assignment +```c++ concurrent_node_set& operator=(concurrent_node_set&& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Initializer List Assignment +```c++ concurrent_node_set& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. + +--- + +=== Visitation + +==== [c]visit + +```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` + +If an element `x` exists with key equivalent to `k`, invokes `f` with a const reference to `x`. + +[horizontal] +Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Bulk visit + +```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` + +For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a const reference to `x`. + +Although functionally equivalent to individually invoking xref:concurrent_node_set_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_node_set_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. + +[horizontal] +Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. + +--- + +==== [c]visit_all + +```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` + +Successively invokes `f` with const references to each of the elements in the table. + +[horizontal] +Returns:;; The number of elements visited. + +--- + +==== Parallel [c]visit_all + +```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with const references to each of the elements in the table. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== [c]visit_while + +```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` + +Successively invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. + +--- + +==== Parallel [c]visit_while + +```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; The number of elements in the table. + +[horizontal] +Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible table. + +--- + +=== Modifiers + +==== emplace +```c++ template bool emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Copy Insert +```c++ bool insert(const value_type& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Move Insert +```c++ bool insert(value_type&& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Transparent Insert +```c++ template bool insert(K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range +```c++ template size_type insert(InputIterator first, InputIterator last); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_set_emplace[emplace](*first++); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List +```c++ size_type insert(std::initializer_list il); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_set_insert_iterator_range[insert](il.begin(), il.end()); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`. `nh` is empty when the function returns. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== emplace_or_[c]visit +```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +--- + +==== Copy insert_or_[c]visit +```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Move insert_or_[c]visit +```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Transparent insert_or_[c]visit +```c++ template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range or Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_set_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List or Visit +```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_set_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node or Visit +```c++ template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); ``` + +If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== emplace_and_[c]visit +```c++ template bool emplace_or_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_or_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. + +--- + +==== Copy insert_and_[c]visit +```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f2, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Move insert_and_[c]visit +```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. + +--- + +==== Transparent insert_and_[c]visit +```c++ template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range and Visit +```c++ template size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_set_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List and Visit +```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_set_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node and Visit +```c++ template insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); template insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); ``` + +If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`, and then invokes `f1` with a const reference to the newly inserted element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f1` or `f2`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== erase +```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` + +Erases the element with key equivalent to `k` if it exists. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if by Key +```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` + +Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if +```c++ template size_type erase_if(F f); ``` + +Successively invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. + +--- + +==== Parallel erase_if +```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` + +Invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== swap +```c++ void swap(concurrent_node_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the table with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== extract +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Extracts the element with key equivalent to `k`, if it exists. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== extract_if +```c++ template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); ``` + +Extracts the element `x` with key equivalent to `k`, if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the table. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. + +--- + +==== merge +```c++ template size_type merge(concurrent_node_set& source); template size_type merge(concurrent_node_set&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +[horizontal] +Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The table's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The table's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The table's key equality predicate. + +--- + +=== Set Operations + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the table's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_set_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const concurrent_node_set& x, const concurrent_node_set& y); ``` + +Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const concurrent_node_set& x, const concurrent_node_set& y); ``` + +Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(concurrent_node_set& x, concurrent_node_set& y) noexcept(noexcept(x.swap(y))); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +x.xref:#concurrent_node_set_swap[swap](y); +----- + +--- + +=== erase_if +```c++ template typename concurrent_node_set::size_type erase_if(concurrent_node_set& c, Predicate pred); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +c.xref:#concurrent_node_set_erase_if[erase_if](pred); +----- + +=== Serialization + +``concurrent_node_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an concurrent_node_set to an archive + +Saves all the elements of a `concurrent_node_set` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. + +--- + +==== Loading an concurrent_node_set from an archive + +Deletes all preexisting elements of a `concurrent_node_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_node_set` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. From 785c8236e742ec52fc3466f6fbad2425b9af0851 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:24:05 +0000 Subject: [PATCH 53/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../concurrent_node_map_zh_Hans.adoc | 1423 +++++++++++++++++ 1 file changed, 1423 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc new file mode 100644 index 0000000..a6fa6a0 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc @@ -0,0 +1,1423 @@ +[#concurrent_node_map] +== Class Template concurrent_node_map + +:idprefix: concurrent_node_map_ + +`boost::concurrent_node_map` — A node-based hash table that associates unique keys with another value and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. + +Even though it acts as a container, `boost::concurrent_node_map` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access and modification are done through user-provided _visitation functions_ that are passed to `concurrent_node_map` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. + +The internal data structure of `boost::concurrent_node_map` is similar to that of `boost::unordered_node_map`. Unlike `boost::concurrent_flat_map`, pointer stability and node handling functionalities are provided, at the expense of potentially lower performance. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_concurrent_node_map.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class concurrent_node_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using init_type = std::pair< + typename std::remove_const::type, + typename std::remove_const::type + >; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using node_type = _implementation-defined_; + using insert_return_type = _implementation-defined_; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled] + + // constants + static constexpr size_type xref:#concurrent_node_map_constants[bulk_visit_size] = _implementation-defined_; + + // construct/copy/destroy + xref:#concurrent_node_map_default_constructor[concurrent_node_map](); + explicit xref:#concurrent_node_map_bucket_count_constructor[concurrent_node_map](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#concurrent_node_map_iterator_range_constructor[concurrent_node_map](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_node_map_copy_constructor[concurrent_node_map](const concurrent_node_map& other); + xref:#concurrent_node_map_move_constructor[concurrent_node_map](concurrent_node_map&& other); + template + xref:#concurrent_node_map_iterator_range_constructor_with_allocator[concurrent_node_map](InputIterator f, InputIterator l,const allocator_type& a); + explicit xref:#concurrent_node_map_allocator_constructor[concurrent_node_map](const Allocator& a); + xref:#concurrent_node_map_copy_constructor_with_allocator[concurrent_node_map](const concurrent_node_map& other, const Allocator& a); + xref:#concurrent_node_map_move_constructor_with_allocator[concurrent_node_map](concurrent_node_map&& other, const Allocator& a); + xref:#concurrent_node_map_move_constructor_from_unordered_node_map[concurrent_node_map](unordered_node_map&& other); + xref:#concurrent_node_map_initializer_list_constructor[concurrent_node_map](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_node_map_bucket_count_constructor_with_allocator[concurrent_node_map](size_type n, const allocator_type& a); + xref:#concurrent_node_map_bucket_count_constructor_with_hasher_and_allocator[concurrent_node_map](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#concurrent_node_map_iterator_range_constructor_with_bucket_count_and_allocator[concurrent_node_map](InputIterator f, InputIterator l, size_type n, + const allocator_type& a); + template + xref:#concurrent_node_map_iterator_range_constructor_with_bucket_count_and_hasher[concurrent_node_map](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_node_map_initializer_list_constructor_with_allocator[concurrent_node_map](std::initializer_list il, const allocator_type& a); + xref:#concurrent_node_map_initializer_list_constructor_with_bucket_count_and_allocator[concurrent_node_map](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#concurrent_node_map_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[concurrent_node_map](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_node_map_destructor[~concurrent_node_map](); + concurrent_node_map& xref:#concurrent_node_map_copy_assignment[operator++=++](const concurrent_node_map& other); + concurrent_node_map& xref:#concurrent_node_map_move_assignment[operator++=++](concurrent_node_map&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + concurrent_node_map& xref:#concurrent_node_map_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#concurrent_node_map_get_allocator[get_allocator]() const noexcept; + + + // visitation + template size_t xref:#concurrent_node_map_cvisit[visit](const key_type& k, F f); + template size_t xref:#concurrent_node_map_cvisit[visit](const key_type& k, F f) const; + template size_t xref:#concurrent_node_map_cvisit[cvisit](const key_type& k, F f) const; + template size_t xref:#concurrent_node_map_cvisit[visit](const K& k, F f); + template size_t xref:#concurrent_node_map_cvisit[visit](const K& k, F f) const; + template size_t xref:#concurrent_node_map_cvisit[cvisit](const K& k, F f) const; + + template + size_t xref:concurrent_node_map_bulk_visit[visit](FwdIterator first, FwdIterator last, F f); + template + size_t xref:concurrent_node_map_bulk_visit[visit](FwdIterator first, FwdIterator last, F f) const; + template + size_t xref:concurrent_node_map_bulk_visit[cvisit](FwdIterator first, FwdIterator last, F f) const; + + template size_t xref:#concurrent_node_map_cvisit_all[visit_all](F f); + template size_t xref:#concurrent_node_map_cvisit_all[visit_all](F f) const; + template size_t xref:#concurrent_node_map_cvisit_all[cvisit_all](F f) const; + template + void xref:#concurrent_node_map_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f); + template + void xref:#concurrent_node_map_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f) const; + template + void xref:#concurrent_node_map_parallel_cvisit_all[cvisit_all](ExecutionPolicy&& policy, F f) const; + + template bool xref:#concurrent_node_map_cvisit_while[visit_while](F f); + template bool xref:#concurrent_node_map_cvisit_while[visit_while](F f) const; + template bool xref:#concurrent_node_map_cvisit_while[cvisit_while](F f) const; + template + bool xref:#concurrent_node_map_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f); + template + bool xref:#concurrent_node_map_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f) const; + template + bool xref:#concurrent_node_map_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; + + // capacity + ++[[nodiscard]]++ bool xref:#concurrent_node_map_empty[empty]() const noexcept; + size_type xref:#concurrent_node_map_size[size]() const noexcept; + size_type xref:#concurrent_node_map_max_size[max_size]() const noexcept; + + // modifiers + template bool xref:#concurrent_node_map_emplace[emplace](Args&&... args); + bool xref:#concurrent_node_map_copy_insert[insert](const value_type& obj); + bool xref:#concurrent_node_map_copy_insert[insert](const init_type& obj); + bool xref:#concurrent_node_map_move_insert[insert](value_type&& obj); + bool xref:#concurrent_node_map_move_insert[insert](init_type&& obj); + template size_type xref:#concurrent_node_map_insert_iterator_range[insert](InputIterator first, InputIterator last); + size_type xref:#concurrent_node_map_insert_initializer_list[insert](std::initializer_list il); + insert_return_type xref:#concurrent_node_map_insert_node[insert](node_type&& nh); + + template bool xref:#concurrent_node_map_emplace_or_cvisit[emplace_or_visit](Args&&... args, F&& f); + template bool xref:#concurrent_node_map_emplace_or_cvisit[emplace_or_cvisit](Args&&... args, F&& f); + template bool xref:#concurrent_node_map_copy_insert_or_cvisit[insert_or_visit](const value_type& obj, F f); + template bool xref:#concurrent_node_map_copy_insert_or_cvisit[insert_or_cvisit](const value_type& obj, F f); + template bool xref:#concurrent_node_map_copy_insert_or_cvisit[insert_or_visit](const init_type& obj, F f); + template bool xref:#concurrent_node_map_copy_insert_or_cvisit[insert_or_cvisit](const init_type& obj, F f); + template bool xref:#concurrent_node_map_move_insert_or_cvisit[insert_or_visit](value_type&& obj, F f); + template bool xref:#concurrent_node_map_move_insert_or_cvisit[insert_or_cvisit](value_type&& obj, F f); + template bool xref:#concurrent_node_map_move_insert_or_cvisit[insert_or_visit](init_type&& obj, F f); + template bool xref:#concurrent_node_map_move_insert_or_cvisit[insert_or_cvisit](init_type&& obj, F f); + template + size_type xref:#concurrent_node_map_insert_iterator_range_or_visit[insert_or_visit](InputIterator first, InputIterator last, F f); + template + size_type xref:#concurrent_node_map_insert_iterator_range_or_visit[insert_or_cvisit](InputIterator first, InputIterator last, F f); + template size_type xref:#concurrent_node_map_insert_initializer_list_or_visit[insert_or_visit](std::initializer_list il, F f); + template size_type xref:#concurrent_node_map_insert_initializer_list_or_visit[insert_or_cvisit](std::initializer_list il, F f); + template insert_return_type xref:#concurrent_node_map_insert_node_or_visit[insert_or_visit](node_type&& nh, F f); + template insert_return_type xref:#concurrent_node_map_insert_node_or_visit[insert_or_cvisit](node_type&& nh, F f); + + template + bool xref:#concurrent_node_map_emplace_and_cvisit[emplace_and_visit](Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_emplace_and_cvisit[emplace_and_cvisit](Args&&... args, F1&& f1, F2&& f2); + template bool xref:#concurrent_node_map_copy_insert_and_cvisit[insert_and_visit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_copy_insert_and_cvisit[insert_and_cvisit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_copy_insert_and_cvisit[insert_and_visit](const init_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_copy_insert_and_cvisit[insert_and_cvisit](const init_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_move_insert_and_cvisit[insert_and_visit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_move_insert_and_cvisit[insert_and_cvisit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_move_insert_and_cvisit[insert_and_visit](init_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_node_map_move_insert_and_cvisit[insert_and_cvisit](init_type&& obj, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_map_insert_iterator_range_and_visit[insert_and_visit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_map_insert_iterator_range_and_visit[insert_and_cvisit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_map_insert_initializer_list_and_visit[insert_and_visit](std::initializer_list il, F1 f1, F2 f2); + template + size_type xref:#concurrent_node_map_insert_initializer_list_and_visit[insert_and_cvisit](std::initializer_list il, F1 f1, F2 f2); + template + insert_return_type xref:#concurrent_node_map_insert_node_and_visit[insert_and_visit](node_type&& nh, F1 f1, F2 f2); + template + insert_return_type xref:#concurrent_node_map_insert_node_and_visit[insert_and_cvisit](node_type&& nh, F1 f1, F2 f2); + + template bool xref:#concurrent_node_map_try_emplace[try_emplace](const key_type& k, Args&&... args); + template bool xref:#concurrent_node_map_try_emplace[try_emplace](key_type&& k, Args&&... args); + template bool xref:#concurrent_node_map_try_emplace[try_emplace](K&& k, Args&&... args); + + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_visit](const key_type& k, Args&&... args, F&& f); + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_cvisit](const key_type& k, Args&&... args, F&& f); + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_visit](key_type&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_cvisit](key_type&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_visit](K&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_node_map_try_emplace_or_cvisit[try_emplace_or_cvisit](K&& k, Args&&... args, F&& f); + + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_visit](const key_type& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_cvisit](const key_type& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_visit](key_type&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_cvisit](key_type&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_visit](K&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_node_map_try_emplace_and_cvisit[try_emplace_and_cvisit](K&& k, Args&&... args, F1&& f1, F2&& f2); + + + template bool xref:#concurrent_node_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj); + template bool xref:#concurrent_node_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj); + template bool xref:#concurrent_node_map_insert_or_assign[insert_or_assign](K&& k, M&& obj); + + size_type xref:#concurrent_node_map_erase[erase](const key_type& k); + template size_type xref:#concurrent_node_map_erase[erase](const K& k); + + template size_type xref:#concurrent_node_map_erase_if_by_key[erase_if](const key_type& k, F f); + template size_type xref:#concurrent_node_map_erase_if_by_key[erase_if](const K& k, F f); + template size_type xref:#concurrent_node_map_erase_if[erase_if](F f); + template void xref:#concurrent_node_map_parallel_erase_if[erase_if](ExecutionPolicy&& policy, F f); + + void xref:#concurrent_node_map_swap[swap](concurrent_node_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + + node_type xref:#concurrent_node_map_extract[extract](const key_type& k); + template node_type xref:#concurrent_node_map_extract[extract](const K& k); + + template node_type xref:#concurrent_node_map_extract_if[extract_if](const key_type& k, F f); + template node_type xref:#concurrent_node_map_extract[extract_if](const K& k, F f); + + void xref:#concurrent_node_map_clear[clear]() noexcept; + + template + size_type xref:#concurrent_node_map_merge[merge](concurrent_node_map& source); + template + size_type xref:#concurrent_node_map_merge[merge](concurrent_node_map&& source); + + // observers + hasher xref:#concurrent_node_map_hash_function[hash_function]() const; + key_equal xref:#concurrent_node_map_key_eq[key_eq]() const; + + // map operations + size_type xref:#concurrent_node_map_count[count](const key_type& k) const; + template + size_type xref:#concurrent_node_map_count[count](const K& k) const; + bool xref:#concurrent_node_map_contains[contains](const key_type& k) const; + template + bool xref:#concurrent_node_map_contains[contains](const K& k) const; + + // bucket interface + size_type xref:#concurrent_node_map_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#concurrent_node_map_load_factor[load_factor]() const noexcept; + float xref:#concurrent_node_map_max_load_factor[max_load_factor]() const noexcept; + void xref:#concurrent_node_map_set_max_load_factor[max_load_factor](float z); + size_type xref:#concurrent_node_map_max_load[max_load]() const noexcept; + void xref:#concurrent_node_map_rehash[rehash](size_type n); + void xref:#concurrent_node_map_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_node_map_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_node_map_get_stats[get_stats]() const; + void xref:#concurrent_node_map_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + concurrent_node_map(InputIterator, InputIterator, typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type = xref:#concurrent_node_map_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_node_map, xref:#concurrent_node_map_iter_mapped_type[__iter-mapped-type__], Hash, + Pred, Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + concurrent_node_map(std::initializer_list>, + typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type = xref:#concurrent_node_map_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> concurrent_node_map; + + template + concurrent_node_map(InputIterator, InputIterator, typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_node_map, xref:#concurrent_node_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_node_map(InputIterator, InputIterator, Allocator) + -> concurrent_node_map, xref:#concurrent_node_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_node_map(InputIterator, InputIterator, typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> concurrent_node_map, xref:#concurrent_node_map_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + concurrent_node_map(std::initializer_list>, typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type, + Allocator) + -> concurrent_node_map, std::equal_to, Allocator>; + + template + concurrent_node_map(std::initializer_list>, Allocator) + -> concurrent_node_map, std::equal_to, Allocator>; + + template + concurrent_node_map(std::initializer_list>, typename xref:#concurrent_node_map_deduction_guides[__see below__]::size_type, + Hash, Allocator) + -> concurrent_node_map, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +.2+|`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] +into the table from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the table. + +|_T_ + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the table's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The element nodes of the table are held into an internal _bucket array_. An node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Concurrency Requirements and Guarantees + +Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: + +* Copy construction from `al` of an allocator rebound from `Alloc` +* `std::allocator_traits::allocate` +* `std::allocator_traits::deallocate` +* `std::allocator_traits::construct` +* `std::allocator_traits::destroy` + +In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. + +With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_node_map` do not introduce data races — that is, they are thread-safe. + +If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_node_map`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_node_map` execute sequentially in a multithreaded scenario. + +An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. + +When executed internally by a `boost::concurrent_node_map`, the following operations by a user-provided visitation function on the element passed do not introduce data races: + +* Read access to the element. +* Non-mutable modification of the element. +* Mutable modification of the element: +** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. + +Any `boost::concurrent_node_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. + +Visitation functions executed by a `boost::concurrent_node_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` + +In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. + +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. + +--- + +=== Typedefs + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ node_type; +---- + +A class for holding extracted table elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. + +--- + +[source,c++,subs=+quotes] +---- +typedef _implementation-defined_ insert_return_type; +---- + +A specialization of an internal class template: + +[source,c++,subs=+quotes] +---- +template +struct _insert_return_type_ // name is exposition only +{ + bool inserted; + NodeType node; +}; +---- + +with `NodeType` = `node_type`. + +--- + +=== Constants + +```cpp static constexpr size_type bulk_visit_size; ``` + +Chunk size internally used in xref:concurrent_node_map_bulk_visit[bulk visit] operations. + +--- + +=== Constructors + +==== Default Constructor +```c++ concurrent_node_map(); ``` + +Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit concurrent_node_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + concurrent_node_map(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ concurrent_node_map(concurrent_node_map const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor +```c++ concurrent_node_map(concurrent_node_map&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template concurrent_node_map(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit concurrent_node_map(Allocator const& a); ``` + +Constructs an empty table, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ concurrent_node_map(concurrent_node_map const& other, Allocator const& a); ``` + +Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor with Allocator +```c++ concurrent_node_map(concurrent_node_map&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor from unordered_node_map + +```c++ concurrent_node_map(unordered_node_map&& other); ``` + +Move construction from a xref:#unordered_node_map[`unordered_node_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; O(`bucket_count()`) + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +concurrent_node_map(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ concurrent_node_map(size_type n, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ concurrent_node_map(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + concurrent_node_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + concurrent_node_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ concurrent_node_map(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ concurrent_node_map(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ concurrent_node_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~concurrent_node_map(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ concurrent_node_map& operator=(concurrent_node_map const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Move Assignment +```c++ concurrent_node_map& operator=(concurrent_node_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Initializer List Assignment +```c++ concurrent_node_map& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. + +--- + +=== Visitation + +==== [c]visit + +```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` + +If an element `x` exists with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. + +[horizontal] +Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Bulk visit + +```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` + +For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. + +Although functionally equivalent to individually invoking xref:concurrent_node_map_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_node_map_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. + +[horizontal] +Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. + +--- + +==== [c]visit_all + +```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` + +Successively invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. + +[horizontal] +Returns:;; The number of elements visited. + +--- + +==== Parallel [c]visit_all + +```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== [c]visit_while + +```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` + +Successively invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. + +--- + +==== Parallel [c]visit_while + +```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; The number of elements in the table. + +[horizontal] +Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible table. + +--- + +=== Modifiers + +==== emplace +```c++ template bool emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. + +--- + +==== Copy Insert +```c++ bool insert(const value_type& obj); bool insert(const init_type& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert +```c++ bool insert(value_type&& obj); bool insert(init_type&& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Insert Iterator Range +```c++ template size_type insert(InputIterator first, InputIterator last); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_map_emplace[emplace](*first++); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List +```c++ size_type insert(std::initializer_list il); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_map_insert_iterator_range[insert](il.begin(), il.end()); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node +```c++ insert_return_type insert(node_type&& nh); ``` + +If `nh` is not empty, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`. `nh` is empty when the function returns. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== emplace_or_[c]visit +```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `emplace_or_cvisit` is used. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +--- + +==== Copy insert_or_[c]visit +```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. + +--- + +==== Move insert_or_[c]visit +```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. + +--- + +==== Insert Iterator Range or Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_map_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List or Visit +```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_map_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node or Visit +```c++ template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); ``` + +If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `insert_or_cvisit` is used. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== emplace_and_[c]visit +```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `emplace_and_cvisit` is used. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. + +--- + +==== Copy insert_and_[c]visit +```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. + +--- + +==== Move insert_and_[c]visit +```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. + +--- + +==== Insert Iterator Range and Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f2, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_node_map_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List and Visit +```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_node_map_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Node and Visit +```c++ template insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); template insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); ``` + +If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`, and then invokes `f1` with a non-const reference to the newly inserted element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `insert_or_cvisit` is used. + +[horizontal] +Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + +* If `nh` is empty, `inserted` is `false` and `node` is empty. +* Otherwise if the insertion took place, `inserted` is true and `node` is empty. +* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. +Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f1` or `f2`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. + +--- + +==== try_emplace +```c++ template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This function is similiar to xref:#concurrent_node_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#concurrent_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace_or_[c]visit +```c++ template bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first four overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// last two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace_and_[c]visit +```c++ template bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first four overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// last two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +The interface is exposition only, as C++ does not allow to declare parameter `f1` and `f2` after a variadic parameter pack. + +The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== insert_or_assign +```c++ template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); ``` + +Inserts a new element into the table or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the table as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +[horizontal] +Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase +```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` + +Erases the element with key equivalent to `k` if it exists. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if by Key +```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` + +Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; `f` is passed a non-const reference to `x`. + + The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if +```c++ template size_type erase_if(F f); ``` + +Successively invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. + +--- + +==== Parallel erase_if +```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` + +Invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== swap +```c++ void swap(concurrent_node_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the table with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== extract +```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` + +Extracts the element with key equivalent to `k`, if it exists. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== extract_if +```c++ template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); ``` + +Extracts the element `x` with key equivalent to `k`, if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the table. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. + +--- + +==== merge +```c++ template size_type merge(concurrent_node_map& source); template size_type merge(concurrent_node_map&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +[horizontal] +Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The table's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The table's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The table's key equality predicate. + +--- + +=== Map Operations + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the table's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_map_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the table type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#concurrent_node_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#concurrent_node_map_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#concurrent_node_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const concurrent_node_map& x, const concurrent_node_map& y); ``` + +Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const concurrent_node_map& x, const concurrent_node_map& y); ``` + +Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(concurrent_node_map& x, concurrent_node_map& y) noexcept(noexcept(x.swap(y))); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +x.xref:#concurrent_node_map_swap[swap](y); +----- + +--- + +=== erase_if +```c++ template typename concurrent_node_map::size_type erase_if(concurrent_node_map& c, Predicate pred); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +c.xref:#concurrent_node_map_erase_if[erase_if](pred); +----- + +=== Serialization + +``concurrent_node_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an concurrent_node_map to an archive + +Saves all the elements of a `concurrent_node_map` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. + +--- + +==== Loading an concurrent_node_map from an archive + +Deletes all preexisting elements of a `concurrent_node_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_node_map` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. From fae016ffcdb515c2a1eec3b1bf6c5025fc022c24 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:24:11 +0000 Subject: [PATCH 54/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../concurrent_flat_set_zh_Hans.adoc | 1184 +++++++++++++++++ 1 file changed, 1184 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc new file mode 100644 index 0000000..5371a30 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc @@ -0,0 +1,1184 @@ +[#concurrent_flat_set] +== Class Template concurrent_flat_set + +:idprefix: concurrent_flat_set_ + +`boost::concurrent_flat_set` — A hash table that stores unique values and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. + +Even though it acts as a container, `boost::concurrent_flat_set` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access is done through user-provided _visitation functions_ that are passed to `concurrent_flat_set` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. + +The internal data structure of `boost::concurrent_flat_set` is similar to that of `boost::unordered_flat_set`. As a result of its using open-addressing techniques, `value_type` must be move-constructible and pointer stability is not kept under rehashing. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_concurrent_flat_set.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator> + class concurrent_flat_set { + public: + // types + using key_type = Key; + using value_type = Key; + using init_type = Key; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled] + + // constants + static constexpr size_type xref:#concurrent_flat_set_constants[bulk_visit_size] = _implementation-defined_; + + // construct/copy/destroy + xref:#concurrent_flat_set_default_constructor[concurrent_flat_set](); + explicit xref:#concurrent_flat_set_bucket_count_constructor[concurrent_flat_set](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#concurrent_flat_set_iterator_range_constructor[concurrent_flat_set](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_flat_set_copy_constructor[concurrent_flat_set](const concurrent_flat_set& other); + xref:#concurrent_flat_set_move_constructor[concurrent_flat_set](concurrent_flat_set&& other); + template + xref:#concurrent_flat_set_iterator_range_constructor_with_allocator[concurrent_flat_set](InputIterator f, InputIterator l,const allocator_type& a); + explicit xref:#concurrent_flat_set_allocator_constructor[concurrent_flat_set](const Allocator& a); + xref:#concurrent_flat_set_copy_constructor_with_allocator[concurrent_flat_set](const concurrent_flat_set& other, const Allocator& a); + xref:#concurrent_flat_set_move_constructor_with_allocator[concurrent_flat_set](concurrent_flat_set&& other, const Allocator& a); + xref:#concurrent_flat_set_move_constructor_from_unordered_flat_set[concurrent_flat_set](unordered_flat_set&& other); + xref:#concurrent_flat_set_initializer_list_constructor[concurrent_flat_set](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_flat_set_bucket_count_constructor_with_allocator[concurrent_flat_set](size_type n, const allocator_type& a); + xref:#concurrent_flat_set_bucket_count_constructor_with_hasher_and_allocator[concurrent_flat_set](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#concurrent_flat_set_iterator_range_constructor_with_bucket_count_and_allocator[concurrent_flat_set](InputIterator f, InputIterator l, size_type n, + const allocator_type& a); + template + xref:#concurrent_flat_set_iterator_range_constructor_with_bucket_count_and_hasher[concurrent_flat_set](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_flat_set_initializer_list_constructor_with_allocator[concurrent_flat_set](std::initializer_list il, const allocator_type& a); + xref:#concurrent_flat_set_initializer_list_constructor_with_bucket_count_and_allocator[concurrent_flat_set](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#concurrent_flat_set_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[concurrent_flat_set](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_flat_set_destructor[~concurrent_flat_set](); + concurrent_flat_set& xref:#concurrent_flat_set_copy_assignment[operator++=++](const concurrent_flat_set& other); + concurrent_flat_set& xref:#concurrent_flat_set_move_assignment[operator++=++](concurrent_flat_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value); + concurrent_flat_set& xref:#concurrent_flat_set_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#concurrent_flat_set_get_allocator[get_allocator]() const noexcept; + + + // visitation + template size_t xref:#concurrent_flat_set_cvisit[visit](const key_type& k, F f); + template size_t xref:#concurrent_flat_set_cvisit[visit](const key_type& k, F f) const; + template size_t xref:#concurrent_flat_set_cvisit[cvisit](const key_type& k, F f) const; + template size_t xref:#concurrent_flat_set_cvisit[visit](const K& k, F f); + template size_t xref:#concurrent_flat_set_cvisit[visit](const K& k, F f) const; + template size_t xref:#concurrent_flat_set_cvisit[cvisit](const K& k, F f) const; + + template + size_t xref:concurrent_flat_set_bulk_visit[visit](FwdIterator first, FwdIterator last, F f); + template + size_t xref:concurrent_flat_set_bulk_visit[visit](FwdIterator first, FwdIterator last, F f) const; + template + size_t xref:concurrent_flat_set_bulk_visit[cvisit](FwdIterator first, FwdIterator last, F f) const; + + template size_t xref:#concurrent_flat_set_cvisit_all[visit_all](F f); + template size_t xref:#concurrent_flat_set_cvisit_all[visit_all](F f) const; + template size_t xref:#concurrent_flat_set_cvisit_all[cvisit_all](F f) const; + template + void xref:#concurrent_flat_set_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f); + template + void xref:#concurrent_flat_set_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f) const; + template + void xref:#concurrent_flat_set_parallel_cvisit_all[cvisit_all](ExecutionPolicy&& policy, F f) const; + + template bool xref:#concurrent_flat_set_cvisit_while[visit_while](F f); + template bool xref:#concurrent_flat_set_cvisit_while[visit_while](F f) const; + template bool xref:#concurrent_flat_set_cvisit_while[cvisit_while](F f) const; + template + bool xref:#concurrent_flat_set_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f); + template + bool xref:#concurrent_flat_set_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f) const; + template + bool xref:#concurrent_flat_set_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; + + // capacity + ++[[nodiscard]]++ bool xref:#concurrent_flat_set_empty[empty]() const noexcept; + size_type xref:#concurrent_flat_set_size[size]() const noexcept; + size_type xref:#concurrent_flat_set_max_size[max_size]() const noexcept; + + // modifiers + template bool xref:#concurrent_flat_set_emplace[emplace](Args&&... args); + bool xref:#concurrent_flat_set_copy_insert[insert](const value_type& obj); + bool xref:#concurrent_flat_set_move_insert[insert](value_type&& obj); + template bool xref:#concurrent_flat_set_transparent_insert[insert](K&& k); + template size_type xref:#concurrent_flat_set_insert_iterator_range[insert](InputIterator first, InputIterator last); + size_type xref:#concurrent_flat_set_insert_initializer_list[insert](std::initializer_list il); + + template bool xref:#concurrent_flat_set_emplace_or_cvisit[emplace_or_visit](Args&&... args, F&& f); + template bool xref:#concurrent_flat_set_emplace_or_cvisit[emplace_or_cvisit](Args&&... args, F&& f); + template bool xref:#concurrent_flat_set_copy_insert_or_cvisit[insert_or_visit](const value_type& obj, F f); + template bool xref:#concurrent_flat_set_copy_insert_or_cvisit[insert_or_cvisit](const value_type& obj, F f); + template bool xref:#concurrent_flat_set_move_insert_or_cvisit[insert_or_visit](value_type&& obj, F f); + template bool xref:#concurrent_flat_set_move_insert_or_cvisit[insert_or_cvisit](value_type&& obj, F f); + template bool xref:#concurrent_flat_set_transparent_insert_or_cvisit[insert_or_visit](K&& k, F f); + template bool xref:#concurrent_flat_set_transparent_insert_or_cvisit[insert_or_cvisit](K&& k, F f); + template + size_type xref:#concurrent_flat_set_insert_iterator_range_or_visit[insert_or_visit](InputIterator first, InputIterator last, F f); + template + size_type xref:#concurrent_flat_set_insert_iterator_range_or_visit[insert_or_cvisit](InputIterator first, InputIterator last, F f); + template size_type xref:#concurrent_flat_set_insert_initializer_list_or_visit[insert_or_visit](std::initializer_list il, F f); + template size_type xref:#concurrent_flat_set_insert_initializer_list_or_visit[insert_or_cvisit](std::initializer_list il, F f); + + template + bool xref:#concurrent_flat_set_emplace_and_cvisit[emplace_and_visit](Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_set_emplace_and_cvisit[emplace_and_cvisit](Args&&... args, F1&& f1, F2&& f2); + template bool xref:#concurrent_flat_set_copy_insert_and_cvisit[insert_and_visit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_set_copy_insert_and_cvisit[insert_and_cvisit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_set_move_insert_and_cvisit[insert_and_visit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_set_move_insert_and_cvisit[insert_and_cvisit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_set_transparent_insert_and_cvisit[insert_and_visit](K&& k, F1 f1, F2 f2); + template bool xref:#concurrent_flat_set_transparent_insert_and_cvisit[insert_and_cvisit](K&& k, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_set_insert_iterator_range_and_visit[insert_and_visit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_set_insert_iterator_range_and_visit[insert_and_cvisit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_set_insert_initializer_list_and_visit[insert_and_visit](std::initializer_list il, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_set_insert_initializer_list_and_visit[insert_and_cvisit](std::initializer_list il, F1 f1, F2 f2); + + size_type xref:#concurrent_flat_set_erase[erase](const key_type& k); + template size_type xref:#concurrent_flat_set_erase[erase](const K& k); + + template size_type xref:#concurrent_flat_set_erase_if_by_key[erase_if](const key_type& k, F f); + template size_type xref:#concurrent_flat_set_erase_if_by_key[erase_if](const K& k, F f); + template size_type xref:#concurrent_flat_set_erase_if[erase_if](F f); + template void xref:#concurrent_flat_set_parallel_erase_if[erase_if](ExecutionPolicy&& policy, F f); + + void xref:#concurrent_flat_set_swap[swap](concurrent_flat_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + void xref:#concurrent_flat_set_clear[clear]() noexcept; + + template + size_type xref:#concurrent_flat_set_merge[merge](concurrent_flat_set& source); + template + size_type xref:#concurrent_flat_set_merge[merge](concurrent_flat_set&& source); + + // observers + hasher xref:#concurrent_flat_set_hash_function[hash_function]() const; + key_equal xref:#concurrent_flat_set_key_eq[key_eq]() const; + + // set operations + size_type xref:#concurrent_flat_set_count[count](const key_type& k) const; + template + size_type xref:#concurrent_flat_set_count[count](const K& k) const; + bool xref:#concurrent_flat_set_contains[contains](const key_type& k) const; + template + bool xref:#concurrent_flat_set_contains[contains](const K& k) const; + + // bucket interface + size_type xref:#concurrent_flat_set_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#concurrent_flat_set_load_factor[load_factor]() const noexcept; + float xref:#concurrent_flat_set_max_load_factor[max_load_factor]() const noexcept; + void xref:#concurrent_flat_set_set_max_load_factor[max_load_factor](float z); + size_type xref:#concurrent_flat_set_max_load[max_load]() const noexcept; + void xref:#concurrent_flat_set_rehash[rehash](size_type n); + void xref:#concurrent_flat_set_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_flat_set_get_stats[get_stats]() const; + void xref:#concurrent_flat_set_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + concurrent_flat_set(InputIterator, InputIterator, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type = xref:#concurrent_flat_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_set, Hash, Pred, Allocator>; + + template, class Pred = std::equal_to, + class Allocator = std::allocator> + concurrent_flat_set(std::initializer_list, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type = xref:#concurrent_flat_set_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_set; + + template + concurrent_flat_set(InputIterator, InputIterator, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_flat_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_flat_set(InputIterator, InputIterator, Allocator) + -> concurrent_flat_set, + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_flat_set(InputIterator, InputIterator, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> concurrent_flat_set, Hash, + std::equal_to>, Allocator>; + + template + concurrent_flat_set(std::initializer_list, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_flat_set, std::equal_to, Allocator>; + + template + concurrent_flat_set(std::initializer_list, Allocator) + -> concurrent_flat_set, std::equal_to, Allocator>; + + template + concurrent_flat_set(std::initializer_list, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type, Hash, Allocator) + -> concurrent_flat_set, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container +and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the table's value type. +`std::allocator_traits::pointer` and `std::allocator_traits::const_pointer` must be convertible to/from `value_type*` and `const value_type*`, respectively. + +|=== + +The elements of the table are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Concurrency Requirements and Guarantees + +Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: + +* Copy construction from `al` of an allocator rebound from `Alloc` +* `std::allocator_traits::allocate` +* `std::allocator_traits::deallocate` +* `std::allocator_traits::construct` +* `std::allocator_traits::destroy` + +In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. + +With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_flat_set` do not introduce data races — that is, they are thread-safe. + +If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_flat_set`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_flat_set` execute sequentially in a multithreaded scenario. + +An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. + +When executed internally by a `boost::concurrent_flat_set`, the following operations by a user-provided visitation function on the element passed do not introduce data races: + +* Read access to the element. +* Non-mutable modification of the element. +* Mutable modification of the element: +** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. + +Any `boost::concurrent_flat_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. + +Visitation functions executed by a `boost::concurrent_flat_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` + +In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. + +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. + +--- + +=== Constants + +```cpp static constexpr size_type bulk_visit_size; ``` + +Chunk size internally used in xref:concurrent_flat_set_bulk_visit[bulk visit] operations. + +=== Constructors + +==== Default Constructor +```c++ concurrent_flat_set(); ``` + +Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit concurrent_flat_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + concurrent_flat_set(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ concurrent_flat_set(concurrent_flat_set const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor +```c++ concurrent_flat_set(concurrent_flat_set&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template concurrent_flat_set(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit concurrent_flat_set(Allocator const& a); ``` + +Constructs an empty table, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ concurrent_flat_set(concurrent_flat_set const& other, Allocator const& a); ``` + +Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor with Allocator +```c++ concurrent_flat_set(concurrent_flat_set&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor from unordered_flat_set + +```c++ concurrent_flat_set(unordered_flat_set&& other); ``` + +Move construction from a xref:#unordered_flat_set[`unordered_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; O(`bucket_count()`) + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +concurrent_flat_set(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ concurrent_flat_set(size_type n, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ concurrent_flat_set(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + concurrent_flat_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + concurrent_flat_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ concurrent_flat_set(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ concurrent_flat_set(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ concurrent_flat_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~concurrent_flat_set(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ concurrent_flat_set& operator=(concurrent_flat_set const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Move Assignment +```c++ concurrent_flat_set& operator=(concurrent_flat_set&& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Initializer List Assignment +```c++ concurrent_flat_set& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. + +--- + +=== Visitation + +==== [c]visit + +```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` + +If an element `x` exists with key equivalent to `k`, invokes `f` with a const reference to `x`. + +[horizontal] +Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Bulk visit + +```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` + +For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a const reference to `x`. + +Although functionally equivalent to individually invoking xref:concurrent_flat_set_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_flat_set_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. + +[horizontal] +Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. + +--- + +==== [c]visit_all + +```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` + +Successively invokes `f` with const references to each of the elements in the table. + +[horizontal] +Returns:;; The number of elements visited. + +--- + +==== Parallel [c]visit_all + +```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with const references to each of the elements in the table. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== [c]visit_while + +```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` + +Successively invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. + +--- + +==== Parallel [c]visit_while + +```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; The number of elements in the table. + +[horizontal] +Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible table. + +--- + +=== Modifiers + +==== emplace +```c++ template bool emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Copy Insert +```c++ bool insert(const value_type& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Move Insert +```c++ bool insert(value_type&& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Transparent Insert +```c++ template bool insert(K&& k); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range +```c++ template size_type insert(InputIterator first, InputIterator last); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_set_emplace[emplace](*first++); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List +```c++ size_type insert(std::initializer_list il); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_set_insert_iterator_range[insert](il.begin(), il.end()); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== emplace_or_[c]visit +```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +--- + +==== Copy insert_or_[c]visit +```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Move insert_or_[c]visit +```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Transparent insert_or_[c]visit +```c++ template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range or Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_set_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List or Visit +```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_set_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== emplace_and_[c]visit +```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. + +--- + +==== Copy insert_and_[c]visit +```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Move insert_and_[c]visit +```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + +--- + +==== Transparent insert_and_[c]visit +```c++ template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); ``` + +Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Insert Iterator Range and Visit +```c++ template size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_set_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List and Visit +```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_set_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== erase +```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` + +Erases the element with key equivalent to `k` if it exists. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if by Key +```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` + +Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if +```c++ template size_type erase_if(F f); ``` + +Successively invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. + +--- + +==== Parallel erase_if +```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` + +Invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== swap +```c++ void swap(concurrent_flat_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the table with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the table. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. + +--- + +==== merge +```c++ template size_type merge(concurrent_flat_set& source); template size_type merge(concurrent_flat_set&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +[horizontal] +Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The table's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The table's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The table's key equality predicate. + +--- + +=== Set Operations + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the table's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates pointers and references to elements, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. + +Invalidates pointers and references to elements, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const concurrent_flat_set& x, const concurrent_flat_set& y); ``` + +Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const concurrent_flat_set& x, const concurrent_flat_set& y); ``` + +Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(concurrent_flat_set& x, concurrent_flat_set& y) noexcept(noexcept(x.swap(y))); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +x.xref:#concurrent_flat_set_swap[swap](y); +----- + +--- + +=== erase_if +```c++ template typename concurrent_flat_set::size_type erase_if(concurrent_flat_set& c, Predicate pred); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +c.xref:#concurrent_flat_set_erase_if[erase_if](pred); +----- + +=== Serialization + +``concurrent_flat_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an concurrent_flat_set to an archive + +Saves all the elements of a `concurrent_flat_set` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. + +--- + +==== Loading an concurrent_flat_set from an archive + +Deletes all preexisting elements of a `concurrent_flat_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_flat_set` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. From 6a7206835775f12635f65203c9dcc2450022edf8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Mon, 11 May 2026 21:24:21 +0000 Subject: [PATCH 55/60] Added translation using Weblate (Chinese (Simplified Han script)) --- .../concurrent_flat_map_zh_Hans.adoc | 1319 +++++++++++++++++ 1 file changed, 1319 insertions(+) create mode 100644 doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc new file mode 100644 index 0000000..bbb5f47 --- /dev/null +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc @@ -0,0 +1,1319 @@ +[#concurrent_flat_map] +== Class Template concurrent_flat_map + +:idprefix: concurrent_flat_map_ + +`boost::concurrent_flat_map` — A hash table that associates unique keys with another value and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. + +Even though it acts as a container, `boost::concurrent_flat_map` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access and modification are done through user-provided _visitation functions_ that are passed to `concurrent_flat_map` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. + +The internal data structure of `boost::concurrent_flat_map` is similar to that of `boost::unordered_flat_map`. As a result of its using open-addressing techniques, `value_type` must be move-constructible and pointer stability is not kept under rehashing. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +// #include xref:reference/header_concurrent_flat_map.adoc[``] + +namespace boost { +namespace unordered { + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + class concurrent_flat_map { + public: + // types + using key_type = Key; + using mapped_type = T; + using value_type = std::pair; + using init_type = std::pair< + typename std::remove_const::type, + typename std::remove_const::type + >; + using hasher = Hash; + using key_equal = Pred; + using allocator_type = Allocator; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled] + + // constants + static constexpr size_type xref:#concurrent_flat_map_constants[bulk_visit_size] = _implementation-defined_; + + // construct/copy/destroy + xref:#concurrent_flat_map_default_constructor[concurrent_flat_map](); + explicit xref:#concurrent_flat_map_bucket_count_constructor[concurrent_flat_map](size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + template + xref:#concurrent_flat_map_iterator_range_constructor[concurrent_flat_map](InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_flat_map_copy_constructor[concurrent_flat_map](const concurrent_flat_map& other); + xref:#concurrent_flat_map_move_constructor[concurrent_flat_map](concurrent_flat_map&& other); + template + xref:#concurrent_flat_map_iterator_range_constructor_with_allocator[concurrent_flat_map](InputIterator f, InputIterator l,const allocator_type& a); + explicit xref:#concurrent_flat_map_allocator_constructor[concurrent_flat_map](const Allocator& a); + xref:#concurrent_flat_map_copy_constructor_with_allocator[concurrent_flat_map](const concurrent_flat_map& other, const Allocator& a); + xref:#concurrent_flat_map_move_constructor_with_allocator[concurrent_flat_map](concurrent_flat_map&& other, const Allocator& a); + xref:#concurrent_flat_map_move_constructor_from_unordered_flat_map[concurrent_flat_map](unordered_flat_map&& other); + xref:#concurrent_flat_map_initializer_list_constructor[concurrent_flat_map](std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + xref:#concurrent_flat_map_bucket_count_constructor_with_allocator[concurrent_flat_map](size_type n, const allocator_type& a); + xref:#concurrent_flat_map_bucket_count_constructor_with_hasher_and_allocator[concurrent_flat_map](size_type n, const hasher& hf, const allocator_type& a); + template + xref:#concurrent_flat_map_iterator_range_constructor_with_bucket_count_and_allocator[concurrent_flat_map](InputIterator f, InputIterator l, size_type n, + const allocator_type& a); + template + xref:#concurrent_flat_map_iterator_range_constructor_with_bucket_count_and_hasher[concurrent_flat_map](InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_flat_map_initializer_list_constructor_with_allocator[concurrent_flat_map](std::initializer_list il, const allocator_type& a); + xref:#concurrent_flat_map_initializer_list_constructor_with_bucket_count_and_allocator[concurrent_flat_map](std::initializer_list il, size_type n, + const allocator_type& a); + xref:#concurrent_flat_map_initializer_list_constructor_with_bucket_count_and_hasher_and_allocator[concurrent_flat_map](std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + xref:#concurrent_flat_map_destructor[~concurrent_flat_map](); + concurrent_flat_map& xref:#concurrent_flat_map_copy_assignment[operator++=++](const concurrent_flat_map& other); + concurrent_flat_map& xref:#concurrent_flat_map_move_assignment[operator++=++](concurrent_flat_map&& other) ++noexcept( + (boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value);++ + concurrent_flat_map& xref:#concurrent_flat_map_initializer_list_assignment[operator++=++](std::initializer_list); + allocator_type xref:#concurrent_flat_map_get_allocator[get_allocator]() const noexcept; + + + // visitation + template size_t xref:#concurrent_flat_map_cvisit[visit](const key_type& k, F f); + template size_t xref:#concurrent_flat_map_cvisit[visit](const key_type& k, F f) const; + template size_t xref:#concurrent_flat_map_cvisit[cvisit](const key_type& k, F f) const; + template size_t xref:#concurrent_flat_map_cvisit[visit](const K& k, F f); + template size_t xref:#concurrent_flat_map_cvisit[visit](const K& k, F f) const; + template size_t xref:#concurrent_flat_map_cvisit[cvisit](const K& k, F f) const; + + template + size_t xref:concurrent_flat_map_bulk_visit[visit](FwdIterator first, FwdIterator last, F f); + template + size_t xref:concurrent_flat_map_bulk_visit[visit](FwdIterator first, FwdIterator last, F f) const; + template + size_t xref:concurrent_flat_map_bulk_visit[cvisit](FwdIterator first, FwdIterator last, F f) const; + + template size_t xref:#concurrent_flat_map_cvisit_all[visit_all](F f); + template size_t xref:#concurrent_flat_map_cvisit_all[visit_all](F f) const; + template size_t xref:#concurrent_flat_map_cvisit_all[cvisit_all](F f) const; + template + void xref:#concurrent_flat_map_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f); + template + void xref:#concurrent_flat_map_parallel_cvisit_all[visit_all](ExecutionPolicy&& policy, F f) const; + template + void xref:#concurrent_flat_map_parallel_cvisit_all[cvisit_all](ExecutionPolicy&& policy, F f) const; + + template bool xref:#concurrent_flat_map_cvisit_while[visit_while](F f); + template bool xref:#concurrent_flat_map_cvisit_while[visit_while](F f) const; + template bool xref:#concurrent_flat_map_cvisit_while[cvisit_while](F f) const; + template + bool xref:#concurrent_flat_map_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f); + template + bool xref:#concurrent_flat_map_parallel_cvisit_while[visit_while](ExecutionPolicy&& policy, F f) const; + template + bool xref:#concurrent_flat_map_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; + + // capacity + ++[[nodiscard]]++ bool xref:#concurrent_flat_map_empty[empty]() const noexcept; + size_type xref:#concurrent_flat_map_size[size]() const noexcept; + size_type xref:#concurrent_flat_map_max_size[max_size]() const noexcept; + + // modifiers + template bool xref:#concurrent_flat_map_emplace[emplace](Args&&... args); + bool xref:#concurrent_flat_map_copy_insert[insert](const value_type& obj); + bool xref:#concurrent_flat_map_copy_insert[insert](const init_type& obj); + bool xref:#concurrent_flat_map_move_insert[insert](value_type&& obj); + bool xref:#concurrent_flat_map_move_insert[insert](init_type&& obj); + template size_type xref:#concurrent_flat_map_insert_iterator_range[insert](InputIterator first, InputIterator last); + size_type xref:#concurrent_flat_map_insert_initializer_list[insert](std::initializer_list il); + + template bool xref:#concurrent_flat_map_emplace_or_cvisit[emplace_or_visit](Args&&... args, F&& f); + template bool xref:#concurrent_flat_map_emplace_or_cvisit[emplace_or_cvisit](Args&&... args, F&& f); + template bool xref:#concurrent_flat_map_copy_insert_or_cvisit[insert_or_visit](const value_type& obj, F f); + template bool xref:#concurrent_flat_map_copy_insert_or_cvisit[insert_or_cvisit](const value_type& obj, F f); + template bool xref:#concurrent_flat_map_copy_insert_or_cvisit[insert_or_visit](const init_type& obj, F f); + template bool xref:#concurrent_flat_map_copy_insert_or_cvisit[insert_or_cvisit](const init_type& obj, F f); + template bool xref:#concurrent_flat_map_move_insert_or_cvisit[insert_or_visit](value_type&& obj, F f); + template bool xref:#concurrent_flat_map_move_insert_or_cvisit[insert_or_cvisit](value_type&& obj, F f); + template bool xref:#concurrent_flat_map_move_insert_or_cvisit[insert_or_visit](init_type&& obj, F f); + template bool xref:#concurrent_flat_map_move_insert_or_cvisit[insert_or_cvisit](init_type&& obj, F f); + template + size_type xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or_visit](InputIterator first, InputIterator last, F f); + template + size_type xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or_cvisit](InputIterator first, InputIterator last, F f); + template size_type xref:#concurrent_flat_map_insert_initializer_list_or_visit[insert_or_visit](std::initializer_list il, F f); + template size_type xref:#concurrent_flat_map_insert_initializer_list_or_visit[insert_or_cvisit](std::initializer_list il, F f); + + template + bool xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_visit](Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_cvisit](Args&&... args, F1&& f1, F2&& f2); + template bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_visit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_cvisit](const value_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_visit](const init_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_cvisit](const init_type& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_visit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_cvisit](value_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_visit](init_type&& obj, F1 f1, F2 f2); + template bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_cvisit](init_type&& obj, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_visit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_cvisit](InputIterator first, InputIterator last, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_map_insert_initializer_list_and_visit[insert_and_visit](std::initializer_list il, F1 f1, F2 f2); + template + size_type xref:#concurrent_flat_map_insert_initializer_list_and_visit[insert_and_cvisit](std::initializer_list il, F1 f1, F2 f2); + + template bool xref:#concurrent_flat_map_try_emplace[try_emplace](const key_type& k, Args&&... args); + template bool xref:#concurrent_flat_map_try_emplace[try_emplace](key_type&& k, Args&&... args); + template bool xref:#concurrent_flat_map_try_emplace[try_emplace](K&& k, Args&&... args); + + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_visit](const key_type& k, Args&&... args, F&& f); + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_cvisit](const key_type& k, Args&&... args, F&& f); + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_visit](key_type&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_cvisit](key_type&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_visit](K&& k, Args&&... args, F&& f); + template + bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_cvisit](K&& k, Args&&... args, F&& f); + + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](const key_type& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](const key_type& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](key_type&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](key_type&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](K&& k, Args&&... args, F1&& f1, F2&& f2); + template + bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](K&& k, Args&&... args, F1&& f1, F2&& f2); + + template bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj); + template bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj); + template bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](K&& k, M&& obj); + + size_type xref:#concurrent_flat_map_erase[erase](const key_type& k); + template size_type xref:#concurrent_flat_map_erase[erase](const K& k); + + template size_type xref:#concurrent_flat_map_erase_if_by_key[erase_if](const key_type& k, F f); + template size_type xref:#concurrent_flat_map_erase_if_by_key[erase_if](const K& k, F f); + template size_type xref:#concurrent_flat_map_erase_if[erase_if](F f); + template void xref:#concurrent_flat_map_parallel_erase_if[erase_if](ExecutionPolicy&& policy, F f); + + void xref:#concurrent_flat_map_swap[swap](concurrent_flat_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + void xref:#concurrent_flat_map_clear[clear]() noexcept; + + template + size_type xref:#concurrent_flat_map_merge[merge](concurrent_flat_map& source); + template + size_type xref:#concurrent_flat_map_merge[merge](concurrent_flat_map&& source); + + // observers + hasher xref:#concurrent_flat_map_hash_function[hash_function]() const; + key_equal xref:#concurrent_flat_map_key_eq[key_eq]() const; + + // map operations + size_type xref:#concurrent_flat_map_count[count](const key_type& k) const; + template + size_type xref:#concurrent_flat_map_count[count](const K& k) const; + bool xref:#concurrent_flat_map_contains[contains](const key_type& k) const; + template + bool xref:#concurrent_flat_map_contains[contains](const K& k) const; + + // bucket interface + size_type xref:#concurrent_flat_map_bucket_count[bucket_count]() const noexcept; + + // hash policy + float xref:#concurrent_flat_map_load_factor[load_factor]() const noexcept; + float xref:#concurrent_flat_map_max_load_factor[max_load_factor]() const noexcept; + void xref:#concurrent_flat_map_set_max_load_factor[max_load_factor](float z); + size_type xref:#concurrent_flat_map_max_load[max_load]() const noexcept; + void xref:#concurrent_flat_map_rehash[rehash](size_type n); + void xref:#concurrent_flat_map_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_flat_map_get_stats[get_stats]() const; + void xref:#concurrent_flat_map_reset_stats[reset_stats]() noexcept; + }; + + // Deduction Guides + template>, + class Pred = std::equal_to>, + class Allocator = std::allocator>> + concurrent_flat_map(InputIterator, InputIterator, typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type = xref:#concurrent_flat_map_deduction_guides[__see below__], + Hash = Hash(), Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_map, xref:#concurrent_flat_map_iter_mapped_type[__iter-mapped-type__], Hash, + Pred, Allocator>; + + template, + class Pred = std::equal_to, + class Allocator = std::allocator>> + concurrent_flat_map(std::initializer_list>, + typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type = xref:#concurrent_flat_map_deduction_guides[__see below__], Hash = Hash(), + Pred = Pred(), Allocator = Allocator()) + -> concurrent_flat_map; + + template + concurrent_flat_map(InputIterator, InputIterator, typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type, Allocator) + -> concurrent_flat_map, xref:#concurrent_flat_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_flat_map(InputIterator, InputIterator, Allocator) + -> concurrent_flat_map, xref:#concurrent_flat_map_iter_mapped_type[__iter-mapped-type__], + boost::hash>, + std::equal_to>, Allocator>; + + template + concurrent_flat_map(InputIterator, InputIterator, typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type, Hash, + Allocator) + -> concurrent_flat_map, xref:#concurrent_flat_map_iter_mapped_type[__iter-mapped-type__], Hash, + std::equal_to>, Allocator>; + + template + concurrent_flat_map(std::initializer_list>, typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type, + Allocator) + -> concurrent_flat_map, std::equal_to, Allocator>; + + template + concurrent_flat_map(std::initializer_list>, Allocator) + -> concurrent_flat_map, std::equal_to, Allocator>; + + template + concurrent_flat_map(std::initializer_list>, typename xref:#concurrent_flat_map_deduction_guides[__see below__]::size_type, + Hash, Allocator) + -> concurrent_flat_map, Allocator>; + +} // namespace unordered +} // namespace boost +----- + +--- + +=== Description + +*Template Parameters* + +[cols="1,1"] +|=== + +|_Key_ +.2+|`Key` and `T` must be https://en.cppreference.com/w/cpp/named_req/MoveConstructible[MoveConstructible^]. +`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the table from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the table. + +|_T_ + +|_Hash_ +|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. + +|_Pred_ +|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. + +|_Allocator_ +|An allocator whose value type is the same as the table's value type. +Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. + +|=== + +The elements of the table are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. + +The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. + +If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. + +--- + +=== Concurrency Requirements and Guarantees + +Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: + +* Copy construction from `al` of an allocator rebound from `Alloc` +* `std::allocator_traits::allocate` +* `std::allocator_traits::deallocate` +* `std::allocator_traits::construct` +* `std::allocator_traits::destroy` + +In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. + +With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_flat_map` do not introduce data races — that is, they are thread-safe. + +If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_flat_map`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_flat_map` execute sequentially in a multithreaded scenario. + +An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. + +When executed internally by a `boost::concurrent_flat_map`, the following operations by a user-provided visitation function on the element passed do not introduce data races: + +* Read access to the element. +* Non-mutable modification of the element. +* Mutable modification of the element: +** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. + +Any `boost::concurrent_flat_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. + +Visitation functions executed by a `boost::concurrent_flat_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. + +--- + +=== Configuration Macros + +==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` + +In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. + +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. + +--- + +=== Constants + +```cpp static constexpr size_type bulk_visit_size; ``` + +Chunk size internally used in xref:concurrent_flat_map_bulk_visit[bulk visit] operations. + +=== Constructors + +==== Default Constructor +```c++ concurrent_flat_map(); ``` + +Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor +```c++ explicit concurrent_flat_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor +[source,c++,subs="+quotes"] +---- +template + concurrent_flat_map(InputIterator f, InputIterator l, + size_type n = _implementation-defined_, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Copy Constructor +```c++ concurrent_flat_map(concurrent_flat_map const& other); ``` + +The copy constructor. Copies the contained elements, hash function, predicate and allocator. + +If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. + +[horizontal] +Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor +```c++ concurrent_flat_map(concurrent_flat_map&& other); ``` + +The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Iterator Range Constructor with Allocator +```c++ template concurrent_flat_map(InputIterator f, InputIterator l, const allocator_type& a); ``` + +Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Allocator Constructor +```c++ explicit concurrent_flat_map(Allocator const& a); ``` + +Constructs an empty table, using allocator `a`. + +--- + +==== Copy Constructor with Allocator +```c++ concurrent_flat_map(concurrent_flat_map const& other, Allocator const& a); ``` + +Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor with Allocator +```c++ concurrent_flat_map(concurrent_flat_map&& other, Allocator const& a); ``` + +If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `other`. + +--- + +==== Move Constructor from unordered_flat_map + +```c++ concurrent_flat_map(unordered_flat_map&& other); ``` + +Move construction from a xref:#unordered_flat_map[`unordered_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. + +[horizontal] +Complexity:;; O(`bucket_count()`) + +--- + +==== Initializer List Constructor +[source,c++,subs="+quotes"] +---- +concurrent_flat_map(std::initializer_list il, + size_type n = _implementation-defined_ + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Allocator +```c++ concurrent_flat_map(size_type n, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Bucket Count Constructor with Hasher and Allocator +```c++ concurrent_flat_map(size_type n, hasher const& hf, allocator_type const& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. + +[horizontal] +Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Allocator +[source,c++,subs="+quotes"] +---- +template + concurrent_flat_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== Iterator Range Constructor with Bucket Count and Hasher +[source,c++,subs="+quotes"] +---- + template + concurrent_flat_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a); +---- + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Allocator + +```c++ concurrent_flat_map(std::initializer_list il, const allocator_type& a); ``` + +Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Allocator + +```c++ concurrent_flat_map(std::initializer_list il, size_type n, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +==== initializer_list Constructor with Bucket Count and Hasher and Allocator + +```c++ concurrent_flat_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` + +Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. + +[horizontal] +Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. + +--- + +=== Destructor + +```c++ ~concurrent_flat_map(); ``` + +[horizontal] +Note:;; The destructor is applied to every element, and all memory is deallocated + +--- + +=== Assignment + +==== Copy Assignment + +```c++ concurrent_flat_map& operator=(concurrent_flat_map const& other); ``` + +The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Move Assignment +```c++ concurrent_flat_map& operator=(concurrent_flat_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. + +[horizontal] +Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== Initializer List Assignment +```c++ concurrent_flat_map& operator=(std::initializer_list il); ``` + +Assign from values in initializer list. All previously existing elements are destroyed. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. + +--- + +=== Visitation + +==== [c]visit + +```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` + +If an element `x` exists with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. + +[horizontal] +Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== Bulk visit + +```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` + +For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. + +Although functionally equivalent to individually invoking xref:concurrent_flat_map_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_flat_map_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. + +[horizontal] +Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. + +--- + +==== [c]visit_all + +```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` + +Successively invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. + +[horizontal] +Returns:;; The number of elements visited. + +--- + +==== Parallel [c]visit_all + +```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== [c]visit_while + +```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` + +Successively invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. + +--- + +==== Parallel [c]visit_while + +```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` + +Invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. + +--- + +=== Size and Capacity + +==== empty + +```c++ [[nodiscard]] bool empty() const noexcept; ``` + +[horizontal] +Returns:;; `size() == 0` + +--- + +==== size + +```c++ size_type size() const noexcept; ``` + +[horizontal] +Returns:;; The number of elements in the table. + +[horizontal] +Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. + +--- + +==== max_size + +```c++ size_type max_size() const noexcept; ``` + +[horizontal] +Returns:;; `size()` of the largest possible table. + +--- + +=== Modifiers + +==== emplace +```c++ template bool emplace(Args&&... args); ``` + +Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. + +--- + +==== Copy Insert +```c++ bool insert(const value_type& obj); bool insert(const init_type& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Move Insert +```c++ bool insert(value_type&& obj); bool insert(init_type&& obj); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. + +--- + +==== Insert Iterator Range +```c++ template size_type insert(InputIterator first, InputIterator last); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_map_emplace[emplace](*first++); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List +```c++ size_type insert(std::initializer_list il); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_map_insert_iterator_range[insert](il.begin(), il.end()); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== emplace_or_[c]visit +```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `emplace_or_cvisit` is used. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +--- + +==== Copy insert_or_[c]visit +```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. + +--- + +==== Move insert_or_[c]visit +```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. + +--- + +==== Insert Iterator Range or Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_map_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List or Visit +```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== emplace_and_[c]visit +```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `emplace_and_cvisit` is used. + +[horizontal] +Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. + +--- + +==== Copy insert_and_[c]visit +```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. + +--- + +==== Move insert_and_[c]visit +```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); ``` + +Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. + +--- + +==== Insert Iterator Range and Visit +```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + while(first != last) this->xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== Insert Initializer List and Visit +```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- + this->xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); +----- + +[horizontal] +Returns:;; The number of elements inserted. + +--- + +==== try_emplace +```c++ template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This function is similiar to xref:#concurrent_flat_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +unlike xref:#concurrent_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. + +Invalidates pointers and references to elements if a rehashing is issued. + +The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace_or_[c]visit +```c++ template bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first four overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// last two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +Invalidates pointers and references to elements if a rehashing is issued. + +The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. + +The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== try_emplace_and_[c]visit +```c++ template bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); ``` + +Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. + +[horizontal] +Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +// first four overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) + +// last two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` + +Invalidates pointers and references to elements if a rehashing is issued. + +The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. + +The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +-- + +--- + +==== insert_or_assign +```c++ template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); ``` + +Inserts a new element into the table or updates an existing one by assigning to the contained value. + +If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. + +If there is no such element, it is added to the table as: ```c++ +// first two overloads +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) + +// third overload +value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` + +[horizontal] +Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase +```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` + +Erases the element with key equivalent to `k` if it exists. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if by Key +```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` + +Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. + +[horizontal] +Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; `f` is passed a non-const reference to `x`. + + The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + +--- + +==== erase_if +```c++ template size_type erase_if(F f); ``` + +Successively invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. + +[horizontal] +Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. + +--- + +==== Parallel erase_if +```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` + +Invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. + +[horizontal] +Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + +--- + +==== swap +```c++ void swap(concurrent_flat_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` + +Swaps the contents of the table with the parameter. + +If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. + +[horizontal] +Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. + +--- + +==== clear +```c++ void clear() noexcept; ``` + +Erases all elements in the table. + +[horizontal] +Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. + +--- + +==== merge +```c++ template size_type merge(concurrent_flat_map& source); template size_type merge(concurrent_flat_map&& source); ``` + +Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. + +[horizontal] +Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. + +--- + +=== Observers + +==== get_allocator +``` allocator_type get_allocator() const noexcept; ``` + +[horizontal] +Returns:;; The table's allocator. + +--- + +==== hash_function +``` hasher hash_function() const; ``` + +[horizontal] +Returns:;; The table's hash function. + +--- + +==== key_eq +``` key_equal key_eq() const; ``` + +[horizontal] +Returns:;; The table's key equality predicate. + +--- + +=== Map Operations + +==== count +```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` + +[horizontal] +Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== contains +```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` + +[horizontal] +Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- +=== Bucket Interface + +==== bucket_count +```c++ size_type bucket_count() const noexcept; ``` + +[horizontal] +Returns:;; The size of the bucket array. + +--- + +=== Hash Policy + +==== load_factor +```c++ float load_factor() const noexcept; ``` + +[horizontal] +Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. + +--- + +==== max_load_factor + +```c++ float max_load_factor() const noexcept; ``` + +[horizontal] +Returns:;; Returns the table's maximum load factor. + +--- + +==== Set max_load_factor +```c++ void max_load_factor(float z); ``` + +[horizontal] +Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. + +--- + + +==== max_load + +```c++ size_type max_load() const noexcept; ``` + +[horizontal] +Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. + +--- + +==== rehash +```c++ void rehash(size_type n); ``` + +Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. + +When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. + +Invalidates pointers and references to elements, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- + +==== reserve +```c++ void reserve(size_type n); ``` + +Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. + +Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. + +Invalidates pointers and references to elements, and changes the order of elements. + +[horizontal] +Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. + +--- + +=== Statistics + +==== get_stats +```c++ stats get_stats() const; ``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ void reset_stats() noexcept; ``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +=== Deduction Guides +A deduction guide will not participate in overload resolution if any of the following are true: + +- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + +A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the table type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. + +==== __iter-value-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-value-type__ = + typename std::iterator_traits::value_type; // exposition only +----- + +==== __iter-key-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-key-type__ = std::remove_const_t< + std::tuple_element_t<0, xref:#concurrent_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +==== __iter-mapped-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-mapped-type__ = + std::tuple_element_t<1, xref:#concurrent_flat_map_iter_value_type[__iter-value-type__]>; // exposition only +----- + +==== __iter-to-alloc-type__ +[listings,subs="+macros,+quotes"] +----- +template + using __iter-to-alloc-type__ = std::pair< + std::add_const_t>>, + std::tuple_element_t<1, xref:#concurrent_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only +----- + +=== Equality Comparisons + +==== operator +```c++ template bool operator==(const concurrent_flat_map& x, const concurrent_flat_map& y); ``` + +Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +==== operator! +```c++ template bool operator!=(const concurrent_flat_map& x, const concurrent_flat_map& y); ``` + +Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). + +[horizontal] +Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. + +--- + +=== Swap +```c++ template void swap(concurrent_flat_map& x, concurrent_flat_map& y) noexcept(noexcept(x.swap(y))); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +x.xref:#concurrent_flat_map_swap[swap](y); +----- + +--- + +=== erase_if +```c++ template typename concurrent_flat_map::size_type erase_if(concurrent_flat_map& c, Predicate pred); ``` + +Equivalent to [listing,subs="+macros,+quotes"] +----- +c.xref:#concurrent_flat_map_erase_if[erase_if](pred); +----- + +=== Serialization + +``concurrent_flat_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. + +==== Saving an concurrent_flat_map to an archive + +Saves all the elements of a `concurrent_flat_map` `x` to an archive (XML archive) `ar`. + +[horizontal] +Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. + +--- + +==== Loading an concurrent_flat_map from an archive + +Deletes all preexisting elements of a `concurrent_flat_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_flat_map` `other` saved to the storage read by `ar`. + +[horizontal] +Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. From a5d6fa082fb927c3cdba70b5692b00cb748be23c Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:24:30 +0000 Subject: [PATCH 56/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Node Set (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-node-set-adoc/ --- .../ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc index 912fb8f..a58cb07 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc @@ -340,14 +340,14 @@ When executed internally by a `boost::concurrent_node_set`, the following operat * Read access to the element. * Non-mutable modification of the element. * Mutable modification of the element: -** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. - Any `boost::concurrent_node_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. Visitation functions executed by a `boost::concurrent_node_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. --- +--- + === Configuration Macros ==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` From 7d779f0b464e05ab04d94cbbbf5ef7cabed75cb2 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:24:34 +0000 Subject: [PATCH 57/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Node Map (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-node-map-adoc/ --- .../ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc index a6fa6a0..6a7fcdc 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc @@ -393,14 +393,14 @@ When executed internally by a `boost::concurrent_node_map`, the following operat * Read access to the element. * Non-mutable modification of the element. * Mutable modification of the element: -** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. - Any `boost::concurrent_node_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. Visitation functions executed by a `boost::concurrent_node_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. --- +--- + === Configuration Macros ==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` From 488a16faee1b1a343e490139df7a17c619f1b5a1 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:24:51 +0000 Subject: [PATCH 58/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Flat Set (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-flat-set-adoc/ --- .../ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc index 5371a30..8f58914 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc @@ -323,14 +323,14 @@ When executed internally by a `boost::concurrent_flat_set`, the following operat * Read access to the element. * Non-mutable modification of the element. * Mutable modification of the element: -** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. - Any `boost::concurrent_flat_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. Visitation functions executed by a `boost::concurrent_flat_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. --- +--- + === Configuration Macros ==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` From c43fb55d6bc8080f86577dc4764a0dddf7c872e3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 11 May 2026 21:25:08 +0000 Subject: [PATCH 59/60] Update translation files Updated by "Cleanup translation files" add-on in Weblate. Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Flat Map (adoc) Translate-URL: https://boost-weblate.cloud/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-flat-map-adoc/ --- .../ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc index bbb5f47..55ed491 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc @@ -375,14 +375,14 @@ When executed internally by a `boost::concurrent_flat_map`, the following operat * Read access to the element. * Non-mutable modification of the element. * Mutable modification of the element: -** Within a container function accepting two visitation functions, always for the first function. ** Within a non-const container function whose name does not contain `cvisit`, for the last (or only) visitation function. - Any `boost::concurrent_flat_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. Visitation functions executed by a `boost::concurrent_flat_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. --- +--- + === Configuration Macros ==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` From 3c2b6997c7c8c583056e81ca97a6d559e39fe718 Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 13 May 2026 04:26:09 +0000 Subject: [PATCH 60/60] Add translations manually. --- doc/modules/ROOT/nav_zh_Hans.adoc | 78 +- .../ROOT/pages/benchmarks_zh_Hans.adoc | 472 ++++-- .../ROOT/pages/bibliography_zh_Hans.adoc | 12 +- doc/modules/ROOT/pages/buckets_zh_Hans.adoc | 112 +- doc/modules/ROOT/pages/changes_zh_Hans.adoc | 660 ++++---- .../ROOT/pages/compliance_zh_Hans.adoc | 73 +- .../ROOT/pages/concurrent_zh_Hans.adoc | 127 +- doc/modules/ROOT/pages/copyright_zh_Hans.adoc | 18 +- .../ROOT/pages/debuggability_zh_Hans.adoc | 85 +- .../ROOT/pages/hash_equality_zh_Hans.adoc | 143 +- .../ROOT/pages/hash_quality_zh_Hans.adoc | 38 +- doc/modules/ROOT/pages/intro_zh_Hans.adoc | 62 +- doc/modules/ROOT/pages/rationale_zh_Hans.adoc | 82 +- doc/modules/ROOT/pages/ref_zh_Hans.adoc | 74 +- .../concurrent_flat_map_zh_Hans.adoc | 1315 ++++++++++----- .../concurrent_flat_set_zh_Hans.adoc | 1194 +++++++++----- .../concurrent_node_map_zh_Hans.adoc | 1398 +++++++++++----- .../concurrent_node_set_zh_Hans.adoc | 1282 ++++++++++----- .../pages/reference/hash_traits_zh_Hans.adoc | 14 +- ...eader_concurrent_flat_map_fwd_zh_Hans.adoc | 4 +- .../header_concurrent_flat_map_zh_Hans.adoc | 20 +- ...eader_concurrent_flat_set_fwd_zh_Hans.adoc | 4 +- .../header_concurrent_flat_set_zh_Hans.adoc | 20 +- ...eader_concurrent_node_map_fwd_zh_Hans.adoc | 4 +- .../header_concurrent_node_map_zh_Hans.adoc | 20 +- ...eader_concurrent_node_set_fwd_zh_Hans.adoc | 4 +- .../header_concurrent_node_set_zh_Hans.adoc | 20 +- ...header_unordered_flat_map_fwd_zh_Hans.adoc | 4 +- .../header_unordered_flat_map_zh_Hans.adoc | 20 +- ...header_unordered_flat_set_fwd_zh_Hans.adoc | 4 +- .../header_unordered_flat_set_zh_Hans.adoc | 20 +- .../header_unordered_map_fwd_zh_Hans.adoc | 4 +- .../header_unordered_map_top_zh_Hans.adoc | 4 +- .../header_unordered_map_zh_Hans.adoc | 26 +- ...header_unordered_node_map_fwd_zh_Hans.adoc | 4 +- .../header_unordered_node_map_zh_Hans.adoc | 20 +- ...header_unordered_node_set_fwd_zh_Hans.adoc | 4 +- .../header_unordered_node_set_zh_Hans.adoc | 20 +- .../header_unordered_set_fwd_zh_Hans.adoc | 4 +- .../header_unordered_set_top_zh_Hans.adoc | 4 +- .../header_unordered_set_zh_Hans.adoc | 26 +- .../ROOT/pages/reference/stats_zh_Hans.adoc | 32 +- .../reference/unordered_flat_map_zh_Hans.adoc | 1179 +++++++++----- .../reference/unordered_flat_set_zh_Hans.adoc | 1006 ++++++++---- .../reference/unordered_map_zh_Hans.adoc | 1412 ++++++++++++----- .../reference/unordered_multimap_zh_Hans.adoc | 1169 ++++++++++---- .../reference/unordered_multiset_zh_Hans.adoc | 1154 ++++++++++---- .../reference/unordered_node_map_zh_Hans.adoc | 1251 ++++++++++----- .../reference/unordered_node_set_zh_Hans.adoc | 1083 +++++++++---- .../reference/unordered_set_zh_Hans.adoc | 1208 +++++++++----- doc/modules/ROOT/pages/regular_zh_Hans.adoc | 220 +-- .../ROOT/pages/structures_zh_Hans.adoc | 118 +- 52 files changed, 11669 insertions(+), 5662 deletions(-) diff --git a/doc/modules/ROOT/nav_zh_Hans.adoc b/doc/modules/ROOT/nav_zh_Hans.adoc index 7143f6a..86f087b 100644 --- a/doc/modules/ROOT/nav_zh_Hans.adoc +++ b/doc/modules/ROOT/nav_zh_Hans.adoc @@ -1,51 +1,51 @@ -* xref:intro.adoc[] -* xref:buckets.adoc[] -* xref:hash_equality.adoc[] -* xref:regular.adoc[] -* xref:concurrent.adoc[] -* xref:hash_quality.adoc[] -* xref:compliance.adoc[] -* xref:structures.adoc[] -* xref:debuggability.adoc[] -* xref:benchmarks.adoc[] -* xref:rationale.adoc[] -* xref:ref.adoc[] -** xref:reference/header_unordered_map_fwd.adoc[``] -** xref:reference/header_unordered_map_top.adoc[``] -** xref:reference/header_unordered_map.adoc[``] +* xref:intro.adoc[介绍] +* xref:buckets.adoc[桶] +* xref:hash_equality.adoc[哈希相等性] +* xref:regular.adoc[常规] +* xref:concurrent.adoc[并发] +* xref:hash_quality.adoc[哈希质量] +* xref:compliance.adoc[合规性] +* xref:structures.adoc[结构] +* xref:debuggability.adoc[可调试性] +* xref:benchmarks.adoc[基准测试] +* xref:rationale.adoc[设计依据] +* xref:ref.adoc[参考文档] +** xref:reference/header_unordered_map_fwd.adoc[`++<++boost/unordered/unordered++_++map++_++fwd.hpp++>++`] +** xref:reference/header_unordered_map_top.adoc[`++<++boost/unordered++_++map.hpp++>++`] +** xref:reference/header_unordered_map.adoc[`++<++boost/unordered/unordered++_++map.hpp++>++`] ** xref:reference/unordered_map.adoc[`unordered_map`] ** xref:reference/unordered_multimap.adoc[`unordered_multimap`] -** xref:reference/header_unordered_set_fwd.adoc[``] -** xref:reference/header_unordered_set_top.adoc[``] -** xref:reference/header_unordered_set.adoc[``] +** xref:reference/header_unordered_set_fwd.adoc[`++<++boost/unordered/unordered++_++set++_++fwd.hpp++>++`] +** xref:reference/header_unordered_set_top.adoc[`++<++boost/unordered++_++set.hpp++>++`] +** xref:reference/header_unordered_set.adoc[`++<++boost/unordered/unordered++_++set.hpp++>++`] ** xref:reference/unordered_set.adoc[`unordered_set`] ** xref:reference/unordered_multiset.adoc[`unordered_multiset`] -** xref:reference/hash_traits.adoc[Hash Traits] -** xref:reference/stats.adoc[Statistics] -** xref:reference/header_unordered_flat_map_fwd.adoc[``] -** xref:reference/header_unordered_flat_map.adoc[``] +** xref:reference/hash_traits.adoc[哈希特征] +** xref:reference/stats.adoc[统计信息] +** xref:reference/header_unordered_flat_map_fwd.adoc[`++<++boost/unordered/unordered++_++flat++_++map++_++fwd.hpp++>++`] +** xref:reference/header_unordered_flat_map.adoc[`++<++boost/unordered/unordered++_++flat++_++map.hpp++>++`] ** xref:reference/unordered_flat_map.adoc[`unordered_flat_map`] -** xref:reference/header_unordered_flat_set_fwd.adoc[``] -** xref:reference/header_unordered_flat_set.adoc[``] +** xref:reference/header_unordered_flat_set_fwd.adoc[`++<++boost/unordered/unordered++_++flat++_++set++_++fwd.hpp++>++`] +** xref:reference/header_unordered_flat_set.adoc[`++<++boost/unordered/unordered++_++flat++_++set.hpp++>++`] ** xref:reference/unordered_flat_set.adoc[`unordered_flat_set`] -** xref:reference/header_unordered_node_map_fwd.adoc[``] -** xref:reference/header_unordered_node_map.adoc[``] +** xref:reference/header_unordered_node_map_fwd.adoc[`++<++boost/unordered/unordered++_++node++_++map++_++fwd.hpp++>++`] +** xref:reference/header_unordered_node_map.adoc[`++<++boost/unordered/unordered++_++node++_++map.hpp++>++`] ** xref:reference/unordered_node_map.adoc[`unordered_node_map`] -** xref:reference/header_unordered_node_set_fwd.adoc[``] -** xref:reference/header_unordered_node_set.adoc[``] +** xref:reference/header_unordered_node_set_fwd.adoc[`++<++boost/unordered/unordered++_++node++_++set++_++fwd.hpp++>++`] +** xref:reference/header_unordered_node_set.adoc[`++<++boost/unordered/unordered++_++node++_++set.hpp++>++`] ** xref:reference/unordered_node_set.adoc[`unordered_node_set`] -** xref:reference/header_concurrent_flat_map_fwd.adoc[``] -** xref:reference/header_concurrent_flat_map.adoc[``] +** xref:reference/header_concurrent_flat_map_fwd.adoc[`++<++boost/unordered/concurrent++_++flat++_++map++_++fwd.hpp++>++`] +** xref:reference/header_concurrent_flat_map.adoc[`++<++boost/unordered/concurrent++_++flat++_++map.hpp++>++`] ** xref:reference/concurrent_flat_map.adoc[`concurrent_flat_map`] -** xref:reference/header_concurrent_flat_set_fwd.adoc[``] -** xref:reference/header_concurrent_flat_set.adoc[``] +** xref:reference/header_concurrent_flat_set_fwd.adoc[`++<++boost/unordered/concurrent++_++flat++_++set++_++fwd.hpp++>++`] +** xref:reference/header_concurrent_flat_set.adoc[`++<++boost/unordered/concurrent++_++flat++_++set.hpp++>++`] ** xref:reference/concurrent_flat_set.adoc[`concurrent_flat_set`] -** xref:reference/header_concurrent_node_map_fwd.adoc[``] -** xref:reference/header_concurrent_node_map.adoc[``] +** xref:reference/header_concurrent_node_map_fwd.adoc[`++<++boost/unordered/concurrent++_++node++_++map++_++fwd.hpp++>++`] +** xref:reference/header_concurrent_node_map.adoc[`++<++boost/unordered/concurrent++_++node++_++map.hpp++>++`] ** xref:reference/concurrent_node_map.adoc[`concurrent_node_map`] -** xref:reference/header_concurrent_node_set_fwd.adoc[``] -** xref:reference/header_concurrent_node_set.adoc[``] +** xref:reference/header_concurrent_node_set_fwd.adoc[`++<++boost/unordered/concurrent++_++node++_++set++_++fwd.hpp++>++`] +** xref:reference/header_concurrent_node_set.adoc[`++<++boost/unordered/concurrent++_++node++_++set.hpp++>++`] ** xref:reference/concurrent_node_set.adoc[`concurrent_node_set`] -* xref:changes.adoc[] -* xref:bibliography.adoc[] -* xref:copyright.adoc[] +* xref:changes.adoc[变更记录] +* xref:bibliography.adoc[参考文献] +* xref:copyright.adoc[版权声明] diff --git a/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc index c3d2c6e..6f511e5 100644 --- a/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc @@ -1,274 +1,335 @@ [#benchmarks] :idprefix: benchmarks_ -= Benchmarks += 基准测试 -== boost::unordered_[multi]set +== boost::unordered++_[++multi++]++set -All benchmarks were created using `unordered_set` (non-duplicate) and `unordered_multiset` (duplicate). The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_set[found here^]. +所有基准测试均使用 `unordered++_++set++<++unsigned int++>++`(非重复元素) 和 `unordered++_++multiset++<++unsigned int++>++` (重复元素)创建。源代码可 https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_set[在此处获取] 。 -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. +插入基准测试会插入 `n` 个随机值,其中 `n` 的范围在10,000至300万之间。在重复值测试场景中,同一组随机值会平均重复插入 5 次。 -The erasure benchmarks erase all `n` elements randomly until the container is empty. Erasure by key uses `erase(const key_type&)` to remove entire groups of equivalent elements in each operation. +在擦除基准测试中,随机删除所有 `n` 个元素直至容器为空。通过键擦除操作使用 `erase(const key++_++type&)` 方法,每次调用将移除整个等效元素组。 -The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order. +成功查找基准测试通过按照元素的原始插入顺序查找全部 `n` 个值来完成。 -The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value. +未命中查找基准测试使用不同种子值生成的 `n` 个随机整数进行。 -=== GCC 12 + libstdc++-v3, x64 +=== GCC 12 {plus} libstdc{plus}{plus}-v3, x64 -==== Insertion +==== 插入 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/gcc/running insertion.xlsx.practice.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice.png,window=_blank] |image::benchmarks-set/gcc/running insertion.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice non-unique.png,window=_blank] |image::benchmarks-set/gcc/running insertion.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice non-unique 5.png,window=_blank] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 |=== +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/gcc/running insertion.xlsx.practice norehash.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice norehash.png,window=_blank] |image::benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique.png[width=250,link=_images/benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique.png,window=_blank] |image::benchmarks-set/gcc/running insertion.xlsx.practice norehash non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/running insertion.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` +h|非重复元素, + +预先 `reserve` +h|重复元素, + +预先 `reserve` +h|重复元素, + +最大负载因子 5, + +预先 `reserve` |=== -==== Erasure +==== 擦除 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/gcc/scattered erasure.xlsx.practice.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice.png,window=_blank] |image::benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique.png,window=_blank] |image::benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure.xlsx.practice non-unique 5.png,window=_blank] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 | |image::benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] |image::benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/gcc/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] | -h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 +h|通过键操作, 重复元素 +h|通过键操作, 重复元素, + +最大负载因子 5 |=== -==== Successful Lookup +==== 成功查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.xlsx.practice.png] |image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered successful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -==== Unsuccessful lookup +==== 未命中查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice.png] |image::benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/gcc/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -=== Clang 15 + libc++, x64 +=== Clang 15 {plus} libc{plus}{plus}, x64 -==== Insertion +==== 插入 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice.png] |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique.png] |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique 5.png[width=250, window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash.png] |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique.png] |image::benchmarks-set/clang_libcpp/running insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/running insertion.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` +h|非重复元素, + +预先 `reserve` +h|重复元素, + +预先 `reserve` +h|重复元素, + +最大负载因子 5, + +预先 `reserve` |=== -==== Erasure +==== 擦除 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice.png] |image::benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique.png] |image::benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered erasure.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 | |image::benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] |image::benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/clang_libcpp/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] | -h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 +h|通过键操作, 重复元素 +h|通过键操作, 重复元素, + +最大负载因子 5 |=== -==== Successful lookup +==== 成功查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice.png] |image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered successful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -==== Unsuccessful lookup +==== 未命中查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice.png] |image::benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/clang_libcpp/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -=== Visual Studio 2022 + Dinkumware, x64 +=== Visual Studio 2022 {plus} Dinkumware, x64 -==== Insertion +==== 插入 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/vs/running insertion.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice.png] |image::benchmarks-set/vs/running insertion.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice non-unique.png] |image::benchmarks-set/vs/running insertion.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/vs/running insertion.xlsx.practice norehash.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice norehash.png] |image::benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique.png] |image::benchmarks-set/vs/running insertion.xlsx.practice norehash non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/running insertion.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` +h|非重复元素, + +预先 `reserve` +h|重复元素, + +预先 `reserve` +h|重复元素, + +最大负载因子 5, + +预先 `reserve` |=== -==== Erasure +==== 擦除 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/vs/scattered erasure.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice.png] |image::benchmarks-set/vs/scattered erasure.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice non-unique.png] |image::benchmarks-set/vs/scattered erasure.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered erasure.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 | |image::benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique.png[width=250,link=_images/benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique.png,window=_blank] |image::benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique 5.png[width=250,link=_images/benchmarks-set/vs/scattered erasure by key.xlsx.practice non-unique 5.png,window=_blank] | -h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 +h|通过键操作, 重复元素 +h|通过键操作, 重复元素, + +最大负载因子 5 |=== -==== Successful lookup +==== 成功查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/vs/scattered successful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.xlsx.practice.png] |image::benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered successful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -==== Unsuccessful lookup +==== 未命中查找 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice.png] |image::benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique.png] |image::benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique 5.png[width=250,window=_blank,link=_images/benchmarks-set/vs/scattered unsuccessful looukp.xlsx.practice non-unique 5.png] -h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load factor 5 +h|非重复元素 +h|重复元素 +h|重复元素, + +最大负载因子 5 |=== -== boost::unordered_(flat|node)_map +== boost::unordered++_++(flat++|++node)++_++map -All benchmarks were created using: +所有基准测试均为使用以下链接来创建的: -* `https://abseil.io/docs/cpp/guides/container[absl::flat_hash_map^]` -* `boost::unordered_map` -* `boost::unordered_flat_map` -* `boost::unordered_node_map` +* https://abseil.io/docs/cpp/guides/container[`absl::flat++_++hash++_++map`^]`++<++uint64++_++t, uint64++_++t++>++` +* `boost::unordered++_++map++<++uint64++_++t, uint64++_++t++>++` +* `boost::unordered++_++flat++_++map++<++uint64++_++t, uint64++_++t++>++` +* `boost::unordered++_++node++_++map++<++uint64++_++t, uint64++_++t++>++` -The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_flat_map[found here^]. +源代码可 https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_unordered_flat_map[在此处获取] 。 -The insertion benchmarks insert `n` random values, where `n` is between 10,000 and 10 million. +插入基准测试的操作将插入 `n` 个随机值,其中 `n` 的范围在10,000至1000万之间。 -The erasure benchmarks erase traverse the `n` elements and erase those with odd key (50% on average). +擦除基准测试会遍历全部 `n` 个元素,并删除其中键值为奇数的元素(平均约占50%)。 -The successful lookup benchmarks are done by looking up all `n` values, in their original insertion order. +成功查找基准测试通过按照元素的原始插入顺序查找全部 `n` 个值来完成。 -The unsuccessful lookup benchmarks use `n` randomly generated integers but using a different seed value. +未命中查找基准测试使用不同种子值生成的 `n` 个随机整数进行。 === GCC 12, x64 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/gcc-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Running insertion.xlsx.plot.png] @@ -276,15 +337,18 @@ The unsuccessful lookup benchmarks use `n` randomly generated integers but using |image::benchmarks-flat_map/gcc-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/gcc-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x64/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === Clang 15, x64 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/clang-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Running insertion.xlsx.plot.png] @@ -292,15 +356,18 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/clang-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/clang-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x64/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === Visual Studio 2022, x64 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/vs-x64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Running insertion.xlsx.plot.png] @@ -308,15 +375,18 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/vs-x64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/vs-x64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x64/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === Clang 12, ARM64 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/clang-arm64/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Running insertion.xlsx.plot.png] @@ -324,15 +394,18 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/clang-arm64/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/clang-arm64/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-arm64/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === GCC 12, x86 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/gcc-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Running insertion.xlsx.plot.png] @@ -340,15 +413,18 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/gcc-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/gcc-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/gcc-x86/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === Clang 15, x86 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/clang-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Running insertion.xlsx.plot.png] @@ -356,15 +432,18 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/clang-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/clang-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/clang-x86/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== === Visual Studio 2022, x86 -[caption=] -[cols="4*^.^a", frame=all, grid=all] +[caption=""] +[cols="4*^.^a", frame=all,, grid=all] |=== |image::benchmarks-flat_map/vs-x86/Running insertion.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Running insertion.xlsx.plot.png] @@ -372,182 +451,269 @@ h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup |image::benchmarks-flat_map/vs-x86/Scattered successful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Scattered successful looukp.xlsx.plot.png] |image::benchmarks-flat_map/vs-x86/Scattered unsuccessful looukp.xlsx.plot.png[width=250,window=_blank,link=_images/benchmarks-flat_map/vs-x86/Scattered unsuccessful looukp.xlsx.plot.png] -h|running insertion h|running erasure h|successful lookup h|unsuccessful lookup +h|插入的执行 +h|擦除的执行 +h|成功查找 +h|未命中查找 |=== -== boost::concurrent_(flat|node)_map +== boost::concurrent++_++(flat++|++node)++_++map -All benchmarks were created using: +所有基准测试均为使用以下链接来创建的: -* `https://spec.oneapi.io/versions/latest/elements/oneTBB/source/containers/concurrent_hash_map_cls.html[oneapi::tbb::concurrent_hash_map^]` -* `https://github.com/greg7mdp/gtl/blob/main/docs/phmap.md[gtl::parallel_flat_hash_map^]` with 64 submaps -* `boost::concurrent_flat_map` -* `boost::concurrent_node_map` +* https://spec.oneapi.io/versions/latest/elements/oneTBB/source/containers/concurrent_hash_map_cls.html[`oneapi::tbb::concurrent++_++hash++_++map`^]`++<++int, int++>++` +* https://github.com/greg7mdp/gtl/blob/main/docs/phmap.md[`gtl::parallel++_++flat++_++hash++_++map`^]`++<++int, int++>++` (含64个子映射) +* `boost::concurrent++_++flat++_++map++<++int, int++>++` +* `boost::concurrent++_++node++_++map++<++int, int++>++` -The source code can be https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_concurrent_flat_map[found here^]. +源代码可 https://github.com/boostorg/boost_unordered_benchmarks/tree/boost_concurrent_flat_map[在此处获取] 。 -The benchmarks exercise a number of threads _T_ (between 1 and 16) concurrently performing operations randomly chosen among **update**, **successful lookup** and **unsuccessful lookup**. The keys used in the operations follow a https://en.wikipedia.org/wiki/Zipf%27s_law#Formal_definition[Zipf distribution^] with different _skew_ parameters: the higher the skew, the more concentrated are the keys in the lower values of the covered range. +基准测试使用__T__个线程(数量1至16之间)并发执行随机选择的操作,这些操作包括**更新**、**成功查找**和**未命中查找**三种类型。操作使用的键遵循 https://en.wikipedia.org/wiki/Zipf%27s_law#Formal_definition[齐夫分布] ,并采用不同的__偏斜__参数:偏斜值越高,键的分布越集中在取值区间的较低数值区域。 -`boost::concurrent_flat_map` and `boost::concurrent_node_map` are exercised using both regular and xref:concurrent.adoc#concurrent_bulk_visitation[bulk visitation]: in the latter case, lookup keys are buffered in a local array and then processed at once each time the buffer reaches `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_constants[bulk_visit_size]`. +测试对 `boost::concurrent++_++flat++_++map` 与 `boost::concurrent++_++node++_++map` 均采用了常规访问与 xref:concurrent.adoc#concurrent_bulk_visitation[批量访问] 两种模式:对于后者,查找键会先缓存在本地数组中,待缓冲区达到 xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_constants[`bulk++_++visit++_++size`] 大小时再统一处理。 === GCC 12, x64 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x64/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === Clang 15, x64 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x64/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === Visual Studio 2022, x64 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x64/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === Clang 12, ARM64 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-arm64/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === GCC 12, x86 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/gcc-x86/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === Clang 15, x86 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/clang-x86/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== === Visual Studio 2022, x86 -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.01.png"] |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.5.png"] |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.500k, 0.99.png"] -h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 h|500k updates, 4.5M lookups + skew=0.99 |=== +h|50万次更新, 450万次查找 + +偏斜=0.01 +h|50万次更新, 450万次查找 + +偏斜=0.5 +h|50万次更新, 450万次查找 + +偏斜=0.99 +|=== -[caption=] -[cols="3*^.^a", frame=all, grid=all] +[caption=""] +[cols="3*^.^a", frame=all,, grid=all] |=== |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.01.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.01.png"] |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.5.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.5.png"] |image::benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.99.png[width=250,window=_blank,link="_images/benchmarks-concurrent_map/vs-x86/Parallel workload.xlsx.5M, 0.99.png"] -h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M updates, 45M lookups + skew=0.99 |=== +h|500万次更新, 4500万次查找 + +偏斜=0.01 +h|500万次更新, 4500万次查找 + +偏斜=0.5 +h|500万次更新, 4500万次查找 + +偏斜=0.99 +|=== diff --git a/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc b/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc index 020d3c0..9567853 100644 --- a/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc @@ -2,11 +2,11 @@ :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 introduction to the standard unordered containers. -* _Wikipedia_. https://en.wikipedia.org/wiki/Hash_table[Hash table^]. + -An introduction to hash table implementations. Discusses the differences between closed-addressing and open-addressing approaches. -* Peter Dimov, 2022. https://pdimov.github.io/articles/unordered_dev_plan.html[Development Plan for Boost.Unordered^]. +* _C/C{plus}{plus}用户期刊_,2006年2月. Pete Becker. http://www.ddj.com/cpp/184402066[STL与TR1:第三部分 — 无序容器^] 。 + +关于标准无序容器的介绍性文章。 +* __维基百科__中的 https://en.wikipedia.org/wiki/Hash_table[哈希表^] 。 + +这是关于哈希表实现原理的概述,重点探讨了链地址法和开放地址法两种实现路径的差异。 +* Peter Dimov,2022年。 https://pdimov.github.io/articles/unordered_dev_plan.html[Boost.Unordered库开发计划^] 。 diff --git a/doc/modules/ROOT/pages/buckets_zh_Hans.adoc b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc index 0b7c2a0..bf4f94d 100644 --- a/doc/modules/ROOT/pages/buckets_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc @@ -1,101 +1,105 @@ [#buckets] :idprefix: buckets_ -= Basics of Hash Tables += 哈希表基础 -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 a `xref:reference/unordered_set.adoc#unordered_set[boost::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). +该容器由若干__桶__组成,每个桶可容纳任意数量的元素。例如,下图展示了一个包含7个桶的 xref:reference/unordered_set.adoc#unordered_set[`boost::unordered++_++set`] ,其中存储着5个元素( `A` 、 `B` 、 `C` 、 `D` 和 `E` )(此示意图仅为演示用途,实际容器通常包含更多桶)。 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 sets 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. +容器通过哈希函数 `Hash` 作用于元素的键来确定其所属的桶(对于集合而言,键即元素本身,但为统一集合与映射表的术语仍称作键)。该函数返回 `std::size++_++t` 类型的值。由于 `std::size++_++t` 的取值范围远大于桶的数量,容器会对此值进行二次转换以确定元素应存入的桶。 -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. +根据指定键检索元素的过程非常简单:首先对键执行相同处理以定位对应桶,随后通过相等性谓词 `Pred` 将键与桶内元素进行比较以寻找匹配项。若哈希函数表现良好,元素将均匀分布于各桶中,此时仅需检查少量元素即可完成检索。 -There is xref:hash_equality.adoc#hash_equality[more information on hash functions and equality predicates in the next section]. +关于哈希函数与相等性谓词的详细说明请参阅 xref:hash_equality.adoc#hash_equality[后续章节] 。 -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. +如图所示, `A` 与 `D` 被置于同一桶内。在此桶内查找元素时最多需要进行 2 次比对,这会降低检索效率,该现象称为**冲突**。为维持高效运作,我们需尽可能减少冲突的发生。 -If instead of `boost::unordered_set` we had used `xref:reference/unordered_flat_set.adoc[boost::unordered_flat_set]`, the diagram would look as follows: +若使用 xref:reference/unordered_flat_set.adoc[`boost::unordered++_++flat++_++set`] 替代 `boost::unordered++_++set` ,其结构示意图将呈现如下形式: image::buckets-oa.png[] -In open-addressing containers, buckets can hold at most one element; if a collision happens (like is the case of `D` in the example), the element uses some other available bucket in the vicinity of the original position. Given this simpler scenario, Boost.Unordered open-addressing containers offer a very limited API for accessing buckets. +在开放寻址式容器中,每个桶最多只能容纳一个元素;若发生冲突(如示例中的元素 `D` 的情况),该元素将使用原始位置附近的其他可用桶。基于此简化设计,Boost.Unordered开放寻址容器仅提供极其有限的桶访问API。 -[caption=, title='Table {counter:table-counter}. Methods for Accessing Buckets'] -[cols="1,.^1", frame=all, grid=rows] +[caption=",", title='Table {counter:table-counter}. Methods for Accessing Buckets'] +[cols="1,.^1", frame=all,, grid=rows] |=== -2+^h| *All containers* h|*Method* h|*Description* +2+^h| *所有容器* +h|*方法* h|*描述* -|`size_type bucket_count() const` -|The number of buckets. +|`size++_++type bucket++_++count() const` +|桶的数量。 -2+^h| *Closed-addressing containers only* h|*Method* h|*Description* +2+^h| *仅限闭寻址容器* +h|*方法* h|*描述* -|`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 max++_++bucket++_++count() const` +|桶数量的上限。 +|`size++_++type bucket++_++size(size++_++type n) const` +|返回桶 `n` 中的元素数量。 -|`size_type bucket(key_type const& k) const` -|Returns the index of the bucket which would contain `k`. +|`size++_++type bucket(key++_++type const& k) const` +|返回键 `k` 所对应的桶的索引。 -|`local_iterator begin(size_type n)` -1.6+|Return begin and end iterators for bucket `n`. +|`local++_++iterator begin(size++_++type n)` +1.6+|返回编号为 `n` 的桶的起始与末尾迭代器。 -|`local_iterator end(size_type n)` +|`local++_++iterator end(size++_++type n)` -|`const_local_iterator begin(size_type n) const` +|`const++_++local++_++iterator begin(size++_++type n) const` -|`const_local_iterator end(size_type n) const` +|`const++_++local++_++iterator end(size++_++type n) const` -|`const_local_iterator cbegin(size_type n) const` +|`const++_++local++_++iterator cbegin(size++_++type n) const` -|`const_local_iterator cend(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 collisions 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`. +当无序关联容器中的元素不断增加时,冲突次数会随之上升,从而导致性能下降。为解决此问题,容器会在插入元素过程中自动增加桶的数量。用户也可以通过调用 `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 number of elements divided by the number of buckets. 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`. +* 用户可在构造容器或调用 `rehash` 方法时指定桶数量的最小值。 +* 用户可通过调用 `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. +`max++_++load++_++factor` 并不允许用户自行设定最大负载因子,该方法仅用于提供__提示__。即便如此,标准也并未强制要求容器必须严格遵守该数值。唯一强制要求负载因子必须小于最大值的场景是在调用 `rehash` 方法之后。但大多数实现会尝试将元素数量维持在最大负载因子以下,并将最大负载因子设定为与提示值相同或接近——除非用户提供的提示值过小或过大。 -[caption=, title='Table {counter:table-counter}. Methods for Controlling Bucket Size'] -[cols="1,.^1", frame=all, grid=rows] +[caption=",", title='Table {counter:table-counter}. Methods for Controlling Bucket Size'] +[cols="1,.^1", frame=all,, grid=rows] |=== -2+^h| *All containers* h|*Method* h|*Description* +2+^h| *所有容器* +h|*方法* h|*描述* -|`X(size_type n)` -|Construct an empty container with at least `n` buckets (`X` is the container type). +|`X(size++_++type n)` +|构造一个至少包含 `n` 个桶的空容器( `X` 表示容器类型)。 -|`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). +|`X(InputIterator i, InputIterator j, size++_++type n)` +|构造一个至少包含 `n` 个桶的空容器,并插入范围 `++[++i, j)` 中的元素( `X` 表示容器类型)。 -|`float load_factor() const` -|The average number of elements per bucket. +|`float load++_++factor() const` +|返回每个桶的平均元素数量。 -|`float max_load_factor() const` -|Returns the current maximum load factor. +|`float max++_++load++_++factor() const` +|返回当前的最大负载因子。 -|`float max_load_factor(float z)` -|Changes the container's maximum load factor, using `z` as a hint. + -**Open-addressing and concurrent containers:** this function does nothing: users are not allowed to change the maximum load factor. +|`float max++_++load++_++factor(float z)` +|以 `z` 作为提示值来更改容器的最大负载因子。 + +**开放寻址与并发容器:**此函数无效,用户不允许更改最大负载因子。 -|`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. +|`void rehash(size++_++type n)` +|调整桶的数量,使其至少为 `n` ,并确保负载因子小于最大负载因子。 -2+^h| *Open-addressing and concurrent containers only* h|*Method* h|*Description* +2+^h| *仅限开放寻址与并发容器* +h|*方法* h|*描述* -|`size_type max_load() const` -|Returns the maximum number of allowed elements in the container before rehash. +|`size++_++type max++_++load() const` +|返回容器触发重新哈希前所允许容纳的最大元素数量。 |=== -A note on `max_load` for open-addressing and concurrent containers: the maximum load will be (`max_load_factor() * bucket_count()`) right after `rehash` or on container creation, but may slightly decrease when erasing elements in high-load situations. For instance, if we have a `xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map]` with `size()` almost at `max_load()` level and then erase 1,000 elements, `max_load()` may decrease by around a few dozen elements. This is done internally by Boost.Unordered in order to keep its performance stable, and must be taken into account when planning for rehash-free insertions. +关于开放寻址与并发容器的 `max++_++load` 注意事项:在容器创建或执行 `rehash` 后,最大负载值将保持为 `max++_++load++_++factor() ++*++ bucket++_++count()` ;但在高负载场景下执行元素删除操作时,该值可能轻微下降。例如,若某个 xref:reference/unordered_flat_map.adoc#unordered_flat_map[`boost::unordered++_++flat++_++map`] 的 `size()` 已接近 `max++_++load()` 阈值,随后删除 1,000 个元素时, `max++_++load()` 可能减少约数十个元素。此机制是Boost.Unordered为保持性能稳定而采取的内部机制,用户在规划无重组插入操作时需予以考虑。 diff --git a/doc/modules/ROOT/pages/changes_zh_Hans.adoc b/doc/modules/ROOT/pages/changes_zh_Hans.adoc index a6297f3..0365af5 100644 --- a/doc/modules/ROOT/pages/changes_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/changes_zh_Hans.adoc @@ -1,392 +1,322 @@ [#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.89.0 - -* Deprecated `boost::unordered::hash_is_avalanching` is now a using-declaration of -`boost::hash_is_avalanching` in ``. Use that header directly instead. `` will be removed in the future. -* Added `pull(const_iterator)` to open-addressing containers. This operation -allows for efficient removal and retrieval of an element via move construction. - -== Release 1.88.0 - -* Migrated the documentation to a multipage format using Antora. - -== Release 1.87.0 - Major update - -* Added concurrent, node-based containers `boost::concurrent_node_map` and `boost::concurrent_node_set`. -* Added `insert_and_visit(x, f1, f2)` and similar operations to concurrent containers, which -allow for visitation of an element right after insertion (by contrast, `insert_or_visit(x, f)` only visits the element if insertion did _not_ take place). -* Made visitation exclusive-locked within certain -`boost::concurrent_flat_set` operations to allow for safe mutable modification of elements ({github-pr-url}/265[PR#265^]). -* In Visual Studio Natvis, supported any container with an allocator that uses fancy pointers. This applies to any fancy pointer type, as long as the proper Natvis customization point "Intrinsic" functions are written for the fancy pointer type. -* Added GDB pretty-printers for all containers and iterators. For a container with an allocator that uses fancy pointers, these only work if the proper pretty-printer is written for the fancy pointer type itself. -* Fixed `std::initializer_list` assignment issues for open-addressing containers -({github-pr-url}/277[PR#277^]). -* Allowed non-copyable callables to be passed to the `std::initializer_list` overloads of `insert_{and|or}_[c]visit` for concurrent containers, by internally passing a `std::reference_wrapper` of the callable to the iterator-pair overloads. - - -== Release 1.86.0 - -* Added container `pmr` aliases when header `` is available. The alias `boost::unordered::pmr::[container]` refers to `boost::unordered::[container]` with a `std::pmr::polymorphic_allocator` allocator type. -* Equipped open-addressing and concurrent containers to internally calculate and provide statistical metrics affected by the quality of the hash function. This functionality is enabled by the global macro `BOOST_UNORDERED_ENABLE_STATS`. -* Avalanching hash functions must now be marked via an `is_avalanching` typedef with an embedded `value` constant set to `true` (typically, defining `is_avalanching` as `std::true_type`). `using is_avalanching = void` is deprecated but allowed for backwards compatibility. -* Added Visual Studio Natvis framework custom visualizations for containers and iterators. This works for all containers with an allocator using raw pointers. In this release, containers and iterators are not supported if their allocator uses fancy pointers. This may be addressed in later releases. - -== Release 1.85.0 - -* Optimized `emplace()` for a `value_type` or `init_type` (if applicable) argument to bypass creating an intermediate object. The argument is already the same type as the would-be intermediate object. -* Optimized `emplace()` for `k,v` arguments on map containers to delay constructing the object until it is certain that an element should be inserted. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. -* Fixed support for allocators with `explicit` copy constructors ({github-pr-url}/234[PR#234^]). -* Fixed bug in the `const` version of `unordered_multimap::find(k, hash, eq)` ({github-pr-url}/238[PR#238^]). - -== Release 1.84.0 - Major update - -* Added `boost::concurrent_flat_set`. -* Added `[c]visit_while` operations to concurrent containers, -with serial and parallel variants. -* Added efficient move construction of `boost::unordered_flat_(map|set)` from -`boost::concurrent_flat_(map|set)` and vice versa. -* Added bulk visitation to concurrent containers for increased lookup performance. -* Added debug-mode mechanisms for detecting illegal reentrancies into -a concurrent container from user code. -* Added Boost.Serialization support to all containers and their (non-local) iterator types. -* Added support for fancy pointers to open-addressing and concurrent containers. -This enables scenarios like the use of Boost.Interprocess allocators to construct containers in shared memory. -* Fixed bug in member of pointer operator for local iterators of closed-addressing -containers ({github-pr-url}/221[PR#221^], credit goes to GitHub user vslashg for finding and fixing this issue). -* Starting with this release, `boost::unordered_[multi]set` and `boost::unordered_[multi]map` -only work with C++11 onwards. - -== Release 1.83.0 - Major update - -* Added `boost::concurrent_flat_map`, a fast, thread-safe hashmap based on open addressing. -* Sped up iteration of open-addressing containers. -* In open-addressing containers, `erase(iterator)`, which previously returned nothing, now -returns a proxy object convertible to an iterator to the next element. This enables the typical `it = c.erase(it)` idiom without incurring any performance penalty when the returned proxy is not used. - -== Release 1.82.0 - Major update - -* {cpp}03 support is planned for deprecation. Boost 1.84.0 will no longer support -{cpp}03 mode and {cpp}11 will become the new minimum for using the library. -* Added node-based, open-addressing containers -`boost::unordered_node_map` and `boost::unordered_node_set`. -* Extended heterogeneous lookup to more member functions as specified in -https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html[P2363]. -* Replaced the previous post-mixing process for open-addressing containers with -a new algorithm based on extended multiplication by a constant. -* Fixed bug in internal emplace() impl where stack-local types were not properly -constructed using the Allocator of the container which breaks uses-allocator construction. - -== Release 1.81.0 - Major update - -* Added fast containers `boost::unordered_flat_map` and `boost::unordered_flat_set` -based on open addressing. -* Added CTAD deduction guides for all containers. -* Added missing constructors as specified in https://cplusplus.github.io/LWG/issue2713[LWG issue 2713]. - -== 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: -allocate ({github-pr-url}/59[PR#59^]). -* 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. -** All containers have been updated to support heterogeneous `erase` and `extract`. -* Improved {cpp}23 support: -allocate ({github-pr-url}/59[PR#59^]). -* All containers have been updated to support heterogeneous `erase` and `extract`. -* Changed behavior of `reserve` to eagerly -* Various warning fixes in the test suite. -* Update code to internally use `boost::allocator_traits`. - -== Release 1.67.0 - -* Improved {cpp}17 support: -will work. -* Improved {cpp}20 support: -and other uses of the Dinkumware standard library, now using Boost.Predef to check compiler and library versions. -* Improved {cpp}20 support: -in order to remove dependency on Boost.Iterator. -* Use `boost::to_address`, which has the proposed {cpp}20 semantics, rather than the old custom implementation. -deprecated in {cpp}17, thanks to Daniela Engert ({github-pr-url}/7[PR#7^]). -* Add `element_type` to iterators, so that `std::pointer_traits` -in order to remove dependency on Boost.Iterator. -* Use `std::piecewise_construct` on recent versions of Visual {cpp}, -deprecated in {cpp}17, thanks to Daniela Engert ({github-pr-url}/7[PR#7^]). -* Use `std::iterator_traits` rather than the boost iterator traits -* Remove iterators' inheritance from `std::iterator`, which is -* Stop using `BOOST_DEDUCED_TYPENAME`. -* Update some Boost include paths. -* Rename some internal methods, and variables. - -== 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 +:idprefix: changes_ +:svn-ticket-url: https://svn.boost.org/trac/boost/ticket +:github-pr-url: https://github.com/boostorg/unordered/pull +:cpp: C++ -* 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:compliance.adoc[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. +== 版本 1.89.0 + +* 已弃用的 `boost::unordered::hash++_++is++_++avalanching` 现为 `++<++boost/container++_++hash/hash++_++is++_++avalanching.hpp++>++` 头文件中 `boost::hash++_++is++_++avalanching` 的 别名声明。请直接使用该头文件, `++<++boost/unordered/hash++_++traits.hpp++>++` 将在未来版本中移除。 +* 为开放寻址容器新增 `pull(const++_++iterator)` 操作,该操作支持通过移动构造机制高效移除并检索指定元素。 + +== 版本 1.88.0 + +* 使用 Antora 将文档重构为多页面格式。 + +== 版本 1.87.0 - 重大更新 + +* 新增基于节点的并发容器 `boost::concurrent++_++node++_++map` 与 `boost::concurrent++_++node++_++set` 。 +* 为并发容器新增 `insert++_++and++_++visit(x, f1, f2)` 及类似操作,这些操作支持在插入元素后立即对其进行访问(而 `insert++_++or++_++visit(x, f)` 仅在未执行插入时才访问元素)。 +* 在特定 `boost::concurrent++_++flat++_++set` 操作中启用独占锁访问机制,以支持对元素进行安全的可变修改(https://github.com/boostorg/unordered/pull/265[PR#265])。 +* 在 Visual Studio Natvis 中,现支持使用带花式指针分配器的任意容器。只要为花式指针类型编写了相应的 Natvis 自定义“Intrinsic”函数,即可适用于所有花式指针类型。 +* 为所有容器和迭代器添加 GDB 美化打印器。对于使用花式指针分配器的容器,需先为花式指针类型编写对应的美化打印器方可正常使用。 +* 修复开放寻址容器中 `std::initializer++_++list` 的 赋值问题(https://github.com/boostorg/unordered/pull/277[PR#277])。 +* 通过内部将可调用对象的 `std::reference++_++wrapper` 传递给迭代器对重载,现允许向并发容器的 `insert++_{++and++|++or}++_[++c++]++visit` 的 `std::initializer++_++list` 重载传递不可复制的可调用对象。 + + +== 版本 1.86.0 + +* 当头文件 `++<++memory++_++resource++>++` 可用时,新增容器 `pmr` 别名。 `boost::unordered::pmr::++[++container++]++` 别名指向使用 `std::pmr::polymorphic++_++allocator` 分配器类型的 `boost::unordered::++[++container++]++` 。 +* 为开放寻址容器与并发容器增设内部统计功能,可计算并提供受哈希函数质量影响的统计指标。通过全局宏 `BOOST++_++UNORDERED++_++ENABLE++_++STATS` 启用。 +* 雪崩哈希函数现在必须通过包含 `value` 常量且其值为 `true` 的 `is++_++avalanching` 类型别名进行标记(通常将 `is++_++avalanching` 定义为 `std::true++_++type` )。虽然出于向后兼容性考虑仍允许使用 `using is++_++avalanching = void` ,但该用法已被弃用。 +* 为容器和迭代器添加 Visual Studio Natvis 框架的自定义可视化功能。此功能适用于所有使用原始指针分配器的容器。在此版本中,若容器或迭代器的分配器使用花式指针,则暂不支持该功能,此问题可能在后续版本中解决。 -* `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`. +== 版本 1.85.0 -== Release 1.45.0 +* 优化 `emplace()` 对 `value++_++type` 或 `init++_++type` (如适用)参数的实现,使其无需创建中间对象即可直接处理参数,因为该参数类型与待构造的中间对象类型完全相同。 +* 优化 map 容器的 `emplace()` 对 `k,v` 参数的处理:将对象构造延迟到确认需要插入元素时执行。此优化在映射的 `key++_++type` 可移动构造或 `k` 参数为 `key++_++type` 类型时生效。 +* 修复对含 `explicit` 复制构造函数的分配器的支持(https://github.com/boostorg/unordered/pull/234[PR#234])。 +* 修复 `unordered++_++multimap::find(k, hash, eq)` 的 `const` 版本中的缺陷(https://github.com/boostorg/unordered/pull/238[PR#238])。 + +== 版本 1.84.0 - 重大更新 + +* 新增 `boost::concurrent++_++flat++_++set` 。 +* 为并发容器新增 `++[++c++]++visit++_++while` 操作,提供串行与并行两种执行模式。 +* 实现 `boost::unordered++_++flat++_++(map++|++set)` 与 `boost::concurrent++_++flat++_++(map++|++set)` 之间的高效双向移动构造。 +* 为并发容器新增批量访问功能以提升查找性能。 +* 新增调试模式机制,用于检测用户代码对并发容器的非法重入操作。 +* 为所有容器及其(非本地)迭代器类型添加 Boost.Serialization 支持。 +* 为开放寻址容器与并发容器新增对花式指针的支持,此特性支持诸如使用 Boost.Interprocess 分配器在共享内存中构建容器等应用场景。 +* 修复闭寻址容器局部迭代器的成员指针运算符缺陷(https://github.com/boostorg/unordered/pull/221[PR#221] ,致谢 GitHub 用户 vslashg 发现并修复)。 +* 从此版本起, `boost::unordered++_[++multi++]++set` 和 `boost::unordered++_[++multi++]++map` 仅支持 C{plus}{plus}11 及以上版本。 + +== 版本 1.83.0 - 重大更新 + +* 新增基于开放寻址的快速线程安全哈希映射容器 `boost::concurrent++_++flat++_++map` 。 +* 提升开放寻址容器的迭代性能。 +* 在开放寻址容器中,原无返回值的 `erase(iterator)` 方法现返回一个可转换为下一元素迭代器的代理对象。此改进支持典型的 `it = c.erase(it)` 编程范式,且当未使用返回的代理对象时不会产生任何性能开销。 + +== 版本 1.82.0 - 重大更新 + +* 计划弃用 C{plus}{plus}03 支持。Boost 1.84.0 将不再支持 C{plus}{plus}03 模式,C{plus}{plus}11 将成为使用该库的最低要求。 +* 新增基于节点的开放寻址容器 `boost::unordered++_++node++_++map` 与 `boost::unordered++_++node++_++set` 。 +* 根据 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2363r5.html[P2363] 规范,将异构查找功能扩展至更多成员函数。 +* 采用基于常量扩展乘法的新算法,取代开放寻址容器原有的后混合处理流程。 +* 修复内部 emplace() 实现中存在的缺陷:该缺陷曾导致栈局部类型未能使用容器的分配器进行正确构造,从而违反分配器感知构造规范。 + +== 版本 1.81.0 - 重大更新 + +* 新增基于开放寻址的快速容器 `boost::unordered++_++flat++_++map` 与 `boost::unordered++_++flat++_++set` 。 +* 为所有容器添加 CTAD 推导指引。 +* 补充 https://cplusplus.github.io/LWG/issue2713[LWG 问题 2713] 中要求的缺失构造函数。 + +== 版本 1.80.0 - 重大更新 + +* 重构内部实现以显著提升性能 +* 允许 使用 `final` 修饰的 Hasher 和 KeyEqual 对象 +* 更新文档,新增性能基准对比图及关于新内部数据结构的说明 -* Fix a bug when inserting into an `unordered_map` or `unordered_set` using -iterators which returns `value_type` by copy. +== 版本 1.79.0 + +* 增强 C{plus}{plus}20 标准兼容性: + ** 所有容器均已完成升级,支持异构查找操作 `count` 、 `equal++_++range` 及 + `find` 。 + ** 所有容器现均已实现成员函数 `contains` 。 + ** 所有容器均已实现 `erase++_++if` 功能。 +* 增强 C{plus}{plus}23 标准兼容性: + ** 所有容器均已完成升级,支持异构版本的 `erase` + 与 `extract` 操作。 +* 更改 `reserve` 的行为,使其立即分配桶数组空间(https://github.com/boostorg/unordered/pull/59[PR#59])。 +* 测试套件中的多项警告修复。 +* 将内部代码更新为使用 `boost::allocator++_++traits` 。 +* 切换至斐波那契哈希算法。 +* 将文档编写格式从 QuickBook 切换为 AsciiDoc。 -== Release 1.43.0 +== 版本 1.67.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. +* 增强 C{plus}{plus}17 标准兼容性: + ** 新增标准的模板推导指南。 + ** 在节点句柄中采用简化的 `optional` 实现,以使其 + 更符合标准规范。 + ** 为 `swap` 、 `operator=` 及节点句柄补充缺失的 `noexcept` + 规范,调整实现以符合规范要求。在实现中使用 `std::allocator++_++traits::is++_++always++_++equal` (若该特性不可用则采用自有实现),以及 `boost::is++_++nothrow++_++swappable` 在实现中。 +* 增强 C{plus}{plus}20 标准兼容性: + ** 使用具有 C{plus}{plus}20 提案语义的 `boost::to++_++address` , + 来替代原有的自定义实现。 +* 向迭代器添加 `element++_++type` 类型定义,以支持 `std::pointer++_++traits` 的正常工作。 +* 在新版 Visual C{plus}{plus} 及其他使用 Dinkumware 标准库的环境中使用 `std::piecewise++_++construct` , 现在使用 Boost.Predef 来检查编译器和标准库版本。 +* 使用 `std::iterator++_++traits` 替代 boost 迭代器特征库,以消除对 Boost.Iterator 的依赖。 +* 移除迭代器对 `std::iterator` 的继承(该基类在 C{plus}{plus}17 中已弃用),感谢 Daniela Engert的贡献(https://github.com/boostorg/unordered/pull/7[PR#7])。 +* 停止使用 `BOOST++_++DEDUCED++_++TYPENAME` 。 +* 更新部分 Boost 头文件包含路径。 +* 重命名部分内部方法和变量。 +* 多项测试改进。 +* 多项内部变更。 + +== 版本 1.66.0 + +* 更简化的移动构造实现。 +* 文档修正(https://github.com/boostorg/unordered/pull/6[GitHub #6])。 + +== 版本 1.65.0 + +* 向 `quick++_++erase` 和 `erase++_++return++_++void` 添加弃用属性。本次确认将在未来版本中移除这两个接口。 +* 局部标准符合性修正: + ** 为 `swap` 自由函数添加 `noexcept` 规范。 + ** 补充缺失的 `insert(P&&)` 方法。 + +== 版本 1.64.0 + +* 初步支持 C{plus}{plus}17 新成员函数: `unordered++_++map` 中的 `insert++_++or++_++assign` 和 `try++_++emplace` , +* 初步支持 `merge` 与 `extract` 操作。当前版本尚未实现 `unordered++_++map` 与 `unordered++_++multimap` 之间或 `unordered++_++set` 与 `unordered++_++multiset` 之间的节点转移功能,该特性预计将在下一版 Boost 中提供。 -== Release 1.42.0 +== 版本 1.63.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. +* 检查 `insert` 与 `emplace++_++hint` 操作中提示迭代器的有效性。 +* 修复部分警告(主要出现在测试中)。 +* 为参数数量较少的情况手动编写 `emplace++_++args` 代码,以减轻模板错误消息的负担。 +* 移除 emplace 参数中多余的 `boost::forward` 调用,以修复旧版 Visual C{plus}{plus} 中字面量字符串的就地构造问题。 +* 修复赋值操作中的异常安全问题。若桶分配过程抛出异常,可能导致哈希函数与相等性判断函数被覆盖,而现有元素仍保留在容器中。这将造成函数对象与容器元素不匹配,进而引发元素错置桶位及等价元素处理错误的问题。 +* 多项参考文档改进。 +* 增强的分配器支持(https://svn.boost.org/trac/boost/ticket/12459[#12459])。 +* 将无参构造函数改为隐式声明。 +* 实现缺失的分配器感知构造函数。 +* 修复空容器在设置哈希函数与键值相等性判断函数时存在的问题。 +* 从文档示例中移除 unary/binary++_++function。这两者在 C{plus}{plus}17 中已被移除。。 +* emplace 方法现支持 10 个构造参数。其设计本应支持最多 10 个参数,但由于预处理代码中存在差一错误,仅支持 9 个参数。 -== Release 1.41.0 - Major update +== 版本 1.62.0 -* 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. +* 停止使用已弃用的 `boost::iterator` 组件 。 +* 移除 `BOOST++_++NO++_++STD++_++DISTANCE` 的兼容性代码。 +* 移除 `BOOST++_++UNORDERED++_++DEPRECATED++_++EQUALITY` 警告。 +* 采用更简化的赋值操作实现,修复了 `unordered++_++multiset` 与 `unordered++_++multimap` 的异常安全问题,但性能可能略有下降。 +* 停止使用返回值SFINAE技术,以避免部分旧版本编译器的兼容性问题。 -* 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. +== 版本 1.58.0 -== Release 1.40.0 +* 移除常量迭代器中不必要的模板参数。 +* 重命名部分迭代器类中私有的 `iterator` 类型别名,以避免某些特征类产生混淆。 +* 修复当使用具有状态且设置了propagate++_++on++_++container++_++move++_++assign 的分配器时,移动赋值操作存在的缺陷(https://svn.boost.org/trac/boost/ticket/10777[#10777])。 +* 修复移动赋值操作中一处罕见的异常安全问题。 +* 修复计算待分配桶数量时可能出现的溢出问题(https://github.com/boostorg/unordered/pull/4[GitHub #4])。 -* {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. +== 版本 1.57.0 -== Release 1.39.0 +* 修复迭代器中 `pointer` 类型定义的问题(https://svn.boost.org/trac/boost/ticket/10672[#10672])。 +* 修复 Coverity 警告(https://github.com/boostorg/unordered/pull/2[GitHub #2])。 -* {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. +== 版本 1.56.0 -== Release 1.38.0 +* 修复部分变量遮蔽警告(https://svn.boost.org/trac/boost/ticket/9377[#9377])。 +* 修正文档中的分配器用法(https://svn.boost.org/trac/boost/ticket/9719[#9719])。 +* 对整数键始终采用质数桶数量。此修复解决了插入连续整数时的性能回归问题,但可能会降低其他使用场景的速度(https://svn.boost.org/trac/boost/ticket/9282[#9282])。 +* 严格遵循 C{plus}{plus}11 标准规定,仅使用分配器构造元素。 -* 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). +== 版本 1.55.0 -== Release 1.37.0 +* 避免部分警告(https://svn.boost.org/trac/boost/ticket/8851[#8851] 、 https://svn.boost.org/trac/boost/ticket/8874[#8874])。 +* 避免通过迭代器上的 ADL 暴露部分细节函数。 +* 遵循标准规范,仅使用分配器的 construct 和 destroy 方法来构造和析构存储的元素,不将其用于指针等内部数据的操作。 -* 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 `` and -``. -* Move all the implementation inside `boost/unordered`, to assist -modularization and hopefully make it easier to track Release subversion. +== 版本 1.54.0 -== Release 1.36.0 +* 为标准中指定的方法标注 `noexcept` 。更多方法将在下一版本中更新。 +* 若已知哈希函数与相等性谓词均具备无抛出移动赋值或移动构造特性,则使用它们。 -First official release. +== 版本 1.53.0 -* 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. +* 移除对旧式变参 pair 构造函数和相等性实现的支持,这两项功能自 Boost 1.48 起已被弃用。 +* 停止使用已弃用的配置宏。 +* 更多内部实现变更,包括采用更简化的 `erase` 方法 实现。 -== Boost 1.35.0 Add-on - 31st March 2008 +== 版本 1.52.0 -Unofficial release uploaded to vault, to be used with Boost 1.35.0. Incorporated many of the suggestions from the review. +* 加速赋值操作:尽可能复用现有节点进行赋值,而非创建全新节点并执行复制构造。 +* 修复 `erase++_++range` 方法中的缺陷(https://svn.boost.org/trac/boost/ticket/7471[#7471])。 +* 回退部分关于节点创建机制的内部变更(尤其针对 C{plus}{plus}11 编译器),使 'construct' 和 'destroy' 对 C{plus}{plus}11 分配器更有效。 +* 简化实现,以提高健壮性。 -* 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. +== 版本 1.51.0 + +* 修复当使用 C{plus}{plus}11 编译器搭配 C{plus}{plus}03 分配器时出现的构造/析构问题(https://svn.boost.org/trac/boost/ticket/7100[#7100])。 +* 移除一段 `try..catch` 代码块以支持无异常编译模式。 +* 调整 SFINAE 的实现方式以兼容 g{plus}{plus} 3.4(https://svn.boost.org/trac/boost/ticket/7175[#7175])。 +* 更新为使用新的配置宏。 + +== 版本 1.50.0 + +* 修复 `unordered++_++multiset` 与 `unordered++_++multimap` 的相等性判断逻辑。 +* https://svn.boost.org/trac/boost/ticket/6857[问题单 6857] :实现 `reserve` 。 +* https://svn.boost.org/trac/boost/ticket/6771[问题 6771] :规避 gcc 的 `-Wfloat-equal` 编译警告。 +* https://svn.boost.org/trac/boost/ticket/6784[问题单 6784] :修复部分 Sun 编译器专用代码。 +* https://svn.boost.org/trac/boost/ticket/6190[问题单 6190] :规避 gcc 的 `-Wshadow` 编译警告。 +* https://svn.boost.org/trac/boost/ticket/6905[问题单 6905] :使宏中的命名空间与 `bcp` 自定义命名空间兼容(由 Luke Elliott 修复)。 +* 移除部分较小的质数桶数量,因为这些数值可能显著增加冲突概率(例如,由于我们使用十进制,5的倍数出现频率很高)。 +* 对于旧版本 Visual C{plus}{plus},优先使用容器库自带的 `allocator++_++traits` 实现,因其兼容性更佳。 +* 64 位 std::size++_++t 机器上使用 2 的幂次桶数量,通过 Thomas Wang 哈希函数选择桶(因取模运算在 64 位值上极慢)。 +* 部分内部变更。 + +== 版本 1.49.0 + +* 修复因意外出现的异常赋值操作而产生的编译警告。 +* 轻微优化错误消息。 + +== 版本 1.48.0 - 重大更新 + +本本次为重大更新:容器已改用 Boost.Move 的移动操作模拟实现,并显著提升了对 C{plus}{plus}11 标准的符合性。详见 xref:compliance.adoc[标准合规性章节] 。 + +该容器现满足 C{plus}{plus}11 的复杂度要求,但为此会占用稍多内存。这意味着 `quick++_++erase` 与 `erase++_++return++_++void` 接口已不再必需,将在未来版本中移除。 + +C{plus}{plus}11 支持导致部分破坏性变更: + +* 相等性比较已改为遵循 C{plus}{plus}11 规范。在包含等价键的容器中,原先要求同一组等价键内的元素必须顺序一致才被视为相等,现在则允许它们互为排列。如需使用旧行为,请定义宏 `BOOST++_++UNORDERED++_++DEPRECATED++_++EQUALITY` 。 + +* 当两个待交换容器的分配器不相等时,swap 操作的行为发生变更。旧版本会通过相应的分配器分配新节点,现在则改为:若分配器包含 `propagate++_++on++_++container++_++swap` 成员结构体且其 `propagate++_++on++_++container++_++swap::value` 为 true,则会交换分配器本身。 + +* 现在当调用分配器的 `construct` 与 `destroy` 时,直接传入原始指针,而非分配器定义的 `pointer` 类型。 + +* `emplace` 方法原先模拟了早期 C{plus}{plus}0x 草案中的变参 pair 构造函数。由于该特性已被移除,现不再提供此模拟实现。当前仅模拟新的 `piecewise++_++construct` pair 构造函数,但需使用 `boost::piecewise++_++construct` 作为参数。若需启用旧版变参构造函数的模拟行为,请定义宏 `BOOST++_++UNORDERED++_++DEPRECATED++_++PAIR++_++CONSTRUCT` 。 + +== 版本 1.45.0 + +* 修复通过返回 `value++_++type` 副本的迭代器向 `unordered++_++map` 或 `unordered++_++set` 插入元素时出现的缺陷。 + +== 版本 1.43.0 + +* https://svn.boost.org/trac/boost/ticket/3966[问题单 3966] : `erase++_++return++_++void` 更名为 `quick++_++erase` (符合 http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#579[当前迭代器擦除缓慢的解决方案^])。旧方法名出于向后兼容性予以保留,但已被视为弃用接口,将在未来版本中移除。 +* 使用 Boost.Exception。 +* 停止使用已弃用的 `BOOST++_++HAS++_*++` 系列宏。 + +== 版本 1.42.0 + +* 支持使用不完整值类型来实例化容器。 +* 减少编译警告数量(主要出现在测试中)。 +* 提升 Codegear 兼容性。 +* https://svn.boost.org/trac/boost/ticket/3693[问题单 3693] :新增 `erase++_++return++_++void` 作为临时解决方案,以应对当前 `erase` 方法因需查找下一元素返回迭代器而可能产生的效率问题。 +* 新增针对兼容键的模板化 find 重载。 +* https://svn.boost.org/trac/boost/ticket/3773[问题单 3773] :为 `ptrdiff++_++t` 添加缺失的 `std` 限定符。 +* 调整代码格式,使大多数代码行不超过 80 字符。 + +== 版本 1.41.0 - 重大更新 + +* 初始版本曾大量使用宏来规避旧式编译器薄弱的模板支持能力。鉴于现已不再支持这些编译器,且宏的使用逐渐成为维护负担,现将实现类重构为使用模板替代宏。 + +* 通过 `boost::compressed++_++pair` 实现 EBO 及微调函数缓冲区(现使用 bool 替代成员指针),容器对象的内存占用得以减小。 + +* 桶采用延迟分配机制,这意味着构造空容器时不会分配任何内存。 + +== 版本 1.40.0 + +* https://svn.boost.org/trac/boost/ticket/2975[问题单 2975] :将质数列表存储为预处理序列,确保未来再次调整列表长度时能自动保持正确。 +* https://svn.boost.org/trac/boost/ticket/1978[问题单 1978] :为所有编译器实现 `emplace` 。 +* https://svn.boost.org/trac/boost/ticket/2908[问题单 2908] 、 https://svn.boost.org/trac/boost/ticket/3096[问题单 3096] :针对旧版 borland 的变通方案(包括为所有容器添加显式析构函数)。 +* https://svn.boost.org/trac/boost/ticket/3082[问题单 3082] :禁用 Visual C{plus}{plus} 编译器的错误警告。 +* 对 C{plus}{plus}0x 特性提供优化方案,以应对头文件不可用的情况。 +* 默认创建更少的桶。 + +== 版本 1.39.0 + +* https://svn.boost.org/trac/boost/ticket/2756[问题单 2756] :规避 Visual C{plus}{plus} 2009 的编译警告。 +* 对实现、测试及文档进行其他少量内部调整。 +* 避免 `operator++[]++` 中不必要的复制。 +* https://svn.boost.org/trac/boost/ticket/2975[问题单 2975] :修正质数列表长度。 + +== 版本 1.38.0 + +* 使用 link:../../../../core/swap.html[`boost::swap`] 。 +* https://svn.boost.org/trac/boost/ticket/2237[问题单 2237] :明确说明当两个对象的相等性判断谓词不等价时,其 == 与 != 运算符的行为是未定义的。感谢 Daniel Krügler 的贡献。 +* https://svn.boost.org/trac/boost/ticket/1710[问题单 1710] :采用更长的质数列表。感谢 Thorsten Ottosen 与 Hervé Brönnimann 的贡献。 +* 使用 link:../../../../type_traits/index.html[对齐存储] 来存储类型。这改变了利用分配器构造节点的方式:原先通过两次调用分配器的 `construct` 方法分别构造指针和值,现在仅通过单次调用构造节点,随后采用就地构造方式构建值对象。 +* 在可用时支持 C{plus}{plus}0x 初始化列表(当前仅 g{plus}{plus} 4.4 的 C{plus}{plus}0x 模式)。 + +== 版本 1.37.0 + +* 根据 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf[n2691^] 规范,将带提示的 `emplace` 重载更名为 `emplace++_++hint` 。 +* 在 `++<++boost/unordered/unordered++_++map++_++fwd.hpp++>++` 与 `++<++boost/unordered/unordered++_++set++_++fwd.hpp++>++` 路径下提供前向声明头文件。 +* 将所有实现移至 `boost/unordered` 内,以支持模块化并便于跟踪发布版本。 + +== 版本 1.36.0 + +首次正式发布。 + +* 调整内部结构。 +* 移动语义:在支持右值引用的环境中提供完整支持,否则使用精简版 Adobe 移动库进行模拟实现。 +* 支持右值引用和变参模板时提供就地构造支持。 +* 在支持右值引用与变参模板的环境中实现更高效的节点分配。 +* 新增相等性判断运算符。 + +== Boost 1.35.0 附加版本 - 2008年3月31日 + +非官方版本已上传至资源库,适用于 Boost 1.35.0。该版本已采纳评审阶段的多项改进建议。 + +* 通过 Boost 回归测试,代码可移植性得到显著提升。 +* 修正文档中的多处笔误,并优化文本表述以提升可读性。 +* 修复根据最大负载因子计算容器大小时,浮点数到 `std::size++_++t` 的转换问题,并在计算过程中使用 `double` 类型来提高精度。 +* 修正示例中的部分错误。 + +== 评审版本 + +初始评审版本(评审时间:2007年12月7日至12月16日)。 diff --git a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc index b895e29..7ee1d0b 100644 --- a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc @@ -1,23 +1,23 @@ [#compliance] -= Standard Compliance += 标准符合性 :idprefix: compliance_ :cpp: C++ -== Closed-addressing Containers +== 闭寻址容器 -`boost::unordered_[multi]set` and `boost::unordered_[multi]map` provide a conformant implementation for {cpp}11 (or later) compilers of the latest standard revision of {cpp} unordered associative containers, with very minor deviations as noted. The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. +`boost::unordered++_[++multi++]++set` 和 `boost::unordered++_[++multi++]++map` 为 C{plus}{plus}11(或更高版本)编译器提供了符合最新 C{plus}{plus} 标准修订版的无序关联容器实现,仅存在文档所述的极微小偏差。这些容器完全满足 https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[分配器感知] 要求,并支持 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 。 -=== Deduction Guides +=== 推导指引 -Deduction guides for https://en.cppreference.com/w/cpp/language/class_template_argument_deduction[class template argument deduction (CTAD)^] are only available on {cpp}17 (or later) compilers. +https://en.cppreference.com/w/cpp/language/class_template_argument_deduction[类模板参数推导 (CTAD)] 的推导指南仅在 C{plus}{plus}17(或更高版本)编译器中可用。 -=== Piecewise Pair Emplacement +=== 分段式 Pair 就地构造 -In accordance with the standard specification, `boost::unordered_[multi]map::emplace` supports piecewise pair construction: +根据标准规范, `boost::unordered++_[++multi++]++map::emplace` 支持 pair 的分段构造: -[source,c++] +[source, c++] ---- boost::unordered_multimap x; @@ -26,69 +26,74 @@ x.emplace( std::make_tuple("key"), std::make_tuple(1, 2)); ---- -Additionally, the same functionality is provided via non-standard `boost::unordered::piecewise_construct` and Boost.Tuple: +此外,通过非标准接口 `boost::unordered::piecewise++_++construct` 与 Boost.Tuple 提供相同功能: -[source,c++] +[source, c++] ---- x.emplace( boost::unordered::piecewise_construct, boost::make_tuple("key"), boost::make_tuple(1, 2)); ---- -This feature has been retained for backwards compatibility with previous versions of Boost.Unordered: users are encouraged to update their code to use `std::piecewise_construct` and ``std::tuple``s instead. +此特性为保持与 Boost.Unordered 旧版本的向后兼容性而保留:建议用户更新代码以使用 `std::piecewise++_++construct` 与 `std::tuple` 。 -=== Swap +=== 交换 -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 thrown from their copy constructor. +执行交换操作时,当前未通过调用 `swap` 函数来交换 `Pred` 和 `Hash` 对象,而是使用其复制构造函数。因此,在交换过程中可能会因其复制构造函数而抛出异常。 -== Open-addressing Containers +== 开放寻址容器 -The C++ standard does not currently provide any open-addressing container specification to adhere to, so `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` take inspiration from `std::unordered_set` and `std::unordered_map`, respectively, and depart from their interface where convenient or as dictated by their internal data structure, which is radically different from that imposed by the standard (closed addressing). +C{plus}{plus} 标准目前未规定任何开放寻址容器的实现规范,因此 `boost::unordered++_++flat++_++set` / `unordered++_++node++_++set` 与 `boost::unordered++_++flat++_++map` / `unordered++_++node++_++map` 分别借鉴 `std::unordered++_++set` 和 `std::unordered++_++map` 的设计,并在其内部数据结构(与标准规定的闭寻址方式截然不同)允许或需要时,对接口进行相应调整。 -Open-addressing containers provided by Boost.Unordered only work with reasonably compliant C++11 (or later) compilers. Language-level features such as move semantics and variadic template parameters are then not emulated. The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^]. +Boost.Unordered 提供的开放寻址容器仅兼容符合 C{plus}{plus}1(或更高版本)的编译器,且不再对移动语义、变参模板等语言特性进行模拟实现。这些容器完全符合 https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[分配器感知] 规范,并支持 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 。 -The main differences with C++ unordered associative containers are: +与 C{plus}{plus} 无序关联容器的主要区别在于: -* In general: -** `begin()` is not constant-time. ** `erase(iterator)` does not return an iterator to the following element, but a proxy object that converts to that iterator if requested; this avoids a potentially costly iterator increment operation when not needed. ** There is no API for bucket handling (except `bucket_count`). ** The maximum load factor of the container is managed internally and can't be set by the user. The maximum load, exposed through the public function `max_load`, may decrease on erasure under high-load conditions. -* `begin()` is not constant-time. ** `erase(iterator)` does not return an iterator to the following element, but a proxy object that converts to that iterator if requested; this avoids a potentially costly iterator increment operation when not needed. ** There is no API for bucket handling (except `bucket_count`). ** The maximum load factor of the container is managed internally and can't be set by the user. The maximum load, exposed through the public function `max_load`, may decrease on erasure under high-load conditions. -** `value_type` must be move-constructible. ** Pointer stability is not kept under rehashing. ** There is no API for node extraction/insertion. +* 总体特性: + ** `begin()` 不是常数时间复杂度操作。 + ** `erase(iterator)` 不返回指向下一元素的迭代器,而是返回一个代理对象,该对象可按需转换为目标迭代器;这可以避免在无需迭代器时可能产生的高昂递增操作开销。 + ** 未提供用于桶管理的 API(除 `bucket++_++count` 外)。 + ** 容器的最大负载因子由内部自动管理,用户无法手动设置。通过公开函数 `max++_++load` 获取的最大负载值,在高负载情况下执行删除操作时可能会降低。 +* 扁平容器( `boost::unordered++_++flat++_++set` 与 `boost::unordered++_++flat++_++map` ): + ** `value++_++type` 必须支持移动构造。 + ** 在重哈希的过程中,指针稳定性无法保持。 + ** 不提供节点提取/插入的 API 接口。 -== Concurrent Containers +== 并发容器 -There is currently no specification in the C++ standard for this or any other type of concurrent data structure. The APIs of `boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map` are modelled after `std::unordered_flat_set` and `std::unordered_flat_map`, respectively, with the crucial difference that iterators are not provided due to their inherent problems in concurrent scenarios (high contention, prone to deadlocking): so, Boost.Unordered concurrent containers are technically not models of https://en.cppreference.com/w/cpp/named_req/Container[Container^], although they meet all the requirements of https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^] containers (including https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointer^] support) except those implying iterators. +C{plus}{plus} 标准目前尚未针对此类或任何其他类型的并发数据结构制定规范。 `boost::concurrent++_++flat++_++set` / `boost::concurrent++_++node++_++set` 与 `boost::concurrent++_++flat++_++map` / `boost::concurrent++_++node++_++map` 的 API 分别基于 `std::unordered++_++flat++_++set` 和 `std::unordered++_++flat++_++map` 建模,其关键区别在于:由于迭代器在并发场景中存在固有缺陷(高竞争、易死锁),因此不提供迭代器。故 Boost.Unordered 并发容器技术上不符合 https://en.cppreference.com/w/cpp/named_req/Container[容器] 模型,但满足除涉及迭代器之外的所有 https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[分配器感知] 容器的要求(包括对 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的支持)。 -In a non-concurrent unordered container, iterators serve two main purposes: +在非并发无序容器中,迭代器主要有两项核心功能: -* Access to an element previously located via lookup. -* Container traversal. +* 访问先前通过查找定位的元素。 +* 容器遍历。 -In place of iterators, Boost.Unordered concurrent containers use _internal visitation_ facilities as a thread-safe substitute. Classical operations returning an iterator to an element already existing in the container, like for instance: +为替代迭代器,Boost.Unordered 并发容器使用__内部访问__机制作为线程安全的替代方案。传统操作会返回指向容器中既有元素的迭代器(例如下列): -[source,c++] +[source, c++] ---- iterator find(const key_type& k); std::pair insert(const value_type& obj); ---- -are transformed to accept a _visitation function_ that is passed such element: +被改造为接受传递该元素的__访问函数__: -[source,c++] +[source, c++] ---- template size_t visit(const key_type& k, F f); template bool insert_or_visit(const value_type& obj, F f); ---- -(In the second case `f` is only invoked if there's an equivalent element to `obj` in the table, not if insertion is successful). Container traversal is served by: +(第二种情况中,仅当表中存在与 `obj` 等价元素时才会调用 `f` ,而非在插入成功时调用)。容器遍历通过以下方式实现: -[source,c++] +[source, c++] ---- template size_t visit_all(F f); ---- -of which there are parallelized versions in C++17 compilers with parallel algorithm support. In general, the interface of concurrent containers is derived from that of their non-concurrent counterparts by a fairly straightforward process of replacing iterators with visitation where applicable. If for regular maps `iterator` and `const_iterator` provide mutable and const access to elements, respectively, here visitation is granted mutable or const access depending on the constness of the member function used (there are also `*cvisit` overloads for explicit const visitation); In the case of `boost::concurrent_flat_set`, visitation is always const. +在支持并行算法的 C{plus}{plus}17 编译器中提供并行化版本。通常,并发容器的接口通过将迭代器替换为访问机制的过程从非并发版本派生。对于常规映射, `iterator` 和 `const++_++iterator` 分别提供对元素的非常量和常量访问;此处访问权限取决于所用成员函数的常量性(同时提供 `++*++cvisit` 重载用于显式常量访问)。对于 `boost::concurrent++_++flat++_++set` ,访问操作始终为常量。 -One notable operation not provided by `boost::concurrent_flat_map`/`boost::concurrent_node_map` is `operator[]`/`at`, which can be replaced, if in a more convoluted manner, by `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_visit]`. +`boost::concurrent++_++flat++_++map` / `boost::concurrent++_++node++_++map` 未提供的一个关键操作是 `operator++[]++` / `at` ,该功能可通过 xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_try_emplace_or_cvisit[`try++_++emplace++_++or++_++visit`] 实现替代(该方式更为复杂)。 //- diff --git a/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc index 4e2a132..7fa6404 100644 --- a/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc @@ -1,24 +1,25 @@ -[#concurrent] = Concurrent Containers +[#concurrent] += 并发容器 :idprefix: concurrent_ -Boost.Unordered provides `boost::concurrent_node_set`, `boost::concurrent_node_map`, `boost::concurrent_flat_set` and `boost::concurrent_flat_map`, hash tables that allow concurrent write/read access from different threads without having to implement any synchronzation mechanism on the user's side. +Boost.Unordered 提供 `boost::concurrent++_++node++_++set` 、 `boost::concurrent++_++node++_++map` 、 `boost::concurrent++_++flat++_++set` 和 `boost::concurrent++_++flat++_++map` ,这些哈希表允许不同线程进行并发读写访问,无需用户实现任何同步机制。 -[source,c++] +[source, c++] ---- std::vector input; boost::concurrent_flat_map m; ... -// process input in parallel +// 并行处理输入 const int num_threads = 8; std::vector threads; std::size_t chunk = input.size() / num_threads; // how many elements per thread for (int i = 0; i < num_threads; ++i) { threads.emplace_back([&,i] { - // calculate the portion of input this thread takes care of + // 计算当前线程处理的输入范围 std::size_t start = i * chunk; std::size_t end = (i == num_threads - 1)? input.size(): (i + 1) * chunk; @@ -29,13 +30,13 @@ for (int i = 0; i < num_threads; ++i) { } ---- -In the example above, threads access `m` without synchronization, just as we'd do in a single-threaded scenario. In an ideal setting, if a given workload is distributed among _N_ threads, execution is _N_ times faster than with one thread —this limit is never attained in practice due to synchronization overheads and _contention_ (one thread waiting for another to leave a locked portion of the map), but Boost.Unordered concurrent containers are designed to perform with very little overhead and typically achieve _linear scaling_ (that is, performance is proportional to the number of threads up to the number of logical cores in the CPU). +在上例中,线程无需同步即可访问 `m` ,这与单线程场景中的操作方式一致。在理想情况下,若将给定工作负载分配给 _N_ 个线程,其执行速度相较单线程提升 _N_ 倍——由于同步开销与__争用__的存在(某线程等待其他线程离开容器的锁定区域),实践中无法达到此理论极限。但 Boost.Unordered 并发容器设计为以极低开销运行,通常可实现__线性扩展__(即性能提升与线程数量成正比,直至达到 CPU 的逻辑核心数)。 -== Visitation-based API +== 基于访问的 API -The first thing a new user of Boost.Unordered concurrent containers will notice is that these classes _do not provide iterators_ (which makes them technically not https://en.cppreference.com/w/cpp/named_req/Container[Containers^] in the C++ standard sense). The reason for this is that iterators are inherently thread-unsafe. Consider this hypothetical code: +Boost.Unordered 并发容器的新用户首先会注意到:这些类__不提供迭代器__(它们在技术层面上不符合 C{plus}{plus} 标准中的 https://en.cppreference.com/w/cpp/named_req/Container[容器] 定义)。因为迭代器本质上是线程不安全的。请参考以下假设代码: -[source,c++] +[source, c++] ---- auto it = m.find(k); // A: get an iterator pointing to the element with key k if (it != m.end() ) { @@ -43,29 +44,29 @@ if (it != m.end() ) { } ---- -In a multithreaded scenario, the iterator `it` may be invalid at point B if some other thread issues an `m.erase(k)` operation between A and B. There are designs that can remedy this by making iterators lock the element they point to, but this approach lends itself to high contention and can easily produce deadlocks in a program. `operator[]` has similar concurrency issues, and is not provided by `boost::concurrent_flat_map`/`boost::concurrent_node_map` either. Instead, element access is done through so-called _visitation functions_: +多线程场景中,若其他线程在 A 和 B 之间执行 `m.erase(k)` 操作,迭代器 `it` 可能在 B 点失效。虽然存在通过锁定指向元素来修复此问题的设计方案,但这种方法容易引发高竞争并可能导致程序死锁。 `operator++[]++` 也存在类似并发问题,因此 `boost::concurrent++_++flat++_++map` / `boost::concurrent++_++node++_++map` 也未提供该操作。替代方案是通过__访问函数__操作元素: -[source,c++] +[source, c++] ---- m.visit(k, [](const auto& x) { // x is the element with key k (if it exists) some_function(x); // use it }); ---- -The visitation function passed by the user (in this case, a lambda function) is executed internally by Boost.Unordered in a thread-safe manner, so it can access the element without worrying about other threads interfering in the process. +用户传递的访问函数(此处为 lambda 函数)由 Boost.Unordered 在内部以线程安全的方式执行,因此该函数可以安全访问目标元素,无需担心其他线程在此过程中造成干扰。 -On the other hand, a visitation function can _not_ access the container itself: +另一方面,访问函数__无法__访问容器本身: -[source,c++] +[source, c++] ---- m.visit(k, [&](const auto& x) { some_function(x, m.size()); // forbidden: m can't be accessed inside visitation }); ---- -Access to a different container is allowed, though: +但允许访问其他容器: -[source,c++] +[source, c++] ---- m.visit(k, [&](const auto& x) { if (some_function(x)) { @@ -74,9 +75,9 @@ m.visit(k, [&](const auto& x) { }); ---- -But, in general, visitation functions should be as lightweight as possible to reduce contention and increase parallelization. In some cases, moving heavy work outside of visitation may be beneficial: +但通常而言,访问函数应尽可能轻量以减少争用并提升并行性。在某些情况下,将繁重操作移出访问函数可能更优: -[source,c++] +[source, c++] ---- std::optional o; bool found = m.visit(k, [&](const auto& x) { @@ -87,22 +88,22 @@ if (found) { } ---- -Visitation is prominent in the API provided by concurrent containers, and many classical operations have visitation-enabled variations: +访问机制在并发容器 API 中占据核心地位,许多经典操作都提供了支持访问机制的变体: -[source,c++] +[source, c++] ---- m.insert_or_visit(x, [](auto& y) { - // if insertion failed because of an equivalent element y, - // do something with it, for instance: + // 若因存在等价元素 y 导致插入失败 + // 可对其进行操作,例如: ++y.second; // increment the mapped part of the element }); ---- -Note that in this last example the visitation function could actually _modify_ the element: as a general rule, operations on a concurrent map `m` will grant visitation functions const/non-const access to the element depending on whether `m` is const/non-const. Const access can be always be explicitly requested by using `cvisit` overloads (for instance, `insert_or_cvisit`) and may result in higher parallelization. For concurrent sets, on the other hand, visitation is always const access. +注意此例中访问函数可__修改__元素:作为通用规则,对并发映射 `m` 的操作将根据 `m` 是否为常量类型,授予访问函数对元素的常量/非常量访问权限。 通过使用 `cvisit` 重载(如 `insert++_++or++_++cvisit` )可始终显式请求常量访问,这可能提升并行性。而并发集合的访问始终为常量访问。 -Although expected to be used much less frequently, concurrent containers also provide insertion operations where an element can be visited right after element creation (in addition to the usual visitation when an equivalent element already exists): +尽管预期使用频率较低,并发容器还提供在元素创建后立即进行访问的插入操作(除在已存在等价元素时执行常规访问之外): -[source,c++] +[source, c++] ---- m.insert_and_cvisit(x, [](const auto& y) { @@ -113,33 +114,33 @@ Although expected to be used much less frequently, concurrent containers also pr }); ---- -Consult the references of `xref:reference/concurrent_node_set.adoc#concurrent_node_set[boost::concurrent_node_set]`, `xref:reference/concurrent_node_map.adoc#concurrent_node_map[boost::concurrent_node_map]`, `xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[boost::concurrent_flat_set]` and `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[boost::concurrent_flat_map]` for the complete list of visitation-enabled operations. +支持访问功能的完整操作列表请参阅 xref:reference/concurrent_node_set.adoc#concurrent_node_set[`boost::concurrent++_++node++_++set`] 、 xref:reference/concurrent_node_map.adoc#concurrent_node_map[`boost::concurrent++_++node++_++map`] 、 xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[`boost::concurrent++_++flat++_++set`] 和 xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[`boost::concurrent++_++flat++_++map`] 的参考文档。 -== Whole-Table Visitation +== 全表访问 -In the absence of iterators, `visit_all` is provided as an alternative way to process all the elements in the container: +在缺乏迭代器的情况下, `visit++_++all` 提供处理容器内全部元素的替代方案: -[source,c++] +[source, c++] ---- m.visit_all([](auto& x) { x.second = 0; // reset the mapped part of the element }); ---- -In C++17 compilers implementing standard parallel algorithms, whole-table visitation can be parallelized: +在支持标准并行算法的 C{plus}{plus}17 编译器中,全表遍历访问可进行并行化处理: -[source,c++] +[source, c++] ---- m.visit_all(std::execution::par, [](auto& x) { // run in parallel x.second = 0; // reset the mapped part of the element }); ---- -Traversal can be interrupted midway: +遍历过程可中途中断: -[source,c++] +[source, c++] ---- -// finds the key to a given (unique) value +// 查找给定(唯一)值对应的键 int key = 0; int value = ...; @@ -156,22 +157,22 @@ bool found = !m.visit_while([&](const auto& x) { if(found) { ... } ---- -There is one last whole-table visitation operation, `erase_if`: +最后一项全表访问操作是 `erase++_++if` : -[source,c++] +[source, c++] ---- m.erase_if([](auto& x) { return x.second == 0; // erase the elements whose mapped value is zero }); ---- -`visit_while` and `erase_if` can also be parallelized. Note that, in order to increase efficiency, whole-table visitation operations do not block the table during execution: this implies that elements may be inserted, modified or erased by other threads during visitation. It is advisable not to assume too much about the exact global state of a concurrent container at any point in your program. +`visit++_++while` 与 `erase++_++if` 同样支持并行化。需要注意的是,为提升执行效率,全表遍历操作在运行期间不会锁定整个容器:这意味着在遍历过程中,其他线程可能同时执行元素的插入、修改或删除操作。建议在程序中避免对并发容器在任意时间点的全局状态做过强的假设。 -== Bulk visitation +== 批量访问 -Suppose you have an `std::array` of keys you want to look up for in a concurrent map: +假设有一个 `std::array` 存储了需要在并发映射中查找的键: -[source,c++] +[source, c++] ---- std::array keys; ... @@ -180,16 +181,16 @@ for(const auto& key: keys) { } ---- -_Bulk visitation_ allows us to pass all the keys in one operation: +__批量访问__允许用户通过单次操作传入所有键: -[source,c++] +[source, c++] ---- m.visit(keys.begin(), keys.end(), [](auto& x) { ++x.second; }); ---- -This functionality is not provided for mere syntactic convenience, though: by processing all the keys at once, some internal optimizations can be applied that increase performance over the regular, one-at-a-time case (consult the xref:benchmarks.adoc#benchmarks_boostconcurrent_flatnode_map[benchmarks]). In fact, it may be beneficial to buffer incoming keys so that they can be bulk visited in chunks: +提供此功能并非仅出于语法便利性考量:通过一次性处理所有键,可应用内部优化提升性能(详见 xref:benchmarks.adoc#benchmarks_boostconcurrent_flatnode_map[基准测试])。实际上,用户可通过缓冲输入键值以实现分块批量访问,从而进一步提升效率: -[source,c++] +[source, c++] ---- static constexpr auto bulk_visit_size = boost::concurrent_flat_map::bulk_visit_size; std::array buffer; @@ -203,42 +204,46 @@ while(...) { // processing loop } ... } -// flush remaining keys +// 处理剩余键 map.visit(buffer.begin(), buffer.begin() + i, [](auto& x) { ++x.second; }); ---- -There's a latency/throughput tradeoff here: it will take longer for incoming keys to be processed (since they are buffered), but the number of processed keys per second is higher. `bulk_visit_size` is the recommended chunk size —smaller buffers may yield worse performance. +这里存在延迟与吞吐量的权衡:缓冲机制会延长单个键的处理延迟,但每秒处理的键总数(吞吐量)会更高。 `bulk++_++visit++_++size` 是推荐的缓冲区块大小——过小的缓冲区可能导致性能下降。 -== Blocking Operations +== 阻塞式操作 -Concurrent containers can be copied, assigned, cleared and merged just like any other Boost.Unordered container. Unlike most other operations, these are _blocking_, that is, all other threads are prevented from accesing the tables involved while a copy, assignment, clear or merge operation is in progress. Blocking is taken care of automatically by the library and the user need not take any special precaution, but overall performance may be affected. +并发容器可像其他 Boost.Unordered 容器一样支持复制、赋值、清空和合并操作。与大多数其他操作不同,这些属于__阻塞式操作__:在执行期间,其他线程将被阻止访问相关容器。该阻塞机制由库自动处理,用户无需采取特殊预防措施,但整体性能可能受到影响。 -Another blocking operation is _rehashing_, which happens explicitly via `rehash`/`reserve` or during insertion when the table's load hits `max_load()`. As with non-concurrent containers, reserving space in advance of bulk insertions will generally speed up the process. +另一阻塞操作是__重哈希__,该操作可通过 `rehash` / `reserve` 显式触发,或在插入过程中当容器负载达到 `max++_++load()` 时自动执行。与非并发容器类似,在批量插入前预先分配空间通常能加速处理过程。 -== Interoperability with non-concurrent containers +== 与非并发容器的互操作性 -As open-addressing and concurrent containers are based on the same internal data structure, they can be efficiently move-constructed from their non-concurrent counterpart, and vice versa. +由于开放寻址容器与并发容器基于相同的内部数据结构,它们可以高效地通过移动构造从其非并发对应容器转换而来,反之亦然。 -[caption=, title='Table {counter:table-counter}. Concurrent/non-concurrent interoperatibility'] -[cols="1,1", frame=all, grid=all] +[caption=",", title='Table {counter:table-counter}. Concurrent/non-concurrent interoperatibility'] +[cols="1,1", frame=all,, grid=all] |=== -^|`boost::concurrent_node_set` ^|`boost::unordered_node_set` +^|`boost::concurrent++_++node++_++set` +^|`boost::unordered++_++node++_++set` -^|`boost::concurrent_node_map` ^|`boost::unordered_node_map` +^|`boost::concurrent++_++node++_++map` +^|`boost::unordered++_++node++_++map` -^|`boost::concurrent_flat_set` ^|`boost::unordered_flat_set` +^|`boost::concurrent++_++flat++_++set` +^|`boost::unordered++_++flat++_++set` -^|`boost::concurrent_flat_map` ^|`boost::unordered_flat_map` +^|`boost::concurrent++_++flat++_++map` +^|`boost::unordered++_++flat++_++map` |=== -This interoperability comes handy in multistage scenarios where parts of the data processing happen in parallel whereas other steps are non-concurrent (or non-modifying). In the following example, we want to construct a histogram from a huge input vector of words: the population phase can be done in parallel with `boost::concurrent_flat_map` and results then transferred to the final container. +此互操作性适用于多阶段场景:部分数据处理环节需要并行执行,而其他步骤采用非并发(或只读)模式。下例中,我们需要从一个庞大的单词输入向量构建词频统计直方图:填充阶段用 `boost::concurrent++_++flat++_++map` 并行执行,随后将结果转移至最终容器。 -[source,c++] +[source, c++] ---- std::vector words = ...; -// Insert words in parallel +// 并行插入单词 boost::concurrent_flat_map m0; std::for_each( std::execution::par, words.begin(), words.end(), @@ -246,6 +251,6 @@ std::for_each( m0.try_emplace_or_visit(word, 1, [](auto& x) { ++x.second; }); }); -// Transfer to a regular unordered_flat_map +// 转入常规 unordered_flat_map boost::unordered_flat_map m=std::move(m0); ---- diff --git a/doc/modules/ROOT/pages/copyright_zh_Hans.adoc b/doc/modules/ROOT/pages/copyright_zh_Hans.adoc index 43a906a..527cc80 100644 --- a/doc/modules/ROOT/pages/copyright_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/copyright_zh_Hans.adoc @@ -1,20 +1,20 @@ [#copyright] -= Copyright and License += 版权与许可协议 :idprefix: copyright_ -*Daniel James* +*丹尼尔·詹姆斯 (Daniel James)* -Copyright (C) 2003, 2004 Jeremy B. Maitin-Shepard +版权所有 © 2003, 2004 杰里米·B·梅廷-谢泼德 (Jeremy B. Maitin-Shepard) -Copyright (C) 2005-2008 Daniel James +版权所有 © 2005-2008 丹尼尔·詹姆斯(Daniel James) -Copyright (C) 2022-2025 Christian Mazakas +版权所有 © 2022-2025 克里斯蒂安·马扎卡斯 (Christian Mazakas) -Copyright (C) 2022-2025 Joaquín M López Muñoz +版权所有 © 2022-2025 华金·M·洛佩斯·穆尼奥斯(Joaquín M López Muñoz) -Copyright (C) 2022-2023 Peter Dimov +版权所有 © 2022-2023 彼得·迪莫夫 (Peter Dimov) -Copyright (C) 2024 Braden Ganetsky +版权所有 © 2024 布雷登·加涅茨基 (Braden Ganetsky) -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) +根据Boost软件许可证1.0版分发。(详见随附文件 LICENSE++_++1++_++0.txt 或访问 http://www.boost.org/LICENSE_1_0.txt 。) diff --git a/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc index e02366a..7fba285 100644 --- a/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc @@ -1,64 +1,89 @@ [#debuggability] :idprefix: debuggability_ -= Debuggability += 可调试性 == Visual Studio Natvis -All containers and iterators have custom visualizations in the Natvis framework. +所有容器和迭代器在 Natvis 框架中均具备自定义可视化功能。 -=== Using in your project +=== 在项目中使用 -To visualize Boost.Unordered containers in the Natvis framework in your project, simply add the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost_unordered.natvis] to your Visual Studio project as an "Existing Item". +若要在项目中通过 Natvis 框架实现 Boost.Unordered 容器的可视化调试,只需将文件 link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost++_++unordered.natvis] 作为"现有项"添加到 Visual Studio 项目中即可。 -=== Visualization structure +=== 可视化结构 -The visualizations mirror those for the standard unordered containers. A container has a maximum of 100 elements displayed at once. Each set element has its item name listed as `[i]`, where `i` is the index in the display, starting at `0`. Each map element has its item name listed as `[\{key-display}]` by default. For example, if the first element is the pair `("abc", 1)`, the item name will be `["abc"]`. This behaviour can be overridden by using the view "ShowElementsByIndex", which switches the map display behaviour to name the elements by index. This same view name is used in the standard unordered containers. +可视化方案与标准无序容器保持一致。容器单次最多显示 100 个元素。集合类容器中每个元素的项名称显示为 `++[++i++]++` (其中 `i` 为从 `0` 开始的显示索引)。映射元素默认显示为 `++[{++ 键值显示}++]++` ,例如当首元素为键值对 `("abc", 1)` 时,其项名称将显示为 `++[++"abc"++]++` 。用户可通过启用"ShowElementsByIndex"视图模式切换为按索引命名元素,此视图命名规则与标准无序容器保持一致。 -By default, the closed-addressing containers will show the `[hash_function]` and `[key_eq]`, the `[spare_hash_function]` and `[spare_key_eq]` if applicable, the `[allocator]`, and the elements. Using the view "detailed" adds the `[bucket_count]` and `[max_load_factor]`. Conversely, using the view "simple" shows only the elements, with no other items present. +默认情况下,封闭寻址容器将显示 `++[++hash++_++function++]++` 、 `++[++key++_++eq++]++` 、适用的 `++[++spare++_++hash++_++function++]++` 与 `++[++spare++_++key++_++eq++]++` 、 `++[++allocator++]++` 以及元素列表。若启用"detailed"视图将额外显示 `++[++bucket++_++count++]++` 和 `++[++max++_++load++_++factor++]++` 信息;若启用"simple"视图,则仅显示元素列表而不包含其他条目。 -By default, the open-addressing containers will show the `[hash_function]`, `[key_eq]`, `[allocator]`, and the elements. Using the view "simple" shows only the elements, with no other items present. Both the SIMD and the non-SIMD implementations are viewable through the Natvis framework. +默认情况下,开放寻址容器显示 `++[++hash++_++function++]++` 、 `++[++key++_++eq++]++` 、 `++[++allocator++]++` 以及元素列表。若启用 "simple" 视图,则仅显示元素列表而不包含其他条目。无论采用 SIMD 还是非 SIMD 实现,均可通过 Natvis 框架进行可视化调试。 -Iterators are displayed similarly to their standard counterparts. An iterator is displayed as though it were the element that it points to. An end iterator is simply displayed as `{ end iterator }`. +迭代器显示方式与标准迭代器类似:指向元素的迭代器显示为元素值;结束迭代器显示为 `++{++ 结束迭代器 }` 。 -=== Fancy pointers +=== 花式指针 -The container visualizations also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has natvis customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost_unordered.natvis]. +分配器中使用花式指针(如 `boost::interprocess::offset++_++ptr` )时,容器可视化功能仍可正常运作。Boost.Unordered 通过 Natvis 定制点支持所有类型的花式指针。 `boost::interprocess::offset++_++ptr` 已在 Boost.Interprocess 库中预定义支持,自定义类型支持方法请参阅文件 link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered.natvis[/extra/boost++_++unordered.natvis] 末尾注释。 -== GDB Pretty-Printers +== GDB 美化打印器 -All containers and iterators have a custom GDB pretty-printer. +所有容器和迭代器均配备自定义 GDB 美化打印器。 -=== Using in your project +=== 在项目中使用 -Always, when using pretty-printers, you must enable pretty-printing like below. This is typically a one-time setup. +使用美化打印器时,必须始终按以下方式启用美化打印功能。此项配置通常只需执行一次。 -```plaintext (gdb) set print pretty on ``` +```plaintext -By default, if you compile into an ELF binary format, your binary will contain the Boost.Unordered pretty-printers. To use the embedded pretty-printers, ensure you allow auto-loading like below. This must be done every time you load GDB, or add it to a ".gdbinit" file. +(gdb) set print pretty on -```plaintext (gdb) add-auto-load-safe-path [/path/to/executable] ``` +``` -You can choose to compile your binary _without_ embedding the pretty-printers by defining `BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS`, which disables the embedded GDB pretty-printers for all Boost libraries that have this feature. +默认情况下,若编译目标为 ELF 二进制格式,生成的文件将内置 Boost.Unordered 美化打印器。要使用内嵌的美化打印器,请确保按以下方式启用自动加载功能(此操作需在每次启动 GDB 时执行,或将其添加到 ".gdbinit" 配置文件中)。 -You can load the pretty-printers externally from the non-embedded Python script. Add the script, link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py], using the `source` command as shown below. +```plaintext -```plaintext (gdb) source [/path/to/boost]/libs/unordered/extra/boost_unordered_printers.py ``` +(gdb) add-auto-load-safe-path [/path/to/executable] -=== Visualization structure +``` -The visualizations mirror the standard unordered containers. The map containers display an association from key to mapped value. The set containers display an association from index to value. An iterator is either displayed with its item, or as an end iterator. Here is what may be shown for an example `boost::unordered_map`, an example `boost::unordered_set`, and their respective begin and end iterators. +用户可通过定义 `BOOST++_++ALL++_++NO++_++EMBEDDED++_++GDB++_++SCRIPTS` 宏,来选择在编译二进制文件时__不__嵌入美化打印器。该宏将禁用所有具备此功能的 Boost 库中内嵌的 GDB 美化打印器。 -```plaintext (gdb) print example_unordered_map $1 = boost::unordered_map with 3 elements = {["C"] = "c", ["B"] = "b", ["A"] = "a"} (gdb) print example_unordered_map_begin $2 = iterator = { {first = "C", second = "c"} } (gdb) print example_unordered_map_end $3 = iterator = { end iterator } (gdb) print example_unordered_set $4 = boost::unordered_set with 3 elements = {[0] = "c", [1] = "b", [2] = "a"} (gdb) print example_unordered_set_begin $5 = iterator = { "c" } (gdb) print example_unordered_set_end $6 = iterator = { end iterator } ``` +用户可通过外部非嵌入的 Python 脚本加载美化打印器:使用 `source` 命令添加 link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost++_++unordered++_++printers.py] 脚本即可。 -The other containers are identical other than replacing "`boost::unordered_{map|set}`" with the appropriate template name when displaying the container itself. Note that each sub-element (i.e. the key, the mapped value, or the value) is displayed based on its own printing settings which may include its own pretty-printer. +```plaintext -Both the SIMD and the non-SIMD implementations are viewable through the GDB pretty-printers. +(gdb) source [/path/to/boost]/libs/unordered/extra/boost_unordered_printers.py -For open-addressing containers where xref:hash_quality.adoc#hash_quality_container_statistics[container statistics] are enabled, you can obtain these statistics by calling `get_stats()` on the container, from within GDB. This is overridden in GDB as an link:https://sourceware.org/gdb/current/onlinedocs/gdb.html/Xmethod-API.html[xmethod], so it will not invoke any C++ synchronization code. See the following printout as an example for the expected format. +``` -```plaintext (gdb) print example_flat_map.get_stats() $1 = [stats] = {[insertion] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}}, [successful_lookup] = {[count] = 0, [probe_length] = {avg = 0.0, var = 0.0, dev = 0.0}, [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}, [unsuccessful_lookup] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}, [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}} ``` +=== 可视化结构 -=== Fancy pointers +可视化方案与标准无序容器保持一致:映射容器显示键到映射值的关联;集合容器显示从索引到值的关联关系。迭代器可显示为指向的元素内容,或标记为结束迭代器。下图展示了示例 `boost::unordered++_++map` 、示例 `boost::unordered++_++set` 及其迭代器. -The pretty-printers also work if you are using fancy pointers in your allocator, such as `boost::interprocess::offset_ptr`. While this is rare, Boost.Unordered has GDB pretty-printer customization points to support any type of fancy pointer. `boost::interprocess::offset_ptr` has support already defined in the Boost.Interprocess library, and you can add support to your own type by following the instructions contained in a comment near the end of the file link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost_unordered_printers.py]. +```plaintext + +(gdb) print example_unordered_map $1 = boost::unordered_map with 3 elements = {["C"] = "c", ["B"] = "b", ["A"] = "a"} (gdb) print example_unordered_map_begin $2 = iterator = { {first = "C", second = "c"} } (gdb) print example_unordered_map_end $3 = iterator = { end iterator } (gdb) print example_unordered_set $4 = boost::unordered_set with 3 elements = {[0] = "c", [1] = "b", [2] = "a"} (gdb) print example_unordered_set_begin $5 = iterator = { "c" } (gdb) print example_unordered_set_end $6 = iterator = { end iterator } + +``` + +其余容器的显示逻辑完全一致,仅在显示容器本身时将其模板名称替换为对应的 "boost::unordered++_{++map++|++set}"。需要注意的事,每个子元素(即键、映射值或值)的显示均取决于其自身的打印设置,这可能包含其专属的美化打印器。 + +无论采用 SIMD 还是非 SIMD 实现,均可通过 GDB 美化打印器查看。 + +对于启用 xref:hash_quality.adoc#hash_quality_container_statistics[容器统计] 的开放寻址容器,可在 GDB 中调用 `get++_++stats()` 方法来获取统计信息。该方法在GDB中被重写为 link:https://sourceware.org/gdb/current/onlinedocs/gdb.html/Xmethod-API.html[xmethod] 实现,因此不会执行任何C{plus}{plus}同步代码。输出格式示例如下. + +```plaintext + +(gdb) print example_flat_map.get_stats() +$1 = [stats] = {[insertion] = {[count] = 5, [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}}, + [successful_lookup] = {[count] = 0, [probe_length] = {avg = 0.0, var = 0.0, dev = 0.0}, + [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}, [unsuccessful_lookup] = {[count] = 5, + [probe_length] = {avg = 1.0, var = 0.0, dev = 0.0}, + [num_comparisons] = {avg = 0.0, var = 0.0, dev = 0.0}}} + +``` + +=== 花式指针 + +当用户在分配器中使用花式指针(例如 `boost::interprocess::offset++_++ptr` )时,GDB 的美化打印器仍可正常工作。虽然这种情况不常见,但 Boost.Unordered 为美化打印器提供了定制点,以支持任何类型的花式指针。 `boost::interprocess::offset++_++ptr` 的支持已在Boost.Interprocess库中预先定义,自定义类型支持方法请参阅文件 link:https://github.com/boostorg/unordered/blob/develop/extra/boost_unordered_printers.py[/extra/boost++_++unordered++_++printers.py] 的末尾注释。 diff --git a/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc index 4835af9..6ce012d 100644 --- a/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc @@ -2,69 +2,144 @@ :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, `xref:reference/unordered_map.adoc[boost::unordered_map]` is declared as: +关联容器使用排序关系来规定元素的存储方式,而无序关联容器则依赖相等性谓词与哈希函数。例如, xref:reference/unordered_map.adoc[`boost::unordered++_++map`] 的声明如下: -```cpp template < class Key, class Mapped, class Hash = boost::hash, class Pred = std::equal_to, class Alloc = std::allocator > > class unordered_map; ``` +```cpp -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 https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a hash^] you could write: +template < + class Key, class Mapped, + class Hash = boost::hash, + class Pred = std::equal_to, + class Alloc = std::allocator > > +class unordered_map; -```cpp boost::unordered_map dictionary; ``` +``` -There is an link:../../../examples/fnv1.hpp[implementation of FNV-1a^] in the examples directory. +哈希函数之所以排在首位,是因为用户可能希望更改哈希函数而不改变相等性谓词。例如,若要使用 https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a哈希] ,可以这样编写: -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: +```cpp -```cpp struct iequal_to { bool operator()(std::string const& x, std::string const& y) const { return boost::algorithm::iequals(x, y, std::locale()); } }; +boost::unordered_map + dictionary; -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)); } +示例目录中提供了 link:../../../examples/fnv1.hpp[FNV-1a的实现] 。 -return seed; } }; ``` +若需使用不同的相等性函数,则必须配套使用对应的哈希函数。例如,要实现不区分大小写的字典,就需要定义不区分大小写的相等性函数和配套的哈希函数: -Which you can then use in a case insensitive dictionary: ```cpp boost::unordered_map idictionary; ``` +```cpp -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. +struct iequal_to +{ + bool operator()(std::string const& x, + std::string const& y) const + { + return boost::algorithm::iequals(x, y, std::locale()); + } +}; -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. +struct ihash +{ + std::size_t operator()(std::string const& x) const + { + std::size_t seed = 0; + std::locale locale; -== Custom Types + for(std::string::const_iterator it = x.begin(); + it != x.end(); ++it) + { + boost::hash_combine(seed, std::toupper(*it, locale)); + } -Similarly, a custom hash function can be used for custom types: + return seed; + } +}; -```cpp struct point { int x; int y; }; +``` -bool operator==(point const& p1, point const& p2) { return p1.x == p2.x && p1.y == p2.y; } +随后可在不区分大小写的字典中使用它: +```cpp -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_map + idictionary; -boost::unordered_multiset 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: +这是位于 link:../../../examples/case_insensitive.hpp[/libs/unordered/examples/case++_++insensitive.hpp] 示例的简化版本,该版本支持其他区域设置和字符串类型。 -```cpp struct point { int x; int y; }; +CAUTION: 注意: 使用相等运算符( `==` )配合自定义相等性函数时需特别注意,尤其是在使用函数指针的情况下。若比较两个使用不同相等性函数的容器,将导致未定义行为。对于大多数无状态的函数对象而言,不可能发生这种结果——因为只有当两个容器使用相同的相等性函数时才能进行比较,此时可确保相等性函数是一致的。但若使用函数指针或带状态的相等性函数(例如 `boost::function` ),则可能引发问题。 -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; } +类似地,自定义类型也可使用自定义哈希函数: + +```cpp + +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 points; + +``` + +鉴于 link:../../../../container_hash/index.html[Boost.Hash] 是默认的哈希函数,我们只需让自定义类型兼容 Boost.Hash,即可免于显式指定哈希函数。 + +```cpp + +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 points; ``` +boost::unordered_multiset 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. +详见 link:../../../../container_hash/index.html[Boost.Hash 文档] 了解具体实现方式。请注意该实现依赖于对标准的扩展功能,因此不适用于其他版本的无序关联容器实现——您需要显式使用 Boost.Hash 才能获得此功能。 -[caption=, title='Table {counter:table-counter} Methods for accessing the hash and equality functions'] -[cols="1,.^1", frame=all, grid=rows] +[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. +|`hasher hash++_++function() const` +|返回容器的哈希函数。 -|`key_equal key_eq() const` -|Returns the container's key equality function.. +|`key++_++equal key++_++eq() const` +|返回容器的键相等性函数。 |=== diff --git a/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc index 3e6efee..d24b877 100644 --- a/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc @@ -1,18 +1,19 @@ -[#hash_quality] = Hash Quality +[#hash_quality] += 哈希质量 :idprefix: hash_quality_ -In order to work properly, hash tables require that the supplied hash function be of __good quality__, roughly meaning that it uses its `std::size_t` output space as uniformly as possible, much like a random number generator would do —except, of course, that the value of a hash function is not random but strictly determined by its input argument. +为了正常工作,哈希表要求提供的哈希函数具有__高质量__,这大致意味着它应尽可能均匀地使用其 `std::size++_++t` 输出空间,就像随机数生成器那样——当然,不同之处在于哈希函数的值并非随机,而是由其输入参数严格决定。 -Closed-addressing containers in Boost.Unordered are fairly robust against hash functions with less-than-ideal quality, but open-addressing and concurrent containers are much more sensitive to this factor, and their performance can degrade dramatically if the hash function is not appropriate. In general, if you're using functions provided by or generated with link:../../../../container_hash/index.html[Boost.Hash^], the quality will be adequate, but you have to be careful when using alternative hash algorithms. +Boost.Unordered 中的闭寻址容器对质量不理想的哈希函数具有较好的鲁棒性,但开放寻址和并发容器对此因素更为敏感。如果哈希函数选择不当,其性能会出现显著下降。通常,使用由 link:../../../../container_hash/index.html[Boost.Hash] 提供或生成的函数可确保质量达标,但在使用其他哈希算法时则需要特别谨慎。 -The rest of this section applies only to open-addressing and concurrent containers. +本节剩余的内容仅适用于开放寻址容器与并发容器。 -== Hash Post-mixing and the Avalanching Property +== 哈希后混合处理与雪崩效应属性 -Even if your supplied hash function does not conform to the uniform behavior required by open addressing, chances are that the performance of Boost.Unordered containers will be acceptable, because the library executes an internal __post-mixing__ step that improves the statistical properties of the calculated hash values. This comes with an extra computational cost; if you'd like to opt out of post-mixing, annotate your hash function as follows: +即使提供的哈希函数不符合开放寻址所需的均匀分布特性,Boost.Unordered容器的性能通常仍可接受,这是因为库会执行内部__后混合处理__步骤来改善计算哈希值的统计特性。当然这会带来额外的计算开销;若希望禁用后混合处理功能,请按以下方式对哈希函数进行注解: -[source,c++] +[source, c++] ---- struct my_string_hash_function { @@ -25,13 +26,13 @@ struct my_string_hash_function }; ---- -By setting the `link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]` trait, we inform Boost.Unordered that `my_string_hash_function` is of sufficient quality to be used directly without any post-mixing safety net. This comes at the risk of degraded performance in the cases where the hash function is not as well-behaved as we've declared. +通过设置 link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`] 特征,我们告知Boost.Unordered: `my++_++string++_++hash++_++function` 具有足够高的质量,无需任何后混合处理安全网即可直接使用。但这样做的风险在于,如果哈希函数的表现未达到我们声明的理想状态,则可能导致性能下降。 -== Container Statistics +== 容器统计信息 -If we globally define the macro `BOOST_UNORDERED_ENABLE_STATS`, open-addressing and concurrent containers will calculate some internal statistics directly correlated to the quality of the hash function: +若在全局定义宏 `BOOST++_++UNORDERED++_++ENABLE++_++STATS` ,开放寻址容器与并发容器将计算与哈希函数质量直接相关的内部统计信息: -[source,c++] +[source, c++] ---- #define BOOST_UNORDERED_ENABLE_STATS #include @@ -48,9 +49,9 @@ int main() } ---- -The `stats` object provides the following information: +`stats` 对象提供以下统计信息: -[source,subs=+quotes] +[source, subs=+quotes] ---- stats .insertion // *Insertion operations* @@ -81,14 +82,13 @@ stats .deviation ---- -Statistics for three internal operations are maintained: insertions (without considering the previous lookup to determine that the key is not present yet), successful lookups, and unsuccessful lookups (including those issued internally when inserting elements). _Probe length_ is the number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed per operation. If the hash function behaves properly: +系统维护三类内部操作的统计信息:插入操作(不考虑先前查找键是否存在的操作)、成功查找及未命中查找(包括插入元素时触发的内部查询)。__探测长度__是指每次操作所访问的 xref:structures.adoc#structures_open_addressing_containers[桶组] 数量。若哈希函数表现正常: -* Average probe lengths should be close to 1.0. -* The average number of comparisons per successful lookup should be close to 1.0 (that is, -just the element found is checked). -* The average number of comparisons per unsuccessful lookup should be close to 0.0. +* 平均探测长度应接近1.0。 +* 每次成功查找的平均比较次数应接近 1.0(即仅需核对找到的元素本身)。 +* 每次失败查找的平均比较次数应接近 0.0。 -An link:../../../benchmark/string_stats.cpp[example^] is provided that displays container statistics for `boost::hash`, an implementation of the https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a hash^] and two ill-behaved custom hash functions that have been incorrectly marked as avalanching: +我们提供了一个 link:../../../benchmark/string_stats.cpp[示例程序] ,用于展示以下哈希函数的容器统计信息: `boost::hash++<++std::string++>++` 、 https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a 哈希算法] 的实现,以及两个被错误标记为具备雪崩效应的自定义哈希函数: [listing] ---- diff --git a/doc/modules/ROOT/pages/intro_zh_Hans.adoc b/doc/modules/ROOT/pages/intro_zh_Hans.adoc index 2eb3215..0381c7b 100644 --- a/doc/modules/ROOT/pages/intro_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/intro_zh_Hans.adoc @@ -1,37 +1,51 @@ [#intro] -= Introduction += 引言 -:idprefix: intro_ :cpp: C++ +:idprefix: intro_ +:cpp: C++ -link:https://en.wikipedia.org/wiki/Hash_table[Hash tables^] are extremely popular computer data structures and can be found under one form or another in virtually any programming language. Whereas other associative structures such as rb-trees (used in {cpp} by `std::set` and `std::map`) have logarithmic-time complexity for insertion and lookup, hash tables, if configured properly, perform these operations in constant time on average, and are generally much faster. +https://en.wikipedia.org/wiki/Hash_table[哈希表] 是一种极其流行的计算机数据结构,几乎在所有编程语言中都能找到其不同形式的存在。红黑树(在 C{plus}{plus} 中被 `std::set` 和 `std::map` 使用)等其他关联结构在插入和查找操作上具有对数时间复杂度,但哈希表若配置得当,这些操作的平均时间复杂度可达到常数级别,并且通常速度更快。 -{cpp} introduced __unordered associative containers__ `std::unordered_set`, `std::unordered_map`, `std::unordered_multiset` and `std::unordered_multimap` in {cpp}11, but research on hash tables hasn't stopped since: advances in CPU architectures such as more powerful caches, link:https://en.wikipedia.org/wiki/Single_instruction,_multiple_data[SIMD] operations and increasingly available link:https://en.wikipedia.org/wiki/Multi-core_processor[multicore processors] open up possibilities for improved hash-based data structures and new use cases that are simply beyond reach of unordered associative containers as specified in 2011. +C{plus}{plus}11 标准引入了__无序关联容器__ `std::unordered++_++set` 、 `std::unordered++_++map` 、 `std::unordered++_++multiset` 和 `std::unordered++_++multimap` ,但针对哈希表的研究并未止步:CPU架构的进步(如更强大的缓存、 https://en.wikipedia.org/wiki/Single_instruction,_multiple_data[SIMD] 指令集以及日益普及的 https://en.wikipedia.org/wiki/Multi-core_processor[多核处理器])为改进基于哈希的数据结构创造了新的可能,这些新应用场景已远超 2011 年标准所定义的无序关联容器的能力范围。 -Boost.Unordered offers a catalog of hash containers with different standards compliance levels, performances and intented usage scenarios: +Boost.Unordered 提供了一系列哈希容器,它们在标准符合性、性能表现和设计应用场景上各有不同: -[caption=, title='Table {counter:table-counter}. Boost.Unordered containers'] -[cols="1,1,.^1", frame=all, grid=all] +[caption=",", title='Table {counter:table-counter}. Boost.Unordered containers'] +[cols="1,1,.^1", frame=all,, grid=all] |=== -^h| ^h|*Node-based* ^h|*Flat* +^h| +^h|*基于节点* +^h|*扁平* -^.^h|*Closed addressing* ^m| boost::unordered_set + boost::unordered_map + boost::unordered_multiset + boost::unordered_multimap ^| +^.^h|*Closed addressing* +^m| +`boost::unordered++_++set` + +`boost::unordered++_++map` + +`boost::unordered++_++multiset` + +`boost::unordered++_++multimap` +^| -^.^h|*Open addressing* ^m| boost::unordered_node_set + boost::unordered_node_map ^m| boost::unordered_flat_set + boost::unordered_flat_map +^.^h|*开放寻址法* +^m| `boost::unordered++_++node++_++set` + +`boost::unordered++_++node++_++map` +^m| `boost::unordered++_++flat++_++set` + +`boost::unordered++_++flat++_++map` -^.^h|*Concurrent* ^| `boost::concurrent_node_set` + `boost::concurrent_node_map` ^| `boost::concurrent_flat_set` + `boost::concurrent_flat_map` +^.^h|*并发* +^| `boost::concurrent++_++node++_++set` + +`boost::concurrent++_++node++_++map` +^| `boost::concurrent++_++flat++_++set` + +`boost::concurrent++_++flat++_++map` |=== -* **Closed-addressing containers** are fully compliant with the C++ specification -for unordered associative containers and feature one of the fastest implementations in the market within the technical constraints imposed by the required standard interface. -* **Open-addressing containers** rely on much faster data structures and algorithms -(more than 2 times faster in typical scenarios) while slightly diverging from the standard interface to accommodate the implementation. There are two variants: **flat** (the fastest) and **node-based**, which provide pointer stability under rehashing at the expense of being slower. -* Finally, **concurrent containers** are designed and implemented to be used in high-performance -multithreaded scenarios. Their interface is radically different from that of regular C++ containers. Flat and node-based variants are provided. +* **闭寻址容器**完全符合C{plus}{plus}无序关联容器规范,并在标准接口的技术约束范围内提供了业界领先的运行性能。 +* **开放寻址容器**采用了更高效的数据结构与算法(典型场景下性能提升2倍以上),同时为了适配实现方案而对标准接口做了细微调整。该类容器包含两种变体:*扁平式*(最快)与**基于节点式**,后者在重新哈希时能保持指针稳定性,但性能会有所下降。 +* 最后,**并发容器**专为高性能多线程场景设计与实现,其接口与常规C{plus}{plus}容器存在根本性差异。该系列同时提供扁平与基于节点两种变体。 -All sets and maps in Boost.Unordered are instantiatied similarly as `std::unordered_set` and `std::unordered_map`, respectively: +Boost.Unordered中的所有集合与映射均分别参照 `std::unordered++_++set` 和 `std::unordered++_++map` 的方式进行实例化: -[source,c++] +[source, c++] ---- namespace boost { template < @@ -40,8 +54,8 @@ namespace boost { class Pred = std::equal_to, class Alloc = std::allocator > class unordered_set; - // same for unordered_multiset, unordered_flat_set, unordered_node_set, - // concurrent_flat_set and concurrent_node_set + // unordered_multiset, unordered_flat_set, unordered_node_set, + // concurrent_flat_set 和 concurrent_node_set 同理 template < class Key, class Mapped, @@ -49,9 +63,9 @@ namespace boost { class Pred = std::equal_to, class Alloc = std::allocator > > class unordered_map; - // same for unordered_multimap, unordered_flat_map, unordered_node_map, - // concurrent_flat_map and concurrent_node_map + // unordered_multimap, unordered_flat_map, unordered_node_map, + // concurrent_flat_map 和 concurrent_node_map 同理 } ---- -Storing 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 xref:hash_equality.adoc#hash_equality[Equality Predicates and Hash Functions], section for more details. +在无序关联容器中存储对象需要同时具备键相等性函数与哈希函数。标准容器中的默认函数对象支持若干基础类型,包括整数类型、浮点类型、指针类型以及标准字符串类型。由于Boost.Unordered采用 link:../../../../container_hash/index.html[boost::hash] ,它还能支持其他类型(包括标准容器)。若要使用这些方法不支持的任意类型,那就需要扩展 Boost.Hash, 以支持该类型,或使用自定义的相等性谓词与哈希函数。更多详细信息请参阅 xref:hash_equality.adoc#hash_equality[相等性谓词与哈希函数] 章节。 diff --git a/doc/modules/ROOT/pages/rationale_zh_Hans.adoc b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc index db2db06..51b873c 100644 --- a/doc/modules/ROOT/pages/rationale_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc @@ -2,78 +2,72 @@ :idprefix: rationale_ -= Implementation Rationale += 实现设计依据 -== Closed-addressing Containers +== 闭寻址容器 -`boost::unordered_[multi]set` and `boost::unordered_[multi]map` adhere to the standard requirements for unordered associative containers, so the interface was fixed. But there are still some implementation decisions to make. The priorities are conformance to the standard and portability. +`boost::unordered++_[++multi++]++set` 与 `boost::unordered++_[++multi++]++map` 遵循无序关联容器的标准规范,因此其接口是确定的。但在实现层面仍需做出一些决策,其首要考量是标准符合性与跨平台移植性。 -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. +关于哈希表的通用实现问题的详细综述,可参阅 http://en.wikipedia.org/wiki/Hash_table[维基百科哈希表条目] 。 -=== Data Structure +=== 数据结构 -By specifying an interface for accessing the buckets of the container the standard pretty much requires that the hash table uses closed 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 closed -addressing, users will be surprised if the performance doesn't reflect that. +* 该标准要求指向元素的指针不得失效,因此元素不能存储在单一数组中,而需要增加一层间接寻址,这将导致效率下降并丧失开放寻址法最主要的优势:高效性和内存节省。 +* 局部迭代器的实现将极为低效,且可能无法满足复杂度要求。 +* 此外,标准对迭代器失效的时机也存在限制。由于开放寻址法在发生大量冲突时性能会急剧下降,这些限制可能会阻止必要的重新哈希操作。虽然可以通过设置较低的最大负载因子来规避此问题——但标准要求该值初始必须设为 1.0。 +* 由于该标准的制定主要着眼于闭寻址方案,若性能表现不符预期,将会引发用户的困惑。 -So closed 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. +选择哈希表桶数量有两种主流方法:一种是采用质数作为桶的数量,另一种则是使用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. +使用2的幂次方可加快桶选择速度,但代价是牺牲哈希值的高位比特。对于一些特殊设计的哈希函数,这样做仍能获得良好效果,但由于容器需要兼容任意哈希函数,因此不能依赖这种方法。 -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. +为避免此问题,可对哈希函数施加转换操作(具体示例可参阅 http://web.archive.org/web/20121102023700/http://www.concentric.net/~Ttwang/tech/inthash.htm[Thomas Wang整数哈希函数文章])。但此类变换需知晓哈希值比特数,故仅在 `size++_++t` 为64位时才会启用。 -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 `2^w` divided by the golden ratio, `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. +自1.79.0版起,改用 https://en.wikipedia.org/wiki/Hash_function#Fibonacci_hashing[斐波那契哈希] 。在此实现中,桶编号通过公式 `(h ++*++ m) ++>>++ (w - k)` 确定:其中 `h` 为哈希值, `m` 为 `2^w` 除以黄金分割比的值, `w` 为字长(32位或64位), `2^k` 表示桶的数量。此方法在速度和分布均匀性之间实现了较好的平衡。 -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. +自1.80.0版起,结合精密取模运算选用质数桶量,无需1.79.0版所用的用户哈希函数结果"混合"处理。 -== Open-addresing Containers +== 开地址容器 -The C++ standard specification of unordered associative containers impose severe limitations on permissible implementations, the most important being that closed addressing is implicitly assumed. Slightly relaxing this specification opens up the possibility of providing container variations taking full advantage of open-addressing techniques. +C{plus}{plus} 标准对无序关联容器的实现规范施加了严格限制。最重要约束是隐式假设必须采用闭寻址方案。若适当放宽此规范,则能充分利用开放寻址技术优势,提供多样化的容器实现变体。 -The design of `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` has been guided by Peter Dimov's https://pdimov.github.io/articles/unordered_dev_plan.html[Development Plan for Boost.Unordered^]. We discuss here the most relevant principles. +`boost::unordered++_++flat++_++set` / `unordered++_++node++_++set` 及 `boost::unordered++_++flat++_++map` / `unordered++_++node++_++map` 的设计遵循Peter Dimov的 https://pdimov.github.io/articles/unordered_dev_plan.html[Boost.Unordered开发计划] 中提出的指导原则。下文将探讨其中最核心的设计理念。 -=== Hash Function +=== 哈希函数 -Given its rich functionality and cross-platform interoperability, `boost::hash` remains the default hash function of open-addressing containers. As it happens, `boost::hash` for integral and other basic types does not possess the statistical properties required by open addressing; to cope with this, we implement a post-mixing stage: +基于其丰富功能与跨平台互操作性, `boost::hash` 仍是开放寻址容器的默认哈希函数。但由于其对整型等基础类型实现的 boost::hash 缺乏开放寻址所需的统计特性,我们额外增加了后混合处理阶段: -{nbsp}{nbsp}{nbsp}{nbsp} _a_ <- _h_ *mul* _C_, + {nbsp}{nbsp}{nbsp}{nbsp} _h_ <- *high*(_a_) *xor* *low*(_a_), +{nbsp}{nbsp}{nbsp}{nbsp} _a_ <- _h_ *mul* _C_, + +{nbsp}{nbsp}{nbsp}{nbsp} _h_ <- *high*(_a_) *xor* *low*(_a_), -where *mul* is an _extended multiplication_ (128 bits in 64-bit architectures, 64 bits in 32-bit environments), and *high* and *low* are the upper and lower halves of an extended word, respectively. In 64-bit architectures, _C_ is the integer part of 2^64^∕https://en.wikipedia.org/wiki/Golden_ratio[_φ_], whereas in 32 bits _C_ = 0xE817FB2Du has been obtained from https://arxiv.org/abs/2001.05304[Steele and Vigna (2021)^]. +其中**mul**为__扩展乘法__(在 64 位架构中生成 128 位结果,在 32 位环境中生成 64 位结果),**high**和**low**分别表示扩展字的高位与低位部分。在 64 位架构中,__C__取值为2^64^∕https://en.wikipedia.org/wiki/Golden_ratio[_φ_] 的整数部分;而在32位中__C__ = 0xE817FB2Du源自 https://arxiv.org/abs/2001.05304[Steele与Vigna(2021)] 。 -When using a hash function directly suitable for open addressing, post-mixing can be opted out of via a dedicated `link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]` trait. `boost::hash` specializations for string types are marked as avalanching. +当所使用的哈希函数本身已适用于开放寻址时,可通过专用的 link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]. -=== Platform Interoperability +=== 平台互操作性 -The observable behavior of `boost::unordered_flat_set`/`unordered_node_set` and `boost::unordered_flat_map`/`unordered_node_map` is deterministically identical across different compilers as long as their ``std::size_t``s are the same size and the user-provided hash function and equality predicate are also interoperable —this includes elements being ordered in exactly the same way for the same sequence of operations. +只要不同编译器的 `std::size++_++t` 具有相同位宽,且用户提供的哈希函数与相等性谓词具备跨平台一致性,那么 `boost::unordered++_++flat++_++set` / `unordered++_++node++_++set` 及 `boost::unordered++_++flat++_++map` / `unordered++_++node++_++map` 的可观测行为在不同编译器间将保持确定性一致——这包括在相同的操作序列下,元素在迭代时的出现顺序完全相同。 -Although the implementation internally uses SIMD technologies, such as https://en.wikipedia.org/wiki/SSE2[SSE2^] and https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(NEON)[Neon^], when available, this does not affect interoperatility. For instance, the behavior is the same for Visual Studio on an x64-mode Intel CPU with SSE2 and for GCC on an IBM s390x without any supported SIMD technology. +尽管实现在内部会适时运用 SIMD 技术(如 https://en.wikipedia.org/wiki/SSE2[SSE2] 与 https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(NEON)[Neon] 等),但这并不会影响其跨平台互操作性。例如,在支持 SSE2 的 x64 架构 Intel CPU 上使用 Visual Studio 编译器,与在不支持任何 SIMD 技术的 IBM s390x 架构上使用 GCC 编译器,两者的容器行为表现完全一致。 -== Concurrent Containers +== 并发容器 -The same data structure used by Boost.Unordered open-addressing containers has been chosen also as the foundation of `boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map`: +Boost.Unordered开放寻址容器所采用的底层数据结构,同样被选作 `boost::concurrent++_++flat++_++set` / `boost::concurrent++_++node++_++set` 与 `boost::concurrent++_++flat++_++map` / `boost::concurrent++_++node++_++map` 的实现基础: -* Open-addressing is faster than closed-addressing alternatives, both in non-concurrent and -concurrent scenarios. -* Open-addressing layouts are eminently suitable for concurrent access and modification -with minimal locking. In particular, the metadata array can be used for implementations of lookup that are lock-free up to the last step of actual element comparison. -* Layout compatibility with Boost.Unordered flat containers allows for -xref:concurrent.adoc#concurrent_interoperability_with_non_concurrent_containers[fast transfer] of all elements between a concurrent container and its non-concurrent counterpart, and vice versa. +* 无论在非并发还是并发场景下,开放寻址方案的性能均优于闭寻址方案。 +* 开放寻址的内存布局极其适合在最小化锁竞争的条件下进行并发访问与修改。具体而言,其元数据数组可实现无锁查找,直至最终执行实际元素比较的阶段。 +* 并发容器与 Boost.Unordered 扁平容器具有内存布局兼容性,支持其与非并发对应容器之间 xref:concurrent.adoc#concurrent_interoperability_with_non_concurrent_containers[快速双向传输] 所有元素。 -=== Hash Function and Platform Interoperability +=== 哈希函数与平台互操作性 -Concurrent containers make the same decisions and provide the same guarantees as Boost.Unordered open-addressing containers with regards to xref:#rationale_hash_function[hash function defaults] and xref:#rationale_platform_interoperability[platform interoperability]. +在 xref:#rationale_hash_function[哈希函数默认设置] 和 xref:#rationale_platform_interoperability[平台互操作性] 方面,并发容器遵循与 Boost.Unordered 开放寻址容器相同的决策逻辑并提供同等保证。 diff --git a/doc/modules/ROOT/pages/ref_zh_Hans.adoc b/doc/modules/ROOT/pages/ref_zh_Hans.adoc index 36976a2..b7ddd46 100644 --- a/doc/modules/ROOT/pages/ref_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/ref_zh_Hans.adoc @@ -1,39 +1,39 @@ [#reference] -= Reference += 参考 -* xref:reference/header_unordered_map_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_map_top.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_map.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_map.adoc[Class Template ++++++unordered_map++++++] -* xref:reference/unordered_multimap.adoc[Class Template ++++++unordered_multimap++++++] -* xref:reference/header_unordered_set_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_set_top.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_set.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_set.adoc[Class Template ++++++unordered_set++++++] -* xref:reference/unordered_multiset.adoc[Class Template ++++++unordered_multiset++++++] -* xref:reference/hash_traits.adoc[Hash Traits] -* xref:reference/stats.adoc[Statistics] -* xref:reference/header_unordered_flat_map_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_flat_map.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_flat_map.adoc[Class Template ++++++unordered_flat_map++++++] -* xref:reference/header_unordered_flat_set_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_flat_set.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_flat_set.adoc[Class Template ++++++unordered_flat_set++++++] -* xref:reference/header_unordered_node_map_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_node_map.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_node_map.adoc[Class Template ++++++unordered_node_map++++++] -* xref:reference/header_unordered_node_set_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_unordered_node_set.adoc[++++++++++++ Synopsis] -* xref:reference/unordered_node_set.adoc[Class Template ++++++unordered_node_set++++++] -* xref:reference/header_concurrent_flat_map_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_concurrent_flat_map.adoc[++++++++++++ Synopsis] -* xref:reference/concurrent_flat_map.adoc[Class Template ++++++concurrent_flat_map++++++] -* xref:reference/header_concurrent_flat_set_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_concurrent_flat_set.adoc[++++++++++++ Synopsis] -* xref:reference/concurrent_flat_set.adoc[Class Template ++++++concurrent_flat_set++++++] -* xref:reference/header_concurrent_node_map_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_concurrent_node_map.adoc[++++++++++++ Synopsis] -* xref:reference/concurrent_node_map.adoc[Class Template ++++++concurrent_node_map++++++] -* xref:reference/header_concurrent_node_set_fwd.adoc[++++++++++++ Synopsis] -* xref:reference/header_concurrent_node_set.adoc[++++++++++++ Synopsis] -* xref:reference/concurrent_node_set.adoc[Class Template ++++++concurrent_node_set++++++] +* xref:reference/header_unordered_map_fwd.adoc[`++<++boost/unordered/unordered++_++map++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_map_top.adoc[`++<++boost/unordered++_++map.hpp++>++` 概要] +* xref:reference/header_unordered_map.adoc[`++<++boost/unordered/unordered++_++map.hpp++>++` 概要] +* xref:reference/unordered_map.adoc[类模板 `unordered++_++map`] +* xref:reference/unordered_multimap.adoc[类模板 `unordered++_++multimap`] +* xref:reference/header_unordered_set_fwd.adoc[`++<++boost/unordered/unordered++_++set++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_set_top.adoc[`++<++boost/unordered++_++set.hpp++>++` 概要] +* xref:reference/header_unordered_set.adoc[`++<++boost/unordered/unordered++_++set.hpp++>++` 概要] +* xref:reference/unordered_set.adoc[类模板 `unordered++_++set`] +* xref:reference/unordered_multiset.adoc[类模板 `unordered++_++multiset`] +* xref:reference/hash_traits.adoc[哈希特征] +* xref:reference/stats.adoc[统计信息] +* xref:reference/header_unordered_flat_map_fwd.adoc[`++<++boost/unordered/unordered++_++flat++_++map++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_flat_map.adoc[`++<++boost/unordered/unordered++_++flat++_++map.hpp++>++` 概要] +* xref:reference/unordered_flat_map.adoc[类模板 `unordered++_++flat++_++map`] +* xref:reference/header_unordered_flat_set_fwd.adoc[`++<++boost/unordered/unordered++_++flat++_++set++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_flat_set.adoc[`++<++boost/unordered/unordered++_++flat++_++set.hpp++>++` 概要] +* xref:reference/unordered_flat_set.adoc[类模板 `unordered++_++flat++_++set`] +* xref:reference/header_unordered_node_map_fwd.adoc[`++<++boost/unordered/unordered++_++node++_++map++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_node_map.adoc[`++<++boost/unordered/unordered++_++node++_++map.hpp++>++` 概要] +* xref:reference/unordered_node_map.adoc[类模板 `unordered++_++node++_++map`] +* xref:reference/header_unordered_node_set_fwd.adoc[`++<++boost/unordered/unordered++_++node++_++set++_++fwd.hpp++>++` 概要] +* xref:reference/header_unordered_node_set.adoc[`++<++boost/unordered/unordered++_++node++_++set.hpp++>++` 概要] +* xref:reference/unordered_node_set.adoc[类模板 `unordered++_++node++_++set`] +* xref:reference/header_concurrent_flat_map_fwd.adoc[`++<++boost/unordered/concurrent++_++flat++_++map++_++fwd.hpp++>++` 概要] +* xref:reference/header_concurrent_flat_map.adoc[`++<++boost/unordered/concurrent++_++flat++_++map.hpp++>++` 概要] +* xref:reference/concurrent_flat_map.adoc[类模板 `concurrent++_++flat++_++map`] +* xref:reference/header_concurrent_flat_set_fwd.adoc[`++<++boost/unordered/concurrent++_++flat++_++set++_++fwd.hpp++>++` 概要] +* xref:reference/header_concurrent_flat_set.adoc[`++<++boost/unordered/concurrent++_++flat++_++set.hpp++>++` 概要] +* xref:reference/concurrent_flat_set.adoc[类模板 `concurrent++_++flat++_++set`] +* xref:reference/header_concurrent_node_map_fwd.adoc[`++<++boost/unordered/concurrent++_++node++_++map++_++fwd.hpp++>++` 概要] +* xref:reference/header_concurrent_node_map.adoc[`++<++boost/unordered/concurrent++_++node++_++map.hpp++>++` 概要] +* xref:reference/concurrent_node_map.adoc[类模板 `concurrent++_++node++_++map`] +* xref:reference/header_concurrent_node_set_fwd.adoc[`++<++boost/unordered/concurrent++_++node++_++set++_++fwd.hpp++>++` 概要] +* xref:reference/header_concurrent_node_set.adoc[`++<++boost/unordered/concurrent++_++node++_++set.hpp++>++` 概要] +* xref:reference/concurrent_node_set.adoc[类模板 `concurrent++_++node++_++set`] diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc index 55ed491..8055207 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_map_zh_Hans.adoc @@ -1,17 +1,17 @@ -[#concurrent_flat_map] -== Class Template concurrent_flat_map +[#concurrent_flat_map] +== 类模板 concurrent++_++flat++_++map :idprefix: concurrent_flat_map_ -`boost::concurrent_flat_map` — A hash table that associates unique keys with another value and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. +`boost::concurrent++_++flat++_++map` — 一种哈希表,用于将唯一键与另一个值相关联,并支持在无外部同步机制的情况下并发执行元素的插入、擦除、查找及访问操作。 -Even though it acts as a container, `boost::concurrent_flat_map` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access and modification are done through user-provided _visitation functions_ that are passed to `concurrent_flat_map` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. +尽管 `boost::concurrent++_++flat++_++map` 充当容器的角色,但它并不符合标准C{plus}{plus}的 https://en.cppreference.com/w/cpp/named_req/Container[容器] 概念。具体而言,它不提供迭代器及相关操作( `begin` 、 `end` 等)。元素的访问和修改通过用户提供的__访问函数__实现,这些函数被传递至 `concurrent++_++flat++_++map` 的内部操作,并以受控方式执行。这种基于访问的 API 设计支持低竞争度的并发使用场景。 -The internal data structure of `boost::concurrent_flat_map` is similar to that of `boost::unordered_flat_map`. As a result of its using open-addressing techniques, `value_type` must be move-constructible and pointer stability is not kept under rehashing. +`boost::concurrent++_++flat++_++map` 的内部数据结构与 `boost::unordered++_++flat++_++map` 类似。由于采用开放寻址技术, `value++_++type` 必须支持移动构造,且在重哈希过程中无法保持指针稳定性。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_concurrent_flat_map.adoc[``] @@ -25,7 +25,7 @@ namespace unordered { class Allocator = std::allocator>> class concurrent_flat_map { public: - // types + // 类型 using key_type = Key; using mapped_type = T; using value_type = std::pair; @@ -45,10 +45,10 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled] - // constants + // 常量 static constexpr size_type xref:#concurrent_flat_map_constants[bulk_visit_size] = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#concurrent_flat_map_default_constructor[concurrent_flat_map](); explicit xref:#concurrent_flat_map_bucket_count_constructor[concurrent_flat_map](size_type n, const hasher& hf = hasher(), @@ -96,7 +96,7 @@ namespace unordered { allocator_type xref:#concurrent_flat_map_get_allocator[get_allocator]() const noexcept; - // visitation + // 访问 template size_t xref:#concurrent_flat_map_cvisit[visit](const key_type& k, F f); template size_t xref:#concurrent_flat_map_cvisit[visit](const key_type& k, F f) const; template size_t xref:#concurrent_flat_map_cvisit[cvisit](const key_type& k, F f) const; @@ -131,12 +131,12 @@ namespace unordered { template bool xref:#concurrent_flat_map_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#concurrent_flat_map_empty[empty]() const noexcept; size_type xref:#concurrent_flat_map_size[size]() const noexcept; size_type xref:#concurrent_flat_map_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template bool xref:#concurrent_flat_map_emplace[emplace](Args&&... args); bool xref:#concurrent_flat_map_copy_insert[insert](const value_type& obj); bool xref:#concurrent_flat_map_copy_insert[insert](const init_type& obj); @@ -235,11 +235,11 @@ namespace unordered { template size_type xref:#concurrent_flat_map_merge[merge](concurrent_flat_map&& source); - // observers + // 观察器 hasher xref:#concurrent_flat_map_hash_function[hash_function]() const; key_equal xref:#concurrent_flat_map_key_eq[key_eq]() const; - // map operations + // 映射操作 size_type xref:#concurrent_flat_map_count[count](const key_type& k) const; template size_type xref:#concurrent_flat_map_count[count](const K& k) const; @@ -247,10 +247,10 @@ namespace unordered { template bool xref:#concurrent_flat_map_contains[contains](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#concurrent_flat_map_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#concurrent_flat_map_load_factor[load_factor]() const noexcept; float xref:#concurrent_flat_map_max_load_factor[max_load_factor]() const noexcept; void xref:#concurrent_flat_map_set_max_load_factor[max_load_factor](float z); @@ -258,12 +258,12 @@ namespace unordered { void xref:#concurrent_flat_map_rehash[rehash](size_type n); void xref:#concurrent_flat_map_reserve[reserve](size_type n); - // statistics (if xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]) + // 统计(如果启用) stats xref:#concurrent_flat_map_get_stats[get_stats]() const; void xref:#concurrent_flat_map_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指南 template>, class Pred = std::equal_to>, @@ -313,120 +313,139 @@ namespace unordered { Hash, Allocator) -> concurrent_flat_map, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -.2+|`Key` and `T` must be https://en.cppreference.com/w/cpp/named_req/MoveConstructible[MoveConstructible^]. -`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the table from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the table. +|_键_ +.2+|`Key` 和 `T` 必须满足 https://en.cppreference.com/w/cpp/named_req/MoveConstructible[可移动构造] 要求。 `std::pair++<++const Key, T++>++` 必须能够从任何可转换的 `std::pair` 对象 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到容器中,并且必须能够从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 。 |_T_ |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the table's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同。支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements of the table are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素存储在内部的__桶数组__中。元素根据其哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 进行调整。容器的__负载因子__(元素数量与桶数量的比值)永远不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Concurrency Requirements and Guarantees +=== 并发要求与保证 -Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: +要求对同一 `Hash` 或 `Pred` 常量实例并发调用 `operator()` 时不得引入数据竞争。对于 `Alloc` (即 `Allocator` 或其重绑定后的任意分配器类型),在同一实例 `al` 上并发调用以下操作时不得引入数据竞争: -* Copy construction from `al` of an allocator rebound from `Alloc` -* `std::allocator_traits::allocate` -* `std::allocator_traits::deallocate` -* `std::allocator_traits::construct` -* `std::allocator_traits::destroy` +* 从 `al` 复制构造重新绑定的分配器 +* `std::allocator++_++traits++<++Alloc++>++::allocate` +* `std::allocator++_++traits++<++Alloc++>++::deallocate` +* `std::allocator++_++traits++<++Alloc++>++::construct` +* `std::allocator++_++traits++<++Alloc++>++::destroy` -In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. +通常而言,若 `Hash` 、 `Pred` 和 `Allocator` 这些类型不包含状态,或其操作仅涉及对内部数据成员的常量访问,即可满足上述要求。 -With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_flat_map` do not introduce data races — that is, they are thread-safe. +除了析构操作外,在同一个 `concurrent++_++flat++_++map` 实例上并发调用任何操作都不会引入数据竞争——即这些操作是线程安全的。 -If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_flat_map`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_flat_map` execute sequentially in a multithreaded scenario. +若某个操作 *op* 被显式指定为__阻塞于__ `x` (其中 `x` 为 `boost::concurrent++_++flat++_++map` 实例),则先前对 `x` 的阻塞操作将与 *op* 同步。因此,在多线程场景中,对同一 `concurrent++_++flat++_++map` 的阻塞操作将按顺序执行。 -An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. +若某个操作仅在触发内部重哈希时才会阻塞于 _`x`_,则称该操作__阻塞于 _`x`_ 的重哈希过程__。 -When executed internally by a `boost::concurrent_flat_map`, the following operations by a user-provided visitation function on the element passed do not introduce data races: +当由 `boost::concurrent++_++flat++_++map` 内部执行时,用户提供的访问函数对传入元素执行以下操作不会引入数据竞争: -* Read access to the element. -* Non-mutable modification of the element. -* Mutable modification of the element: -Any `boost::concurrent_flat_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. +* 对元素的读取访问。 +* 对元素的非可变修改。 +* 对元素的可变修改: + ** 在容器接受两个访问函数的操作中,此条件始终适用于第一个访问函数。 + ** 在名称不包含 `cvisit` 的非常量容器函数中,此条件适用于最后一个(或唯一一个)访问函数。 -Visitation functions executed by a `boost::concurrent_flat_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. +任何插入或修改元素 `e` 的 `boost::concurrent++_++flat++_++map` 操作,都会与针对 `e` 的内部访问函数调用同步。 ---- +由 `boost::concurrent++_++flat++_++map` 容器 `x` 执行的访问函数不得调用 `x` 上的任何操作;仅当对另一 `boost::concurrent++_++flat++_++map` 实例 `y` 的并发的未完成操作不直接或间接访问 `x` 时,才允许调用实例 `y` 上的操作。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` +==== `BOOST++_++UNORDERED++_++DISABLE++_++REENTRANCY++_++CHECK` -In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. +在调试版本中(更准确地说,当未定义 link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST++_++ASSERT++_++IS++_++VOID`] 时),系统会检测__容器重入__行为(即在访问 `m` 元素的函数内部非法调用 `m` 上的操作),并通过 `BOOST++_++ASSERT++_++MSG` 发出信号。若需关注运行时速度,可通过全局定义此宏来禁用该功能。 --- -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. +全局定义此宏以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低多数操作的总体性能。 --- -=== Constants +=== 常量 + +```cpp + +static constexpr size_type bulk_visit_size; + +``` + +在 xref:concurrent_flat_map_bulk_visit[批量访问] 操作中内部使用的块大小。 -```cpp static constexpr size_type bulk_visit_size; ``` +=== 构造函数 -Chunk size internally used in xref:concurrent_flat_map_bulk_visit[bulk visit] operations. +==== 默认构造函数 +```c++ -=== Constructors +concurrent_flat_map(); -==== Default Constructor -```c++ concurrent_flat_map(); ``` +``` -Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +构造一个空容器,使用 `hasher()` 作为哈希函数, `key++_++equal()` 作为键相等性谓词, `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit concurrent_flat_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +explicit concurrent_flat_map(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_map(InputIterator f, InputIterator l, @@ -436,85 +455,115 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ concurrent_flat_map(concurrent_flat_map const& other); ``` +==== 复制构造函数 +```c++ + +concurrent_flat_map(concurrent_flat_map const& other); -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. +要求;; `value++_++type` 必须满足可复制构造要求 +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor -```c++ concurrent_flat_map(concurrent_flat_map&& other); ``` +==== 移动构造函数 +```c++ + +concurrent_flat_map(concurrent_flat_map&& other); -The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +``` + +移动构造函数。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。如果统计功能已 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] ,则同时转移 `other` 中的内部统计信息并调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template concurrent_flat_map(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + concurrent_flat_map(InputIterator f, InputIterator l, const allocator_type& a); -Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit concurrent_flat_map(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit concurrent_flat_map(Allocator const& a); -Constructs an empty table, using allocator `a`. +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ concurrent_flat_map(concurrent_flat_map const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +concurrent_flat_map(concurrent_flat_map const& other, Allocator const& a); + +``` -Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor with Allocator -```c++ concurrent_flat_map(concurrent_flat_map&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +concurrent_flat_map(concurrent_flat_map&& other, Allocator const& a); + +``` -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +如果 `a == other.get++_++allocator()` ,则 `other` 的元素直接转移至新容器;否则,元素从 `other` 的元素移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。如果统计功能已 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] ,则当且仅当 `a == other.get++_++allocator()` 时,同时转移其内部统计信息,并始终调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor from unordered_flat_map +==== 从 unordered++_++flat++_++map 的移动构造函数 -```c++ concurrent_flat_map(unordered_flat_map&& other); ``` +```c++ -Move construction from a xref:#unordered_flat_map[`unordered_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +concurrent_flat_map(unordered_flat_map&& other); + +``` + +从 xref:#unordered_flat_map[`unordered_flat_map`][`unordered++_++flat++_++map`] 移动构造。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。如果统计功能已 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; O(`bucket_count()`) +复杂度;; O(`bucket++_++count()`) --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- concurrent_flat_map(std::initializer_list il, size_type n = _implementation-defined_ @@ -523,710 +572,1155 @@ concurrent_flat_map(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ concurrent_flat_map(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +concurrent_flat_map(size_type n, allocator_type const& a); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ concurrent_flat_map(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +concurrent_flat_map(size_type n, hasher const& hf, allocator_type const& a); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ + +concurrent_flat_map(std::initializer_list il, const allocator_type& a); -```c++ concurrent_flat_map(std::initializer_list il, const allocator_type& a); ``` +``` -Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ + +concurrent_flat_map(std::initializer_list il, size_type n, const allocator_type& a); -```c++ concurrent_flat_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +``` -Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 -```c++ concurrent_flat_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +concurrent_flat_map(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~concurrent_flat_map(); ``` +~concurrent_flat_map(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ concurrent_flat_map& operator=(concurrent_flat_map const& other); ``` +concurrent_flat_map& operator=(concurrent_flat_map const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Move Assignment -```c++ concurrent_flat_map& operator=(concurrent_flat_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +concurrent_flat_map& operator=(concurrent_flat_map&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值操作符。该操作会销毁容器中原有的元素,交换 `other` +的哈希函数与键相等性谓词。若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则直接将 `other` 的内部桶数组转移至 +`++*++this` ;否则,将插入 `other` +中元素的移动构造副本。如果统计功能已 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] ,则当且仅当最终分配器与 +`other.get++_++allocator()` 相等时,同时转移其内部统计信息,并始终调用 +`other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `*this` and `other`. +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Initializer List Assignment -```c++ concurrent_flat_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +concurrent_flat_map& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All previously existing elements are destroyed. +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 。 --- -=== Visitation +=== 访问操作 -==== [c]visit +==== ++[++c++]++visit( ++[++c++]++ 访问) -```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` +```c++ -If an element `x` exists with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. +template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; + +``` + +如果存在键等价于 `k` 的元素 `x` ,则通过指向 `x` 的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被访问的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Bulk visit +==== 批量访问 + +```c++ -```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` +template + size_t visit(FwdIterator first, FwdIterator last, F f); +template + size_t visit(FwdIterator first, FwdIterator last, F f) const; +template + size_t cvisit(FwdIterator first, FwdIterator last, F f) const; -For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. +``` -Although functionally equivalent to individually invoking xref:concurrent_flat_map_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_flat_map_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. +对于范围 ++[++`first`, `last`)中的每个元素 `k` ,如果容器中存在键等价于 `k` 的元素 `x` ,则通过指向 `x` 的引用来调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为 常量引用。 + +尽管在功能上等同于为每个键单独调用 xref:#concurrent_flat_map_cvisit[`++[++c++]++visit`] ,但由于内部流线化优化,批量访问通常表现更优。建议使 `std::distance(first,last)` 至少达到 xref:#concurrent_flat_map_constants[`bulk++_++visit++_++size`] 以获得性能提升:超过此大小,性能预计不会进一步提升。 [horizontal] -Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. +要求;; `FwdIterator` 需满足 https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator] 要求(C{plus}{plus}11 至 C{plus}{plus}17)或符合 https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward++_++iterator] 规范(C{plus}{plus}20 及更高版本)。对于 `K` = `std::iterator++_++traits++<++FwdIterator++>++::value++_++type` ,需满足以下条件之一: `K` 与 `key++_++type` 类型相同,或 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名。对于后一种情况,该库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 +返回;; 被访问的元素数量。 --- -==== [c]visit_all +==== ++[++c++]++visit++_++all + +```c++ -```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` +template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; -Successively invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. +``` + +依次使用指向表中各元素的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Returns:;; The number of elements visited. +返回;; 被访问的元素数量。 --- -==== Parallel [c]visit_all +==== 并行 ++[++c++]++visit++_++all + +```c++ + +template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; -```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` +``` -Invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. +根据指定的执行策略语义并行化执行,使用指向表中各元素的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== [c]visit_while +==== ++[++c++]++visit++_++while + +```c++ + +template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; -```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` +``` -Successively invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. +依次使用指向容器中各元素的引用来调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问。当且仅当 `++*++this` 为常量时,指向元素的该引用也为常量引用。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 --- -==== Parallel [c]visit_while +==== 并行 ++[++c++]++visit++_++while -```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` +```c++ -Invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. +template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; + +``` + +依次使用指向容器中各元素的引用来调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问。当且仅当 `++*++this` 为常量时,指向元素的该引用也为常量引用。根据指定的执行策略语义并行化执行操作。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 + ++ +并行化意味着执行不一定会因 `f` 返回 `false` 而立即结束,因此系统可能继续使用其他元素调用 `f` (即使其返回值同样为 `false` )。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ -```c++ size_type size() const noexcept; ``` +size_type size() const noexcept; + +``` [horizontal] -Returns:;; The number of elements in the table. +返回;; 容器中的元素数量。 [horizontal] -Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. +注意;; 在存在并发插入操作的情况下,返回值可能无法准确反映执行完成后容器的真实大小。 --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回;; 返回该容器可能包含的最大元素数量 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template bool emplace(Args&&... args); -==== emplace -```c++ template bool emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. +当且仅当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。 --- -==== Copy Insert -```c++ bool insert(const value_type& obj); bool insert(const init_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +bool insert(const value_type& obj); bool insert(const init_type& obj); + +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Move Insert -```c++ bool insert(value_type&& obj); bool insert(init_type&& obj); ``` +==== 移动插入 +```c++ + +bool insert(value_type&& obj); bool insert(init_type&& obj); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Insert Iterator Range -```c++ template size_type insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template size_type insert(InputIterator first, InputIterator last); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_map_emplace[emplace](*first++); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List -```c++ size_type insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ + +size_type insert(std::initializer_list il); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_map_insert_iterator_range[insert](il.begin(), il.end()); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +==== emplace++_++or++_[++c++]++visit +```c++ + +template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); + +``` -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `emplace_or_cvisit` is used. +如果容器中不存在等价键的元素,则插入一个用参数 `args` 构造的对象。否则,使用执行等价元素的引用来调用 `f` ;如果使用 `emplace++_++or++_++cvisit` 时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 --- -==== Copy insert_or_[c]visit -```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); ``` +==== 复制 insert++_++or++_[++c++]++visit +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj` ;否则,使用指向等效元素的引用调用 `f` (当使用 `++*_++cvisit` 重载时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +在 `insert++_++or++_[++c++]++visit(obj, f)` 形式的调用中,仅当 `std::remove++_++cv++<++std::remove++_++reference++<++decltype(obj)++>++::type++>++::type` 为 `value++_++type` 时,接受 `const value++_++type&` 参数的重载才会参与重载决议。 --- -==== Move insert_or_[c]visit -```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); ``` +==== 移动 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj` ;否则,使用指向等效元素的引用调用 `f` (当使用 `++*_++cvisit` 重载时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +在 `insert++_++or++_[++c++]++visit(obj, f)` 形式的调用中,仅当 `std::remove++_++reference++<++decltype(obj)++>++::type` 为 `value++_++type` 时,接受 `value++_++type&&` 参数的重载才会参与重载决议。 --- -==== Insert Iterator Range or Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` +==== 迭代器范围插入或访问 +```c++ + +template + size_type insert_or_visit(InputIterator first, InputIterator last, F f); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_map_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List or Visit -```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` +==== 初始化列表插入或访问 +```c++ + +template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== emplace_and_[c]visit -```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` +==== emplace++_++and++_[++c++]++visit +```c++ + +template + bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); +template + bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `emplace_and_cvisit` is used. +``` + +当容器中不存在等价键的元素时,插入一个用参数 `args` 构造的对象,然后使用指向新创建元素的非常量引用来调用 `f1` 。否则,使用指向等价元素的引用来调用 `f2` ;(当使用 `emplace++_++and++_++cvisit` 时,该引用为常量引用). [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +此接口仅为说明,因为 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 --- -==== Copy insert_and_[c]visit -```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); ``` +==== 复制 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +当且仅当容器中不存在具有等效键的元素时,插入 `obj`,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +在 `insert++_++and++_[++c++]++visit(obj, f1, f2)` 形式的调用中,仅当 `std::remove++_++cv++<++std::remove++_++reference++<++decltype(obj)++>++::type++>++::type` 为 `value++_++type` 时,接受 `const value++_++type&` 参数的重载才会参与重载决议。 --- -==== Move insert_and_[c]visit -```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); ``` +==== 移动 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +当且仅当容器中不存在具有等效键的元素时,插入 `obj`,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +在 `insert++_++and++_[++c++]++visit(obj, f1, f2)` 形式的调用中,仅当 `std::remove++_++reference++<++decltype(obj)++>++::type` 为 `value++_++type` 时,接受 `value++_++type&&` 参数的重载才会参与重载决议。 --- -==== Insert Iterator Range and Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` +==== 迭代器范围插入并访问 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List and Visit -```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` +==== 初始化列表插入并访问 +```c++ + +template + size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); +template + size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== try_emplace -```c++ template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); ``` +==== try++_++emplace +```c++ + +template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. +``` + +如果容器中不存在键为 `k` 的元素,则插入一个由 `k` 和 `args` 构造的元素。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This function is similiar to xref:#concurrent_flat_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此函数与 xref:#concurrent_flat_map_emplace[emplace] 类似,区别在于:若已存在具有等效键的元素,则不会构造任何 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#concurrent_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. +``` -Invalidates pointers and references to elements if a rehashing is issued. +与 xref:#concurrent_flat_map_emplace[emplace] 不同,后者只是将所有参数转发给 `value++_++type` 的构造函数。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +若触发重哈希操作,则使指向元素的指针和引用失效。 + +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类别名义时, `template++<++class K, class... Args++>++` 重载会才参与重决议析。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== try_emplace_or_[c]visit -```c++ template bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); ``` +==== try++_++emplace++_++or++_[++c++]++visit +```c++ + +template + bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); +template + bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); +template + bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +如果容器中不存在键为 `k` 的元素,则插入一个由 `k` 和 `args` 构造的元素。否则,使用指向等价元素的引用调用 `f` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若已存在具有等效键的元素,则不会构造 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first four overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // last two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -Invalidates pointers and references to elements if a rehashing is issued. +``` -The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +若触发重哈希操作,则使指向元素的指针和引用失效。 -The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 + +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class... Args, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 -- --- -==== try_emplace_and_[c]visit -```c++ template bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); ``` +==== try++_++emplace++_++and++_[++c++]++visit +```c++ + +template + bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +若容器中不存在键为 `k` 的元素,则插入由 `k` 和 `args` 构造的元素,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若已存在具有等效键的元素,则不会构造 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first four overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // last two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -Invalidates pointers and references to elements if a rehashing is issued. +``` -The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. +若触发重哈希操作,则使指向元素的指针和引用失效。 -The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +此接口仅为说明,因为 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 + +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class... Args, class F1, class F2++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 -- --- -==== insert_or_assign -```c++ template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); ``` +==== insert++_++or++_++assign +```c++ + +template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); -Inserts a new element into the table or updates an existing one by assigning to the contained value. +``` -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 + +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +如果不存在这样的元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the table as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` [horizontal] -Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== erase -```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` +==== 擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(const K& k); + +``` -Erases the element with key equivalent to `k` if it exists. +若存在键等价于 `k` 的元素,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if by Key -```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` +==== 通过键进行条件擦除 +```c++ -Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. +template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); + +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; `f` is passed a non-const reference to `x`. + + The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,本函数才会抛出异常。 +注意;; 向 `f` 传递指向 `x` 的非常量引用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `false` 时, `template++<++class K, class F++>++` 重载才会参与重载决议。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if -```c++ template size_type erase_if(F f); ``` +==== erase++_++if +```c++ + +template size_type erase_if(F f); -Successively invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. +``` + +依次使用指向表中各元素的非常量引用调用 `f` ,并删除其中使 `f` 返回 `true` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `f` 抛出异常时,才会抛出异常。 --- -==== Parallel erase_if -```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` +==== 并行条件擦除 +```c++ + +template void erase_if(ExecutionPolicy&& policy, F f); -Invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. +``` + +根据指定的执行策略语义并行化执行一下操作:使用指向表中各元素的非常量引用调用 `f` ,并删除其中使 `f` 返回 `true` 的元素。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,此重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== swap -```c++ void swap(concurrent_flat_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ + +void swap(concurrent_flat_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + +``` -Swaps the contents of the table with the parameter. +交换容器与参数的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +若 `Allocator::propagate++_++on++_++container++_++swap` 已声明, 且其 `value` 为 `true` ,则交换容器的分配器;否则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the table. +擦除容器中所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` +并发性;; 阻塞于 `++*++this` 。 --- -==== merge -```c++ template size_type merge(concurrent_flat_map& source); template size_type merge(concurrent_flat_map&& source); ``` +==== 合并 +```c++ -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +template + size_type merge(concurrent_flat_map& source); +template + size_type merge(concurrent_flat_map&& source); + +``` + +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 [horizontal] -Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. +返回;; 插入的元素数量。 +并发性;; 阻塞于 `++*++this` 和 `source` 。 --- -=== Observers +=== 观察器 + +==== get++_++allocator +``` -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The table's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The table's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The table's key equality predicate. +返回;; 容器的键相等性谓词。 --- -=== Map Operations +=== 映射操作 ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 键等价于 `k` 的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回布尔值,表示容器中是否存在键等于 `k` 的元素。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ + +float max_load_factor() const noexcept; -```c++ float max_load_factor() const noexcept; ``` +``` [horizontal] -Returns:;; Returns the table's maximum load factor. +返回;; 返回容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++map` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) -```c++ size_type max_load() const noexcept; ``` +```c++ + +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回容器在无需重哈希的情况下所能容纳的最大元素数量(假设后续无元素被删除)。 +注意;; 在构造、重哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. +``` -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -Invalidates pointers and references to elements, and changes the order of elements. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 + +使指向元素的指针和引用失效,并改变元素的顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 +--- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +void reserve(size_type n); -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. +``` -Invalidates pointers and references to elements, and changes the order of elements. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 + +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 + +使指向元素的指针和引用失效,并改变元素的顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 --- -=== Statistics +=== 统计信息 + +==== get++_++stats +```c++ -==== get_stats -```c++ stats get_stats() const; ``` +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. +返回;; 返回容器截至目前所执行的插入与查找操作的统计信息。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能被 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. +效果;; 将容器所保存的内部统计信息重置为零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能被 xref:#concurrent_flat_map_boost_unordered_enable_stats[启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the table type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1234,7 +1728,7 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-key-type__ = std::remove_const_t< @@ -1242,7 +1736,7 @@ template ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = @@ -1250,7 +1744,7 @@ template ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-to-alloc-type__ = std::pair< @@ -1258,62 +1752,93 @@ template std::tuple_element_t<1, xref:#concurrent_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const concurrent_flat_map& x, + const concurrent_flat_map& y); -==== operator -```c++ template bool operator==(const concurrent_flat_map& x, const concurrent_flat_map& y); ``` +``` -Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `true` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const concurrent_flat_map& x, const concurrent_flat_map& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const concurrent_flat_map& x, + const concurrent_flat_map& y); + +``` -Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,并且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(concurrent_flat_map& x, concurrent_flat_map& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + void swap(concurrent_flat_map& x, + concurrent_flat_map& y) + noexcept(noexcept(x.swap(y))); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- x.xref:#concurrent_flat_map_swap[swap](y); ----- --- -=== erase_if -```c++ template typename concurrent_flat_map::size_type erase_if(concurrent_flat_map& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename concurrent_flat_map::size_type + erase_if(concurrent_flat_map& c, Predicate pred); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- c.xref:#concurrent_flat_map_erase_if[erase_if](pred); ----- -=== Serialization +=== 序列化 -``concurrent_flat_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`concurrent++_++flat++_++map` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an concurrent_flat_map to an archive +==== 将concurrent++_++flat++_++map保存到归档 -Saves all the elements of a `concurrent_flat_map` `x` to an archive (XML archive) `ar`. +将 `concurrent++_++flat++_++map` 容器 `x` 的所有元素保存到归档(XML归档) `ar` 中。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 +并发性;; 阻塞于 `x` 。 --- -==== Loading an concurrent_flat_map from an archive +==== 从归档加载concurrent++_++flat++_++map -Deletes all preexisting elements of a `concurrent_flat_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_flat_map` `other` saved to the storage read by `ar`. +删除 `concurrent++_++flat++_++map` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `concurrent++_++flat++_++map` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +并发性;; 阻塞于 `x` 。 diff --git a/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc index 8f58914..823776e 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_flat_set_zh_Hans.adoc @@ -1,17 +1,17 @@ -[#concurrent_flat_set] -== Class Template concurrent_flat_set +[#concurrent_flat_set] +== 类模板 concurrent++_++flat++_++set :idprefix: concurrent_flat_set_ -`boost::concurrent_flat_set` — A hash table that stores unique values and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. +`boost::concurrent++_++flat++_++set` —— 一种存储唯一值的哈希表,它支持并发的元素插入、删除、查找及访问操作,且无需外部同步机制。 -Even though it acts as a container, `boost::concurrent_flat_set` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access is done through user-provided _visitation functions_ that are passed to `concurrent_flat_set` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. +尽管 `boost::concurrent++_++flat++_++set` 具备容器特性,但它并不符合 C{plus}{plus}标准中的 https://en.cppreference.com/w/cpp/named_req/Container[容器] 概念。具体而言,该容器未提供迭代器及相关操作(如 `begin` 、 `end` 等)。元素访问通过用户提供的__访问函数__实现,这些函数被传递至 `concurrent++_++flat++_++set` 操作中,并在其内部以受控方式执行。这种基于访问机制的 API 设计能够有效支持低争用的并发应用场景。 -The internal data structure of `boost::concurrent_flat_set` is similar to that of `boost::unordered_flat_set`. As a result of its using open-addressing techniques, `value_type` must be move-constructible and pointer stability is not kept under rehashing. +`boost::concurrent++_++flat++_++set` 的内部数据结构类似于 `boost::unordered++_++flat++_++set` 。由于其采用开放寻址技术, `value++_++type` 必须满足可移动构造要求,且在重哈希过程中无法保持指针稳定性。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_concurrent_flat_set.adoc[``] @@ -24,7 +24,7 @@ namespace unordered { class Allocator = std::allocator> class concurrent_flat_set { public: - // types + // 类型 using key_type = Key; using value_type = Key; using init_type = Key; @@ -40,10 +40,10 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled] - // constants + // 常量 static constexpr size_type xref:#concurrent_flat_set_constants[bulk_visit_size] = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#concurrent_flat_set_default_constructor[concurrent_flat_set](); explicit xref:#concurrent_flat_set_bucket_count_constructor[concurrent_flat_set](size_type n, const hasher& hf = hasher(), @@ -90,7 +90,7 @@ namespace unordered { allocator_type xref:#concurrent_flat_set_get_allocator[get_allocator]() const noexcept; - // visitation + // 访问 template size_t xref:#concurrent_flat_set_cvisit[visit](const key_type& k, F f); template size_t xref:#concurrent_flat_set_cvisit[visit](const key_type& k, F f) const; template size_t xref:#concurrent_flat_set_cvisit[cvisit](const key_type& k, F f) const; @@ -125,12 +125,12 @@ namespace unordered { template bool xref:#concurrent_flat_set_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#concurrent_flat_set_empty[empty]() const noexcept; size_type xref:#concurrent_flat_set_size[size]() const noexcept; size_type xref:#concurrent_flat_set_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template bool xref:#concurrent_flat_set_emplace[emplace](Args&&... args); bool xref:#concurrent_flat_set_copy_insert[insert](const value_type& obj); bool xref:#concurrent_flat_set_move_insert[insert](value_type&& obj); @@ -190,11 +190,11 @@ namespace unordered { template size_type xref:#concurrent_flat_set_merge[merge](concurrent_flat_set&& source); - // observers + // 观察器 hasher xref:#concurrent_flat_set_hash_function[hash_function]() const; key_equal xref:#concurrent_flat_set_key_eq[key_eq]() const; - // set operations + // 集合操作 size_type xref:#concurrent_flat_set_count[count](const key_type& k) const; template size_type xref:#concurrent_flat_set_count[count](const K& k) const; @@ -202,10 +202,10 @@ namespace unordered { template bool xref:#concurrent_flat_set_contains[contains](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#concurrent_flat_set_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#concurrent_flat_set_load_factor[load_factor]() const noexcept; float xref:#concurrent_flat_set_max_load_factor[max_load_factor]() const noexcept; void xref:#concurrent_flat_set_set_max_load_factor[max_load_factor](float z); @@ -213,12 +213,12 @@ namespace unordered { void xref:#concurrent_flat_set_rehash[rehash](size_type n); void xref:#concurrent_flat_set_reserve[reserve](size_type n); - // statistics (if xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]) + // 统计(若启用) stats xref:#concurrent_flat_set_get_stats[get_stats]() const; void xref:#concurrent_flat_set_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -263,118 +263,143 @@ namespace unordered { concurrent_flat_set(std::initializer_list, typename xref:#concurrent_flat_set_deduction_guides[__see below__]::size_type, Hash, Allocator) -> concurrent_flat_set, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container -and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +|`Key` 必须满足 +https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] +到容器中的要求,且需满足从容器中 +https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the table's value type. -`std::allocator_traits::pointer` and `std::allocator_traits::const_pointer` must be convertible to/from `value_type*` and `const value_type*`, respectively. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同。 `std::allocator++_++traits++<++Allocator++>++::pointer` +和 `std::allocator++_++traits++<++Allocator++>++::const++_++pointer` +必须可分别转换为 `value++_++type++*++` 和 +`const value++_++type++*++` ,且可从这些类型转换而来。 |=== -The elements of the table are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素存储在内部的__桶数组__中。元素根据其哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 进行调整。容器的__负载因子__(元素数量与桶数量的比值)永远不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Concurrency Requirements and Guarantees +=== 并发要求与保证 -Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: +要求对同一 `Hash` 或 `Pred` 常量实例并发调用 `operator()` 时不得引入数据竞争。对于 `Alloc` (即 `Allocator` 或其重绑定后的任意分配器类型),在同一实例 `al` 上并发调用以下操作时不得引入数据竞争: -* Copy construction from `al` of an allocator rebound from `Alloc` -* `std::allocator_traits::allocate` -* `std::allocator_traits::deallocate` -* `std::allocator_traits::construct` -* `std::allocator_traits::destroy` +* 从 `al` 复制构造重新绑定的分配器 +* `std::allocator++_++traits++<++Alloc++>++::allocate` +* `std::allocator++_++traits++<++Alloc++>++::deallocate` +* `std::allocator++_++traits++<++Alloc++>++::construct` +* `std::allocator++_++traits++<++Alloc++>++::destroy` -In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. +通常而言,若 `Hash` 、 `Pred` 和 `Allocator` 这些类型不包含状态,或其操作仅涉及对内部数据成员的常量访问,即可满足上述要求。 -With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_flat_set` do not introduce data races — that is, they are thread-safe. +除析构操作外,对同一个 `concurrent++_++flat++_++set` 实例并发调用任何操作都不会引发数据竞争——即这些操作是线程安全的。 -If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_flat_set`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_flat_set` execute sequentially in a multithreaded scenario. +若操作 *op* 显式指定为__阻塞于__ 容器 `x` (其中 `x` 是 `boost::concurrent++_++flat++_++set` 的实例),则先前对 `x` 的阻塞操作将与 *op* 同步。因此,在多线程场景下,对同一 `concurrent++_++flat++_++set` 的阻塞操作将按顺序执行。 -An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. +若某个操作仅在触发内部重哈希时才会阻塞于 _`x`_,则称该操作__阻塞于 _`x`_ 的重哈希过程__。 -When executed internally by a `boost::concurrent_flat_set`, the following operations by a user-provided visitation function on the element passed do not introduce data races: +当由 `boost::concurrent++_++flat++_++set` 内部执行时,用户提供的访问函数对传入元素的以下操作不会引发数据竞争: -* Read access to the element. -* Non-mutable modification of the element. -* Mutable modification of the element: -Any `boost::concurrent_flat_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. +* 对元素的读取访问。 +* 对元素的非可变修改。 +* 对元素的可变修改: + ** 在容器接受两个访问函数的操作中,此条件始终适用于第一个访问函数。 + ** 在名称不包含 `cvisit` 的非常量容器函数中,此条件适用于最后一个(或唯一一个)访问函数。 -Visitation functions executed by a `boost::concurrent_flat_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_flat_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. +任何插入或修改元素 `e` 的 `boost::concurrent++_++flat++_++set` 操作都会与在 `e` 的内部调用的访问函数同步。 ---- +由 `boost::concurrent++_++flat++_++set` `x` 执行的访问函数不允许调用 `x` 上的任何操作;若并发未完成操作不直接或间接访问 `x` ,则允许调用不同 `boost::concurrent++_++flat++_++set` 实例 `y` 上的操作。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` +==== `BOOST++_++UNORDERED++_++DISABLE++_++REENTRANCY++_++CHECK` -In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. +在调试版本中(更准确地说,当未定义 link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST++_++ASSERT++_++IS++_++VOID`] 时),系统会检测__容器重入__行为(即在访问 `m` 元素的函数内部非法调用 `m` 上的操作),并通过 `BOOST++_++ASSERT++_++MSG` 发出信号。若需关注运行时速度,可通过全局定义此宏来禁用该功能。 --- -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. +全局定义此宏以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低多数操作的总体性能。 --- -=== Constants +=== 常量 + +```cpp + +static constexpr size_type bulk_visit_size; + +``` + +在 xref:#concurrent_flat_set_bulk_visit[批量访问] 操作中内部使用的块大小。 -```cpp static constexpr size_type bulk_visit_size; ``` +=== 构造函数 -Chunk size internally used in xref:concurrent_flat_set_bulk_visit[bulk visit] operations. +==== 默认构造函数 +```c++ -=== Constructors +concurrent_flat_set(); -==== Default Constructor -```c++ concurrent_flat_set(); ``` +``` -Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +构造一个空容器,使用 `hasher()` 作为哈希函数, `key++_++equal()` 作为键相等性谓词, `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit concurrent_flat_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +explicit concurrent_flat_set(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_set(InputIterator f, InputIterator l, @@ -384,85 +409,115 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ concurrent_flat_set(concurrent_flat_set const& other); ``` +==== 复制构造函数 +```c++ + +concurrent_flat_set(concurrent_flat_set const& other); -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. +要求;; `value++_++type` 必须满足可复制构造要求 +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor -```c++ concurrent_flat_set(concurrent_flat_set&& other); ``` +==== 移动构造函数 +```c++ + +concurrent_flat_set(concurrent_flat_set&& other); -The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +``` + +移动构造函数。该操作将 `other` 的内部桶数组直接转移至新容器,其哈希函数、相等性谓词以及分配器均通过移动构造方式从 `other` 转移而来。若统计功能 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] ,则同时转移 `other` 的内部统计信息并调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template concurrent_flat_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + concurrent_flat_set(InputIterator f, InputIterator l, const allocator_type& a); -Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit concurrent_flat_set(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit concurrent_flat_set(Allocator const& a); -Constructs an empty table, using allocator `a`. +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ concurrent_flat_set(concurrent_flat_set const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +concurrent_flat_set(concurrent_flat_set const& other, Allocator const& a); -Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +``` + +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor with Allocator -```c++ concurrent_flat_set(concurrent_flat_set&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +concurrent_flat_set(concurrent_flat_set&& other, Allocator const& a); -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +``` + +若 `a == other.get++_++allocator()` ,则 `other` 中的元素直接转移至新的容器;否则,元素从 `other` 移动构造。哈希函数和相等性谓词从 `other` 移动构造,分配器从 `a` 复制构造。若统计功能 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] ,当且仅当 `a == other.get++_++allocator()` 时,同步转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor from unordered_flat_set +==== 从 unordered++_++flat++_++set 的移动构造函数 + +```c++ + +concurrent_flat_set(unordered_flat_set&& other); -```c++ concurrent_flat_set(unordered_flat_set&& other); ``` +``` -Move construction from a xref:#unordered_flat_set[`unordered_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +从 xref:#unordered_flat_set[`unordered_flat_set`][`unordered++_++flat++_++set`] 进行移动构造。 `other` 的内部桶数组直接转移至新容器。其哈希函数、相等性谓词和分配器从 `other` 移动构造。若统计功能 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; O(`bucket_count()`) +复杂度;; O(`bucket++_++count()`) --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- concurrent_flat_set(std::initializer_list il, size_type n = _implementation-defined_ @@ -471,714 +526,1115 @@ concurrent_flat_set(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ concurrent_flat_set(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +concurrent_flat_set(size_type n, allocator_type const& a); + +``` -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ concurrent_flat_set(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +concurrent_flat_set(size_type n, hasher const& hf, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_flat_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ + +concurrent_flat_set(std::initializer_list il, const allocator_type& a); -```c++ concurrent_flat_set(std::initializer_list il, const allocator_type& a); ``` +``` -Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 -```c++ concurrent_flat_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +```c++ -Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +concurrent_flat_set(std::initializer_list il, size_type n, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ -```c++ concurrent_flat_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +concurrent_flat_set(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~concurrent_flat_set(); ``` +~concurrent_flat_set(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ concurrent_flat_set& operator=(concurrent_flat_set const& other); ``` +concurrent_flat_set& operator=(concurrent_flat_set const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Move Assignment -```c++ concurrent_flat_set& operator=(concurrent_flat_set&& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +concurrent_flat_set& operator=(concurrent_flat_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value); + +``` +移动赋值运算符。该操作会销毁容器中先前存在的元素,交换 `other` +的哈希函数和谓词,若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则将 `other` 的内部桶数组直接转移至 +`++*++this` ;否则插入 `other` +元素的移动构造副本。若统计功能 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] ,当且仅当最终分配器与 +`other.get++_++allocator()` 相等时,转移内部统计信息,并始终调用 +`other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `*this` and `other`. +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Initializer List Assignment -```c++ concurrent_flat_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +concurrent_flat_set& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All previously existing elements are destroyed. +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 。 --- -=== Visitation +=== 访问操作 + +==== ++[++c++]++visit( ++[++c++]++ 访问) + +```c++ -==== [c]visit +template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; -```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` +``` -If an element `x` exists with key equivalent to `k`, invokes `f` with a const reference to `x`. +若存在键等价于 `k` 的元素 `x` ,则以 `x` 的常量引用调用 `f` 。 [horizontal] -Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被访问的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Bulk visit +==== 批量访问 -```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` +```c++ -For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a const reference to `x`. +template + size_t visit(FwdIterator first, FwdIterator last, F f); +template + size_t visit(FwdIterator first, FwdIterator last, F f) const; +template + size_t cvisit(FwdIterator first, FwdIterator last, F f) const; -Although functionally equivalent to individually invoking xref:concurrent_flat_set_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_flat_set_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. +``` + +对范围 ++[++`first`, `last`) 内的每个元素 `k` ,若容器中存在键等价于 `k` 的元素 `x` ,则使用指向 `x` 的常量引用调用 `f` 。 + +尽管在功能上等同于对每个键单独调用 xref:#concurrent_flat_set_cvisit[`++[++c++]++visit`] ,但批量访问因内部流线优化而通常具有更快的执行速度。建议 `std::distance(first,last)` 至少达到 xref:#concurrent_flat_set_constants[`bulk++_++visit++_++size`] 以获得性能提升:超过此大小后,性能预计不再提升。 [horizontal] -Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. +要求;; `FwdIterator` 需满足 https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator] 要求(C{plus}{plus}11 至 C{plus}{plus}17)或符合 https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward++_++iterator] 规范(C{plus}{plus}20 及更高版本)。对于 `K` = `std::iterator++_++traits++<++FwdIterator++>++::value++_++type` ,需满足以下条件之一: `K` 与 `key++_++type` 类型相同,或 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名。对于后一种情况,该库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 +返回;; 被访问的元素数量。 --- -==== [c]visit_all +==== ++[++c++]++visit++_++all + +```c++ + +template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; -```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` +``` -Successively invokes `f` with const references to each of the elements in the table. +依次使用指向容器中各元素的常量引用调用 `f` 。 [horizontal] -Returns:;; The number of elements visited. +返回;; 被访问的元素数量。 --- -==== Parallel [c]visit_all +==== 并行 ++[++c++]++visit++_++all -```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` +```c++ -Invokes `f` with const references to each of the elements in the table. Execution is parallelized according to the semantics of the execution policy specified. +template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; + +``` + +根据指定的执行策略语义并行化执行操作;使用指向容器中各元素的常量引用调用 `f` 。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== [c]visit_while +==== ++[++c++]++visit++_++while + +```c++ -```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` +template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; -Successively invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. +``` + +依次使用指向容器中每个元素的常量引用调用 `f` ,直到 `f` 返回 `false` ,或所有元素均被访问。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 --- -==== Parallel [c]visit_while +==== 并行 ++[++c++]++visit++_++while + +```c++ -```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` +template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; -Invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. Execution is parallelized according to the semantics of the execution policy specified. +``` + +根据指定的执行策略语义并行化执行操作;使用指向容器中各元素的常量引用调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问完毕。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 + ++ +并行化意味着执行不一定会因 `f` 返回 `false` 而立即结束,因此系统可能继续使用其他元素调用 `f` (即使其返回值同样为 `false` )。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ -```c++ size_type size() const noexcept; ``` +size_type size() const noexcept; + +``` [horizontal] -Returns:;; The number of elements in the table. +返回;; 容器中的元素数量。 [horizontal] -Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. +注意;; 在存在并发插入操作的情况下,返回值可能无法准确反映执行完成后容器的真实大小。 --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回;; 返回该容器可能包含的最大元素数量 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template bool emplace(Args&&... args); -==== emplace -```c++ template bool emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. +当且仅当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Copy Insert -```c++ bool insert(const value_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +bool insert(const value_type& obj); + +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Move Insert -```c++ bool insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +bool insert(value_type&& obj); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Transparent Insert -```c++ template bool insert(K&& k); ``` +==== 透明插入 +```c++ -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +template bool insert(K&& k); + +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,此重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range -```c++ template size_type insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template size_type insert(InputIterator first, InputIterator last); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_set_emplace[emplace](*first++); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List -```c++ size_type insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ + +size_type insert(std::initializer_list il); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_set_insert_iterator_range[insert](il.begin(), il.end()); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +==== emplace++_++or++_[++c++]++visit +```c++ + +template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +``` + +当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 --- -==== Copy insert_or_[c]visit -```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); ``` +==== 复制 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 插入到容器中;否则,以该等价元素的常量引用为参数调用函数 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Move insert_or_[c]visit -```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); ``` +==== 移动 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +当且仅当容器中不存在等价键的元素时,将 `obj` 插入到容器中;否则,以该等价元素的常量引用为参数调用函数 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Transparent insert_or_[c]visit -```c++ template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); ``` +==== 透明 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); + +``` -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +当且仅当容器中不存在具有等效键的元素时,插入由 `std::forward++<++K++>++(k)` 构造的元素;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,这些重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range or Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` +==== 迭代器范围插入或访问 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + size_type insert_or_visit(InputIterator first, InputIterator last, F f); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_set_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List or Visit -```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` +==== 初始化列表插入或访问 +```c++ + +template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_set_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== emplace_and_[c]visit -```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` +==== emplace++_++and++_[++c++]++visit +```c++ -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +template + bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); +template + bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); + +``` + +当容器中不存在具有等效键的元素时,插入由参数 `args` 构造的对象,并使用指向新创建元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +此接口仅为说明,因为 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 --- -==== Copy insert_and_[c]visit -```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); ``` +==== 复制 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器中,并以新元素的常量引用为参数调用函数 `f1` ;否则,以该等价元素的常量引用为参数调用函数 `f2` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Move insert_and_[c]visit -```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); ``` +==== 移动 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器中,并以新元素的常量引用为参数调用函数 `f1` ;否则,以该等价元素的常量引用为参数调用函数 `f2` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 --- -==== Transparent insert_and_[c]visit -```c++ template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); ``` +==== 透明 insert++_++and++_[++c++]++visit(透明插入并 ++[++c++]++ 访问) +```c++ + +template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在具有等效键的元素时,插入由 `std::forward++<++K++>++(k)` 构造的元素,并使用指向新创建元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. + + These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若触发重哈希操作,则使指向元素的指针和引用失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,这些重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range and Visit -```c++ template size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` +==== 迭代器范围插入并访问 +```c++ + +template + size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); +template + size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_flat_set_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List and Visit -```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` +==== 初始化列表插入并访问 +```c++ + +template + size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); +template + size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_flat_set_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== erase -```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` +==== 擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(const K& k); + +``` -Erases the element with key equivalent to `k` if it exists. +若存在键等价于 `k` 的元素,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if by Key -```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` +==== 通过键进行条件擦除 +```c++ -Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. +template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); + +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,本函数才会抛出异常。 +注意;; 仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `false` 时, `template++<++class K, class F++>++` 重载才会参与重载决议。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if -```c++ template size_type erase_if(F f); ``` +==== erase++_++if +```c++ + +template size_type erase_if(F f); + +``` -Successively invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. +依次使用指向容器中各元素的引用调用 `f` ,并擦除其中使 `f` 返回 `true` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `f` 抛出异常时,才会抛出异常。 --- -==== Parallel erase_if -```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` +==== 并行条件擦除 +```c++ -Invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. +template void erase_if(ExecutionPolicy&& policy, F f); + +``` + +使用指向容器中每个元素的引用调用 `f` ,并擦除其中使 `f` 返回 `true` 的元素。该执行根据指定的执行策略语义并行化。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,此重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== swap -```c++ void swap(concurrent_flat_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ + +void swap(concurrent_flat_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); -Swaps the contents of the table with the parameter. +``` -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +交换容器与参数的内容。 + +若 `Allocator::propagate++_++on++_++container++_++swap` 已声明, 且其 `value` 为 `true` ,则交换容器的分配器;否则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; -Erases all elements in the table. +``` + +擦除容器中所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` +并发性;; 阻塞于 `++*++this` 。 --- -==== merge -```c++ template size_type merge(concurrent_flat_set& source); template size_type merge(concurrent_flat_set&& source); ``` +==== 合并 +```c++ + +template + size_type merge(concurrent_flat_set& source); +template + size_type merge(concurrent_flat_set&& source); -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +``` + +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 [horizontal] -Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. +返回;; 插入的元素数量。 +并发性;; 阻塞于 `++*++this` 和 `source` 。 --- -=== Observers +=== 观察器 + +==== get++_++allocator +``` -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The table's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The table's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The table's key equality predicate. +返回;; 容器的键相等性谓词。 --- -=== Set Operations +=== 集合操作 ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 键等价于 `k` 的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回布尔值,表示容器中是否存在键等于 `k` 的元素。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the table's maximum load factor. +返回;; 返回容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++set` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) + +```c++ -```c++ size_type max_load() const noexcept; ``` +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回容器在无需重哈希的情况下所能容纳的最大元素数量(假设后续无元素被删除)。 +注意;; 在构造、重哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 -Invalidates pointers and references to elements, and changes the order of elements. +使指向元素的指针和引用失效,并改变元素的顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 +--- + +==== 保留 +```c++ -==== reserve -```c++ void reserve(size_type n); ``` +void reserve(size_type n); -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +``` -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 -Invalidates pointers and references to elements, and changes the order of elements. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 + +使指向元素的指针和引用失效,并改变元素的顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 --- -=== Statistics +=== 统计信息 + +==== get++_++stats +```c++ -==== get_stats -```c++ stats get_stats() const; ``` +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. +返回;; 返回容器截至目前所执行的插入与查找操作的统计信息。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 被 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. +效果;; 将容器所保存的内部统计信息重置为零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 被 xref:#concurrent_flat_set_boost_unordered_enable_stats[启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const concurrent_flat_set& x, + const concurrent_flat_set& y); -==== operator -```c++ template bool operator==(const concurrent_flat_set& x, const concurrent_flat_set& y); ``` +``` -Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `true` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const concurrent_flat_set& x, const concurrent_flat_set& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const concurrent_flat_set& x, + const concurrent_flat_set& y); + +``` -Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,并且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(concurrent_flat_set& x, concurrent_flat_set& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + void swap(concurrent_flat_set& x, + concurrent_flat_set& y) + noexcept(noexcept(x.swap(y))); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- x.xref:#concurrent_flat_set_swap[swap](y); ----- --- -=== erase_if -```c++ template typename concurrent_flat_set::size_type erase_if(concurrent_flat_set& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename concurrent_flat_set::size_type + erase_if(concurrent_flat_set& c, Predicate pred); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- c.xref:#concurrent_flat_set_erase_if[erase_if](pred); ----- -=== Serialization +=== 序列化 -``concurrent_flat_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +可通过本库提供的 API ,借助 link:../../../../../serialization/index.html[Boost.Serialization] 实现档归档/检索 `concurrent++_++flat++_++set` 。同时支持常规格式与 XML 格式的归档文件。 -==== Saving an concurrent_flat_set to an archive +==== 将 concurrent++_++flat++_++set 保存到归档 -Saves all the elements of a `concurrent_flat_set` `x` to an archive (XML archive) `ar`. +将 `concurrent++_++flat++_++set` 容器 `x` 的所有元素保存到归档(XML 归档) `ar` 中。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 +并发性;; 阻塞于 `x` 。 --- -==== Loading an concurrent_flat_set from an archive +==== 从归档加载 concurrent++_++flat++_++set -Deletes all preexisting elements of a `concurrent_flat_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_flat_set` `other` saved to the storage read by `ar`. +删除 `concurrent++_++flat++_++set` 容器 `x` 中的所有现有元素,并从归档 `ar` (XML格式归档)中读取原始 `concurrent++_++flat++_++set` 容器 `other` 保存的元素副本并插入到 `x` 。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +并发性;; 阻塞于 `x` 。 diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc index 6a7fcdc..bb5d036 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_node_map_zh_Hans.adoc @@ -1,19 +1,19 @@ -[#concurrent_node_map] -== Class Template concurrent_node_map +[#concurrent_node_map] +== 类模板 concurrent++_++node++_++map :idprefix: concurrent_node_map_ -`boost::concurrent_node_map` — A node-based hash table that associates unique keys with another value and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. +`boost::concurrent++_++node++_++map` —— 一种基于节点的哈希表,用于建立唯一键与对应值的关联,并支持在无外部同步机制的情况下并发执行元素插入、擦除、查找和访问操作。 -Even though it acts as a container, `boost::concurrent_node_map` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access and modification are done through user-provided _visitation functions_ that are passed to `concurrent_node_map` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. +尽管 `boost::concurrent++_++node++_++map` 的行为类似于容器,但它并不符合标准 C{plus}{plus} 的 https://en.cppreference.com/w/cpp/named_req/Container[容器] 概念模型。具体而言,它不提供迭代器及相关操作(如 `begin` 、 `end` 等)。元素的访问和修改通过用户提供的__访问函数__来实现,这些函数被传递至 `concurrent++_++node++_++map` 的操作中,并在其内部以受控方式执行。这种基于访问的 API 设计能够支持低争用的并发应用场景。 -The internal data structure of `boost::concurrent_node_map` is similar to that of `boost::unordered_node_map`. Unlike `boost::concurrent_flat_map`, pointer stability and node handling functionalities are provided, at the expense of potentially lower performance. +`boost::concurrent++_++node++_++map` 的内部数据结构与 `boost::unordered++_++node++_++map` 类似。与 `boost::concurrent++_++flat++_++map` 不同,它提供了指针稳定性和节点处理功能,但代价是可能带来性能上的损失。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- -// #include xref:reference/header_concurrent_node_map.adoc[``] +// #include namespace boost { namespace unordered { @@ -25,7 +25,7 @@ namespace unordered { class Allocator = std::allocator>> class concurrent_node_map { public: - // types + // 类型 using key_type = Key; using mapped_type = T; using value_type = std::pair; @@ -48,10 +48,10 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled] - // constants + // 常量 static constexpr size_type xref:#concurrent_node_map_constants[bulk_visit_size] = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#concurrent_node_map_default_constructor[concurrent_node_map](); explicit xref:#concurrent_node_map_bucket_count_constructor[concurrent_node_map](size_type n, const hasher& hf = hasher(), @@ -99,7 +99,7 @@ namespace unordered { allocator_type xref:#concurrent_node_map_get_allocator[get_allocator]() const noexcept; - // visitation + // 访问 template size_t xref:#concurrent_node_map_cvisit[visit](const key_type& k, F f); template size_t xref:#concurrent_node_map_cvisit[visit](const key_type& k, F f) const; template size_t xref:#concurrent_node_map_cvisit[cvisit](const key_type& k, F f) const; @@ -134,12 +134,12 @@ namespace unordered { template bool xref:#concurrent_node_map_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#concurrent_node_map_empty[empty]() const noexcept; size_type xref:#concurrent_node_map_size[size]() const noexcept; size_type xref:#concurrent_node_map_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template bool xref:#concurrent_node_map_emplace[emplace](Args&&... args); bool xref:#concurrent_node_map_copy_insert[insert](const value_type& obj); bool xref:#concurrent_node_map_copy_insert[insert](const init_type& obj); @@ -253,11 +253,11 @@ namespace unordered { template size_type xref:#concurrent_node_map_merge[merge](concurrent_node_map&& source); - // observers + // 观察器 hasher xref:#concurrent_node_map_hash_function[hash_function]() const; key_equal xref:#concurrent_node_map_key_eq[key_eq]() const; - // map operations + // 映射操作 size_type xref:#concurrent_node_map_count[count](const key_type& k) const; template size_type xref:#concurrent_node_map_count[count](const K& k) const; @@ -265,10 +265,10 @@ namespace unordered { template bool xref:#concurrent_node_map_contains[contains](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#concurrent_node_map_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#concurrent_node_map_load_factor[load_factor]() const noexcept; float xref:#concurrent_node_map_max_load_factor[max_load_factor]() const noexcept; void xref:#concurrent_node_map_set_max_load_factor[max_load_factor](float z); @@ -276,12 +276,12 @@ namespace unordered { void xref:#concurrent_node_map_rehash[rehash](size_type n); void xref:#concurrent_node_map_reserve[reserve](size_type n); - // statistics (if xref:concurrent_node_map_boost_unordered_enable_stats[enabled]) + // 统计(若启用) stats xref:#concurrent_node_map_get_stats[get_stats]() const; void xref:#concurrent_node_map_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -331,109 +331,113 @@ namespace unordered { Hash, Allocator) -> concurrent_node_map, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -.2+|`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] -into the table from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the table. +|_键_ +.2+|`std::pair++<++const Key, T++>++` 必须能够从任何可转换为该类型的 +`std::pair` +对象 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到容器中,并且必须支持从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[擦除] 。 |_T_ |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the table's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同。支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The element nodes of the table are held into an internal _bucket array_. An node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素节点存储在内部的__桶数组__中。节点根据其元素的哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 进行调整。容器的__负载因子__(元素数量与桶数量的比值)永远不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Concurrency Requirements and Guarantees +=== 并发要求与保证 -Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: +要求对同一 `Hash` 或 `Pred` 常量实例并发调用 `operator()` 时不得引入数据竞争。对于 `Alloc` (即 `Allocator` 或其重绑定后的任意分配器类型),在同一实例 `al` 上并发调用以下操作时不得引入数据竞争: -* Copy construction from `al` of an allocator rebound from `Alloc` -* `std::allocator_traits::allocate` -* `std::allocator_traits::deallocate` -* `std::allocator_traits::construct` -* `std::allocator_traits::destroy` +* 从 `al` 复制构造重新绑定的分配器 +* `std::allocator++_++traits++<++Alloc++>++::allocate` +* `std::allocator++_++traits++<++Alloc++>++::deallocate` +* `std::allocator++_++traits++<++Alloc++>++::construct` +* `std::allocator++_++traits++<++Alloc++>++::destroy` -In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. +通常而言,若 `Hash` 、 `Pred` 和 `Allocator` 这些类型不包含状态,或其操作仅涉及对内部数据成员的常量访问,即可满足上述要求。 -With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_node_map` do not introduce data races — that is, they are thread-safe. +除析构操作外,对同一个 `concurrent++_++node++_++map` 实例并发调用任何操作都不会引入数据竞争——即这些操作是线程安全的。 -If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_node_map`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_node_map` execute sequentially in a multithreaded scenario. +如果某个操作 *op* 被显式指定为__阻塞于__ `x` (其中 `x` 是 `boost::concurrent++_++node++_++map` 的实例),则先前对 `x` 的阻塞操作将与 *op* 同步。因此,在多线程场景中,对同一 `concurrent++_++node++_++map` 的阻塞操作将按顺序执行。 -An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. +若某个操作仅在触发内部重哈希时才会阻塞于 _`x`_,则称该操作__阻塞于 _`x`_ 的重哈希过程__。 -When executed internally by a `boost::concurrent_node_map`, the following operations by a user-provided visitation function on the element passed do not introduce data races: +当由 `boost::concurrent++_++node++_++map` 在内部执行时,用户提供的访问函数对传递的元素执行以下操作不会引入数据竞争: -* Read access to the element. -* Non-mutable modification of the element. -* Mutable modification of the element: -Any `boost::concurrent_node_map operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. +* 对元素的读取访问。 +* 对元素的非可变修改。 +* 对元素的可变修改: + ** 在容器接受两个访问函数的操作中,此条件始终适用于第一个访问函数。 + ** 在名称不包含 `cvisit` 的非常量容器函数中,此条件适用于最后一个(或唯一一个)访问函数。 -Visitation functions executed by a `boost::concurrent_node_map` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_map` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. +任何插入或修改元素 `e` 的 `boost::concurrent++_++node++_++map 操作 ` 都会与对 `e` 执行的内部访问函数的调用同步。 ---- +由 `boost::concurrent++_++node++_++map` 实例 `x` 执行的访问函数不允许调用 `x` 上的任何操作;仅当对另一 `boost::concurrent++_++node++_++map` 实例 `y` 的并发未完成操作不会直接或间接访问 `x` 时,才会允许调用 `y` 上的操作。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` +==== `BOOST++_++UNORDERED++_++DISABLE++_++REENTRANCY++_++CHECK` -In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. +在调试版本中(更准确地说,当未定义 link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST++_++ASSERT++_++IS++_++VOID`] 时),系统会检测__容器重入__行为(即在访问 `m` 元素的函数内部非法调用 `m` 上的操作),并通过 `BOOST++_++ASSERT++_++MSG` 发出信号。若需关注运行时速度,可通过全局定义此宏来禁用该功能。 --- -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. +全局定义此宏以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低多数操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted table elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存提取的表元素的类,建模为 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -443,42 +447,59 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `NodeType` = `node_type`. +其中 `NodeType` = `node++_++type` 。 --- -=== Constants +=== 常量 + +```cpp + +static constexpr size_type bulk_visit_size; -```cpp static constexpr size_type bulk_visit_size; ``` +``` -Chunk size internally used in xref:concurrent_node_map_bulk_visit[bulk visit] operations. +在 xref:concurrent_node_map_bulk_visit[批量访问] 操作中内部使用的数据块大小。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ concurrent_node_map(); ``` +==== 默认构造函数 +```c++ -Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +concurrent_node_map(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数, `key++_++equal()` 作为键相等性谓词, `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit concurrent_node_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit concurrent_node_map(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_map(InputIterator f, InputIterator l, @@ -488,85 +509,115 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ concurrent_node_map(concurrent_node_map const& other); ``` +==== 复制构造函数 +```c++ + +concurrent_node_map(concurrent_node_map const& other); + +``` -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. +要求;; `value++_++type` 必须满足可复制构造要求 +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor -```c++ concurrent_node_map(concurrent_node_map&& other); ``` +==== 移动构造函数 +```c++ + +concurrent_node_map(concurrent_node_map&& other); + +``` -The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +移动构造函数。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器从 `other` 移动构造。若统计功能 xref:#concurrent_node_map_boost_unordered_enable_stats[已启用] ,则同步转移 `other` 的内部统计信息并调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template concurrent_node_map(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +template + concurrent_node_map(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit concurrent_node_map(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit concurrent_node_map(Allocator const& a); + +``` -Constructs an empty table, using allocator `a`. +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ concurrent_node_map(concurrent_node_map const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ -Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +concurrent_node_map(concurrent_node_map const& other, Allocator const& a); + +``` + +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor with Allocator -```c++ concurrent_node_map(concurrent_node_map&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +concurrent_node_map(concurrent_node_map&& other, Allocator const& a); -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +``` + +若 `a == other.get++_++allocator()` ,则 `other` 的元素直接转移至新容器;否则,元素从 `other` 移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。若统计功能 xref:#concurrent_node_map_boost_unordered_enable_stats[已启用] ,则当 `a == other.get++_++allocator()` 时同步转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor from unordered_node_map +==== 从 unordered++_++node++_++map 的移动构造函数 + +```c++ -```c++ concurrent_node_map(unordered_node_map&& other); ``` +concurrent_node_map(unordered_node_map&& other); -Move construction from a xref:#unordered_node_map[`unordered_node_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +``` + +从 xref:#unordered_node_map[`unordered_node_map`][`unordered++_++node++_++map`] 进行移动构造。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器从 `other` 移动构造。若统计功能 xref:#concurrent_node_map_boost_unordered_enable_stats[已启用] ,则同时转移 `other` 的内部统计信息并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; O(`bucket_count()`) +复杂度;; O(`bucket++_++count()`) --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- concurrent_node_map(std::initializer_list il, size_type n = _implementation-defined_ @@ -575,762 +626,1220 @@ concurrent_node_map(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ concurrent_node_map(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +concurrent_node_map(size_type n, allocator_type const& a); + +``` -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ concurrent_node_map(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +concurrent_node_map(size_type n, hasher const& hf, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ -```c++ concurrent_node_map(std::initializer_list il, const allocator_type& a); ``` +concurrent_node_map(std::initializer_list il, const allocator_type& a); -Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ + +concurrent_node_map(std::initializer_list il, size_type n, const allocator_type& a); -```c++ concurrent_node_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +``` -Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ + +concurrent_node_map(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -```c++ concurrent_node_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +``` -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 -```c++ ~concurrent_node_map(); ``` +```c++ + +~concurrent_node_map(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ concurrent_node_map& operator=(concurrent_node_map const& other); ``` +concurrent_node_map& operator=(concurrent_node_map const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Move Assignment -```c++ concurrent_node_map& operator=(concurrent_node_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +concurrent_node_map& operator=(concurrent_node_map&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值运算符。该操作会销毁先前存在的元素,交换 `other` +的哈希函数和谓词,若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且其 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则将 `other` 的内部桶数组直接转移至 +`++*++this` ;否则,插入 `other` +元素的移动构造副本。若统计功能 xref:#concurrent_node_map_boost_unordered_enable_stats[已启用] ,则当最终分配器等于 +`other.get++_++allocator()` 时转移 `other` 的内部统计信息,并始终调用 +`other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `*this` and `other`. +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Initializer List Assignment -```c++ concurrent_node_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +concurrent_node_map& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All previously existing elements are destroyed. +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 。 --- -=== Visitation +=== 访问操作 + +==== ++[++c++]++visit( ++[++c++]++ 访问) + +```c++ -==== [c]visit +template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; -```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` +``` -If an element `x` exists with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. +如果存在键等价于 `k` 的元素 `x` ,则通过指向 `x` 的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被访问的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Bulk visit +==== 批量访问 -```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` +```c++ -For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a reference to `x`. Such reference is const iff `*this` is const. +template + size_t visit(FwdIterator first, FwdIterator last, F f); +template + size_t visit(FwdIterator first, FwdIterator last, F f) const; +template + size_t cvisit(FwdIterator first, FwdIterator last, F f) const; -Although functionally equivalent to individually invoking xref:concurrent_node_map_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_node_map_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. +``` + +对于范围 ++[++`first`, `last`)中的每个元素 `k` ,如果容器中存在键等价于 `k` 的元素 `x` ,则通过指向 `x` 的引用来调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为 常量引用。 + +尽管在功能上等效于对每个键单独调用 xref:#concurrent_node_map_cvisit[`++[++c++]++visit`] ,但批量访问因内部流线型优化而通常具有更快的执行速度。建议 `std::distance(first,last)` 至少为 xref:#concurrent_node_map_constants[`bulk++_++visit++_++size`] 以获得性能提升:超过此大小,性能预计不会进一步提升。 [horizontal] -Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. +要求;; `FwdIterator` 需满足 https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator] 要求(C{plus}{plus}11 至 C{plus}{plus}17)或符合 https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward++_++iterator] 规范(C{plus}{plus}20 及更高版本)。对于 `K` = `std::iterator++_++traits++<++FwdIterator++>++::value++_++type` ,需满足以下条件之一: `K` 与 `key++_++type` 类型相同,或 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名。对于后一种情况,该库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 +返回;; 被访问的元素数量。 --- -==== [c]visit_all +==== ++[++c++]++visit++_++all + +```c++ -```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` +template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; -Successively invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. +``` + +依次使用指向表中各元素的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Returns:;; The number of elements visited. +返回;; 被访问的元素数量。 --- -==== Parallel [c]visit_all +==== 并行 ++[++c++]++visit++_++all + +```c++ + +template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; -```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` +``` -Invokes `f` with references to each of the elements in the table. Such references are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. +根据指定的执行策略语义并行化执行,使用指向表中各元素的引用调用 `f` 。当且仅当 `++*++this` 为常量时,该引用也为常量引用。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== [c]visit_while +==== ++[++c++]++visit++_++while -```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` +```c++ -Successively invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. +template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; + +``` + +依次使用指向容器中各元素的引用来调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问。当且仅当 `++*++this` 为常量时,指向元素的该引用也为常量引用。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 --- -==== Parallel [c]visit_while +==== 并行 ++[++c++]++visit++_++while + +```c++ -```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` +template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; -Invokes `f` with references to each of the elements in the table until `f` returns `false` or all the elements are visited. Such references to the elements are const iff `*this` is const. Execution is parallelized according to the semantics of the execution policy specified. +``` + +依次使用指向容器中各元素的引用来调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问。当且仅当 `++*++this` 为常量时,指向元素的该引用也为常量引用。根据指定的执行策略语义并行化执行操作。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 + ++ +并行化意味着执行不一定会因 `f` 返回 `false` 而立即结束,因此系统可能继续使用其他元素调用 `f` (即使其返回值同样为 `false` )。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ + +size_type size() const noexcept; -```c++ size_type size() const noexcept; ``` +``` [horizontal] -Returns:;; The number of elements in the table. +返回;; 容器中的元素数量。 [horizontal] -Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. +注意;; 在存在并发插入操作的情况下,返回值可能无法准确反映执行完成后容器的真实大小。 --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回;; 返回该容器可能包含的最大元素数量 `size()` 。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template bool emplace(Args&&... args); ``` +==== 原地构造 +```c++ -Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. +template bool emplace(Args&&... args); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。 --- -==== Copy Insert -```c++ bool insert(const value_type& obj); bool insert(const init_type& obj); ``` +==== 复制插入 +```c++ + +bool insert(const value_type& obj); bool insert(const init_type& obj); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Move Insert -```c++ bool insert(value_type&& obj); bool insert(init_type&& obj); ``` +==== 移动插入 +```c++ + +bool insert(value_type&& obj); bool insert(init_type&& obj); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Insert Iterator Range -```c++ template size_type insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template size_type insert(InputIterator first, InputIterator last); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_map_emplace[emplace](*first++); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List -```c++ size_type insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +size_type insert(std::initializer_list il); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_map_insert_iterator_range[insert](il.begin(), il.end()); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node -```c++ insert_return_type insert(node_type&& nh); ``` +==== 节点插入 +```c++ + +insert_return_type insert(node_type&& nh); -If `nh` is not empty, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`. `nh` is empty when the function returns. +``` + +若 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入关联元素。函数返回时 `nh` 为空。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +==== emplace++_++or++_[++c++]++visit +```c++ + +template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); + +``` -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `emplace_or_cvisit` is used. +如果容器中不存在等价键的元素,则插入一个用参数 `args` 构造的对象。否则,使用执行等价元素的引用来调用 `f` ;如果使用 `emplace++_++or++_++cvisit` 时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 --- -==== Copy insert_or_[c]visit -```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); ``` +==== 复制 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); template bool insert_or_visit(const init_type& obj, F f); template bool insert_or_cvisit(const init_type& obj, F f); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +当且仅当容器中不存在具有等效键的元素时,插入 `obj` ;否则,使用指向等效元素的引用调用 `f` (当使用 `++*_++cvisit` 重载时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 在 `insert++_++or++_[++c++]++visit(obj, f)` 形式的调用中,仅当 `std::remove++_++cv++<++std::remove++_++reference++<++decltype(obj)++>++::type++>++::type` 为 `value++_++type` 时,接受 `const value++_++type&` 参数的重载才会参与重载决议。 --- -==== Move insert_or_[c]visit -```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); ``` +==== 移动 insert++_++or++_[++c++]++visit +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); template bool insert_or_visit(init_type&& obj, F f); template bool insert_or_cvisit(init_type&& obj, F f); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj` ;否则,使用指向等效元素的引用调用 `f` (当使用 `++*_++cvisit` 重载时,该引用为常量引用)。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_or_[c]visit(obj, f)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 在 `insert++_++or++_[++c++]++visit(obj, f)` 形式的调用中,仅当 `std::remove++_++reference++<++decltype(obj)++>++::type` 为 `value++_++type` 时,接受 `value++_++type&&` 参数的重载才会参与重载决议。 --- -==== Insert Iterator Range or Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` +==== 迭代器范围插入或访问 +```c++ + +template + size_type insert_or_visit(InputIterator first, InputIterator last, F f); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_map_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List or Visit -```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` +==== 初始化列表插入或访问 +```c++ + +template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_map_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node or Visit -```c++ template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); ``` +==== 节点插入或访问 +```c++ + +template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); + +``` -If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff `insert_or_cvisit` is used. +若 `nh` 为空,则不执行任何操作。否则,当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入其关联的元素;否则,以等价元素的引用为参数调用 `f` ;当且仅当使用 `insert++_++or++_++cvisit` 时该引用为常量引用。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由调用 `hasher` 或调用 `f` 以外的操作抛出,则此函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== emplace_and_[c]visit -```c++ template bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` +==== emplace++_++and++_[++c++]++visit +```c++ + +template + bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2); +template + bool emplace_and_cvisit(Args&&... args, F1&& f1, F2&& f2); + +``` -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `emplace_and_cvisit` is used. +当容器中不存在等价键的元素时,插入一个用参数 `args` 构造的对象,然后使用指向新创建元素的非常量引用来调用 `f1` 。否则,使用指向等价元素的引用来调用 `f2` ;(当使用 `emplace++_++and++_++cvisit` 时,该引用为常量引用). [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此接口仅为说明,因为 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 --- -==== Copy insert_and_[c]visit -```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); ``` +==== 复制 insert++_++and++_[++c++]++visit +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_visit(const init_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const init_type& obj, F1 f1, F2 f2); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj`,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `const value_type&` argument participate in overload resolution only if `std::remove_cv::type>::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 在 `insert++_++and++_[++c++]++visit(obj, f1, f2)` 形式的调用中,仅当 `std::remove++_++cv++<++std::remove++_++reference++<++decltype(obj)++>++::type++>++::type` 为 `value++_++type` 时,接受 `const value++_++type&` 参数的重载才会参与重载决议。 --- -==== Move insert_and_[c]visit -```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); ``` +==== 移动 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_visit(init_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(init_type&& obj, F1 f1, F2 f2); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj`,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; In a call of the form `insert_and_[c]visit(obj, f1, f2)`, the overloads accepting a `value_type&&` argument participate in overload resolution only if `std::remove_reference::type` is `value_type`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 在 `insert++_++and++_[++c++]++visit(obj, f1, f2)` 形式的调用中,仅当 `std::remove++_++reference++<++decltype(obj)++>++::type` 为 `value++_++type` 时,接受 `value++_++type&&` 参数的重载才会参与重载决议。 --- -==== Insert Iterator Range and Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f2, F2 f2); ``` +==== 迭代器范围插入并访问 +```c++ + +template + size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F1 f2, F2 f2); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_map_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List and Visit -```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` +==== 初始化列表插入并访问 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); +template + size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_map_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node and Visit -```c++ template insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); template insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); ``` +==== 节点插入并访问 +```c++ + +template + insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); +template + insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); -If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.key()`, and then invokes `f1` with a non-const reference to the newly inserted element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff `insert_or_cvisit` is used. +``` + +若 `nh` 为空,则不执行任何操作。否则,当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入关联元素,并以新插入元素的非常量引用为参数调用 `f1` ;否则,以等价元素的引用为参数调用 `f2` ;当且仅当使用 `insert++_++or++_++cvisit` (此处应为 `insert++_++and++_++cvisit` ,可能是英文出了点错误)时该引用为常量引用。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f1` or `f2`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由调用 `hasher` 、 `f1` 或 `f2` 以外的操作抛出,则此函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== try_emplace -```c++ template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); ``` +==== try++_++emplace +```c++ + +template bool try_emplace(const key_type& k, Args&&... args); template bool try_emplace(key_type&& k, Args&&... args); template bool try_emplace(K&& k, Args&&... args); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. +``` + +如果容器中不存在键为 `k` 的元素,则插入一个由 `k` 和 `args` 构造的元素。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This function is similiar to xref:#concurrent_node_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此函数与 xref:#concurrent_node_map_emplace[emplace] 类似,区别在于:若存在等价键的元素,则不会构造任何 `value++_++type` ;否则,将按以下形式执行构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#concurrent_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. +``` -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +与 xref:#concurrent_node_map_emplace[emplace] 不同——该操作仅将所有参数直接转发给 `value++_++type` 的构造函数。 + +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类别名义时, `template++<++class K, class... Args++>++` 重载会才参与重决议析。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== try_emplace_or_[c]visit -```c++ template bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); template bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); template bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); template bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); ``` +==== try++_++emplace++_++or++_[++c++]++visit +```c++ + +template + bool try_emplace_or_visit(const key_type& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(const key_type& k, Args&&... args, F&& f); +template + bool try_emplace_or_visit(key_type&& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(key_type&& k, Args&&... args, F&& f); +template + bool try_emplace_or_visit(K&& k, Args&&... args, F&& f); +template + bool try_emplace_or_cvisit(K&& k, Args&&... args, F&& f); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it. Otherwise, invokes `f` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +如果容器中不存在键为 `k` 的元素,则插入一个由 `k` 和 `args` 构造的元素。否则,使用指向等价元素的引用调用 `f` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若已存在具有等效键的元素,则不会构造 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first four overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // last two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +``` -The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 + +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class... Args, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 -- --- -==== try_emplace_and_[c]visit -```c++ template bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); template bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); ``` +==== try++_++emplace++_++and++_[++c++]++visit +```c++ + +template + bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2); +template + bool try_emplace_and_cvisit(K&& k, Args&&... args, F1&& f1, F2&& f2); -Inserts an element constructed from `k` and `args` into the table if there is no existing element with key `k` contained within it, and then invokes `f1` with a non-const reference to the newly created element. Otherwise, invokes `f2` with a reference to the equivalent element; such reference is const iff a `*_cvisit` overload is used. +``` + +若容器中不存在键为 `k` 的元素,则插入由 `k` 和 `args` 构造的元素,并使用指向新创建元素的非常量引用调用 `f1` ;否则,使用指向等效元素的引用调用 `f2` ;当使用 `++*_++cvisit` 重载时,该引用为常量引用。 [horizontal] -Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. Notes:;; No `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 若已存在具有等效键的元素,则不会构造 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first four overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // last two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -The interface is exposition only, as C++ does not allow to declare parameter `f1` and `f2` after a variadic parameter pack. +``` -The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 + +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class... Args, class F1, class F2++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 -- --- -==== insert_or_assign -```c++ template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); ``` +==== insert++_++or++_++assign +```c++ + +template bool insert_or_assign(const key_type& k, M&& obj); template bool insert_or_assign(key_type&& k, M&& obj); template bool insert_or_assign(K&& k, M&& obj); + +``` -Inserts a new element into the table or updates an existing one by assigning to the contained value. +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +如果不存在这样的元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the table as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` [horizontal] -Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== erase -```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` +==== 擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(const K& k); -Erases the element with key equivalent to `k` if it exists. +``` + +若存在键等价于 `k` 的元素,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if by Key -```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` +==== 通过键进行条件擦除 +```c++ + +template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); -Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; `f` is passed a non-const reference to `x`. + + The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,本函数才会抛出异常。 +注意;; 向 `f` 传递指向 `x` 的非常量引用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `false` 时, `template++<++class K, class F++>++` 重载才会参与重载决议。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if -```c++ template size_type erase_if(F f); ``` +==== erase++_++if +```c++ + +template size_type erase_if(F f); + +``` -Successively invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. +依次使用指向表中各元素的非常量引用调用 `f` ,并删除其中使 `f` 返回 `true` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `f` 抛出异常时,才会抛出异常。 --- -==== Parallel erase_if -```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` +==== 并行条件擦除 +```c++ + +template void erase_if(ExecutionPolicy&& policy, F f); + +``` -Invokes `f` with non-const references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. +根据指定的执行策略语义并行化执行一下操作:使用指向表中各元素的非常量引用调用 `f` ,并删除其中使 `f` 返回 `true` 的元素。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,此重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== swap -```c++ void swap(concurrent_node_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ -Swaps the contents of the table with the parameter. +void swap(concurrent_node_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +若 `Allocator::propagate++_++on++_++container++_++swap` 已声明, 且其 `value` 为 `true` ,则交换容器的分配器;否则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- ==== extract -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); -Extracts the element with key equivalent to `k`, if it exists. +``` + +若存在键等价于 `k` 的元素,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== extract_if -```c++ template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); ``` +==== 条件提取 +```c++ + +template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); -Extracts the element `x` with key equivalent to `k`, if it exists and `f(x)` is `true`. +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the table. +擦除容器中所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` +并发性;; 阻塞于 `++*++this` 。 --- -==== merge -```c++ template size_type merge(concurrent_node_map& source); template size_type merge(concurrent_node_map&& source); ``` +==== 合并 +```c++ -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +template + size_type merge(concurrent_node_map& source); +template + size_type merge(concurrent_node_map&& source); + +``` + +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 [horizontal] -Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. +返回;; 插入的元素数量。 +并发性;; 阻塞于 `++*++this` 和 `source` 。 --- -=== Observers +=== 观察器 + +==== get++_++allocator +``` -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The table's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The table's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The table's key equality predicate. +返回;; 容器的键相等性谓词。 --- -=== Map Operations +=== 映射操作 ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 键等价于 `k` 的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回布尔值,表示容器中是否存在键等于 `k` 的元素。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ + +float load_factor() const noexcept; -==== load_factor -```c++ float load_factor() const noexcept; ``` +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ + +float max_load_factor() const noexcept; -```c++ float max_load_factor() const noexcept; ``` +``` [horizontal] -Returns:;; Returns the table's maximum load factor. +返回;; 返回容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++map` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) + +```c++ -```c++ size_type max_load() const noexcept; ``` +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回容器在无需重哈希的情况下所能容纳的最大元素数量(假设后续无元素被删除)。 +注意;; 在构造、重哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 +--- + +==== 保留 +```c++ + +void reserve(size_type n); -==== reserve -```c++ void reserve(size_type n); ``` +``` -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 --- -=== Statistics +=== 统计信息 + +==== get++_++stats +```c++ + +stats get_stats() const; -==== get_stats -```c++ stats get_stats() const; ``` +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_map_boost_unordered_enable_stats[enabled]. +返回;; 返回容器截至目前所执行的插入与查找操作的统计信息。 +注意;; 仅在 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#concurrent_node_map_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_map_boost_unordered_enable_stats[enabled]. +效果;; 将容器所保存的内部统计信息重置为零。 +注意;; 仅在 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#concurrent_node_map_boost_unordered_enable_stats[启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the table type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1338,7 +1847,7 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-key-type__ = std::remove_const_t< @@ -1346,7 +1855,7 @@ template ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = @@ -1354,7 +1863,7 @@ template ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-to-alloc-type__ = std::pair< @@ -1362,62 +1871,93 @@ template std::tuple_element_t<1, xref:#concurrent_node_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ -==== operator -```c++ template bool operator==(const concurrent_node_map& x, const concurrent_node_map& y); ``` +template + bool operator==(const concurrent_node_map& x, + const concurrent_node_map& y); -Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +``` + +若 `x.size() == y.size()` ,且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `true` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const concurrent_node_map& x, const concurrent_node_map& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const concurrent_node_map& x, + const concurrent_node_map& y); -Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +``` + +若 `x.size() == y.size()` ,并且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(concurrent_node_map& x, concurrent_node_map& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(concurrent_node_map& x, + concurrent_node_map& y) + noexcept(noexcept(x.swap(y))); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- x.xref:#concurrent_node_map_swap[swap](y); ----- --- -=== erase_if -```c++ template typename concurrent_node_map::size_type erase_if(concurrent_node_map& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename concurrent_node_map::size_type + erase_if(concurrent_node_map& c, Predicate pred); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- c.xref:#concurrent_node_map_erase_if[erase_if](pred); ----- -=== Serialization +=== 序列化 -``concurrent_node_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`concurrent++_++node++_++map` 可通过本库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 实现归档/检索功能。同时支持常规格式与 XML 格式的归档文件。 -==== Saving an concurrent_node_map to an archive +==== 将 concurrent++_++node++_++map 保存至归档 -Saves all the elements of a `concurrent_node_map` `x` to an archive (XML archive) `ar`. +将 `concurrent++_++node++_++map` 容器 `x` 中的所有元素保存至归档(XML 格式归档) `ar` 中。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 +并发性;; 阻塞于 `x` 。 --- -==== Loading an concurrent_node_map from an archive +==== 从归档加载 concurrent++_++node++_++map -Deletes all preexisting elements of a `concurrent_node_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_node_map` `other` saved to the storage read by `ar`. +删除 `concurrent++_++node++_++map` 容器 `x` 中的所有现有元素,并从归档(XML 归档) `ar` 插入原始 `concurrent++_++node++_++map` 容器 `other` 的元素副本,这些副本保存在 `ar` 读取的存储中。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +并发性;; 阻塞于 `x` 。 diff --git a/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc index a58cb07..a7ab335 100644 --- a/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/concurrent_node_set_zh_Hans.adoc @@ -1,17 +1,17 @@ -[#concurrent_node_set] -== Class Template concurrent_node_set +[#concurrent_node_set] +== 类模板 concurrent++_++node++_++set :idprefix: concurrent_node_set_ -`boost::concurrent_node_set` — A node-based hash table that stores unique values and allows for concurrent element insertion, erasure, lookup and access without external synchronization mechanisms. +`boost::concurrent++_++node++_++set` —— 一种基于节点的哈希表,用于存储唯一值,并允许在无外部同步机制的情况下并发执行元素插入、擦除、查找和访问操作。 -Even though it acts as a container, `boost::concurrent_node_set` does not model the standard C++ https://en.cppreference.com/w/cpp/named_req/Container[Container^] concept. In particular, iterators and associated operations (`begin`, `end`, etc.) are not provided. Element access is done through user-provided _visitation functions_ that are passed to `concurrent_node_set` operations where they are executed internally in a controlled fashion. Such visitation-based API allows for low-contention concurrent usage scenarios. +尽管 `boost::concurrent++_++node++_++set` 的行为类似于容器,但它并不符合标准 C{plus}{plus} https://en.cppreference.com/w/cpp/named_req/Container[容器] 概念。具体而言,它不提供迭代器及相关操作(如 `begin` 、 `end` 等)。元素的访问通过用户提供的 _访问函数_ 实现,这些函数被传递至 `concurrent++_++node++_++set` 的内部操作,并以受控方式执行。这种基于访问的 API 设计支持低竞争度的并发使用场景。 -The internal data structure of `boost::concurrent_node_set` is similar to that of `boost::unordered_node_set`. Unlike `boost::concurrent_flat_set`, pointer stability and node handling functionalities are provided, at the expense of potentially lower performance. +`boost::concurrent++_++node++_++set` 的内部数据结构与 `boost::unordered++_++node++_++set` 类似。与 `boost::concurrent++_++flat++_++set` 不同,它提供了指针稳定性和节点处理功能,但可能以性能降低为代价。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_concurrent_node_set.adoc[``] @@ -24,7 +24,7 @@ namespace unordered { class Allocator = std::allocator> class concurrent_node_set { public: - // types + // 类型 using key_type = Key; using value_type = Key; using init_type = Key; @@ -43,10 +43,10 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled] - // constants + // 常量 static constexpr size_type xref:#concurrent_node_set_constants[bulk_visit_size] = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#concurrent_node_set_default_constructor[concurrent_node_set](); explicit xref:#concurrent_node_set_bucket_count_constructor[concurrent_node_set](size_type n, const hasher& hf = hasher(), @@ -93,7 +93,7 @@ namespace unordered { allocator_type xref:#concurrent_node_set_get_allocator[get_allocator]() const noexcept; - // visitation + // 访问 template size_t xref:#concurrent_node_set_cvisit[visit](const key_type& k, F f); template size_t xref:#concurrent_node_set_cvisit[visit](const key_type& k, F f) const; template size_t xref:#concurrent_node_set_cvisit[cvisit](const key_type& k, F f) const; @@ -128,12 +128,12 @@ namespace unordered { template bool xref:#concurrent_node_set_parallel_cvisit_while[cvisit_while](ExecutionPolicy&& policy, F f) const; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#concurrent_node_set_empty[empty]() const noexcept; size_type xref:#concurrent_node_set_size[size]() const noexcept; size_type xref:#concurrent_node_set_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template bool xref:#concurrent_node_set_emplace[emplace](Args&&... args); bool xref:#concurrent_node_set_copy_insert[insert](const value_type& obj); bool xref:#concurrent_node_set_move_insert[insert](value_type&& obj); @@ -207,11 +207,11 @@ namespace unordered { template size_type xref:#concurrent_node_set_merge[merge](concurrent_node_set&& source); - // observers + // 观察器 hasher xref:#concurrent_node_set_hash_function[hash_function]() const; key_equal xref:#concurrent_node_set_key_eq[key_eq]() const; - // set operations + // 集合操作 size_type xref:#concurrent_node_set_count[count](const key_type& k) const; template size_type xref:#concurrent_node_set_count[count](const K& k) const; @@ -219,10 +219,10 @@ namespace unordered { template bool xref:#concurrent_node_set_contains[contains](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#concurrent_node_set_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#concurrent_node_set_load_factor[load_factor]() const noexcept; float xref:#concurrent_node_set_max_load_factor[max_load_factor]() const noexcept; void xref:#concurrent_node_set_set_max_load_factor[max_load_factor](float z); @@ -230,12 +230,12 @@ namespace unordered { void xref:#concurrent_node_set_rehash[rehash](size_type n); void xref:#concurrent_node_set_reserve[reserve](size_type n); - // statistics (if xref:concurrent_node_set_boost_unordered_enable_stats[enabled]) + // 统计(若已启用) stats xref:#concurrent_node_set_get_stats[get_stats]() const; void xref:#concurrent_node_set_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -280,107 +280,115 @@ namespace unordered { concurrent_node_set(std::initializer_list, typename xref:#concurrent_node_set_deduction_guides[__see below__]::size_type, Hash, Allocator) -> concurrent_node_set, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container -and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +|`Key` 必须满足 +https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] +到容器中的要求,且需满足从容器中 +https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the table's value type. -`std::allocator_traits::pointer` and `std::allocator_traits::const_pointer` must be convertible to/from `value_type*` and `const value_type*`, respectively. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同。 `std::allocator++_++traits++<++Allocator++>++::pointer` +和 `std::allocator++_++traits++<++Allocator++>++::const++_++pointer` +必须可分别转换为 `value++_++type++*++` 和 +`const value++_++type++*++` ,且可从这些类型转换而来。 |=== -The element nodes of the table are held into an internal _bucket array_. An node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素节点存储在内部的__桶数组__中。节点根据其元素的哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the table (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 进行调整。容器的__负载因子__(元素数量与桶数量的比值)永远不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Concurrency Requirements and Guarantees +=== 并发要求与保证 -Concurrent invocations of `operator()` on the same const instance of `Hash` or `Pred` are required to not introduce data races. For `Alloc` being either `Allocator` or any allocator type rebound from `Allocator`, concurrent invocations of the following operations on the same instance `al` of `Alloc` are required to not introduce data races: +要求对同一 `Hash` 或 `Pred` 常量实例并发调用 `operator()` 时不得引入数据竞争。对于 `Alloc` (即 `Allocator` 或其重绑定后的任意分配器类型),在同一实例 `al` 上并发调用以下操作时不得引入数据竞争: -* Copy construction from `al` of an allocator rebound from `Alloc` -* `std::allocator_traits::allocate` -* `std::allocator_traits::deallocate` -* `std::allocator_traits::construct` -* `std::allocator_traits::destroy` +* 从 `al` 复制构造重新绑定的分配器 +* `std::allocator++_++traits++<++Alloc++>++::allocate` +* `std::allocator++_++traits++<++Alloc++>++::deallocate` +* `std::allocator++_++traits++<++Alloc++>++::construct` +* `std::allocator++_++traits++<++Alloc++>++::destroy` -In general, these requirements on `Hash`, `Pred` and `Allocator` are met if these types are not stateful or if the operations only involve constant access to internal data members. +通常而言,若 `Hash` 、 `Pred` 和 `Allocator` 这些类型不包含状态,或其操作仅涉及对内部数据成员的常量访问,即可满足上述要求。 -With the exception of destruction, concurrent invocations of any operation on the same instance of a `concurrent_node_set` do not introduce data races — that is, they are thread-safe. +除析构操作外,对同一 `concurrent++_++node++_++set` 实例并发调用任何操作均不会引入数据竞争——即这些操作是线程安全的。 -If an operation *op* is explicitly designated as _blocking on_ `x`, where `x` is an instance of a `boost::concurrent_node_set`, prior blocking operations on `x` synchronize with *op*. So, blocking operations on the same `concurrent_node_set` execute sequentially in a multithreaded scenario. +若某个操作 *op* 被显式指定为__阻塞于__ `x` (其中 `x` 为 `boost::concurrent++_++node++_++set` 实例),则先前对 `x` 的阻塞操作将与 *op* 同步。因此,在多线程场景中,对同一 `concurrent++_++node++_++set` 的阻塞操作将按顺序执行。 -An operation is said to be _blocking on rehashing of_ ``__x__`` if it blocks on `x` only when an internal rehashing is issued. +若某个操作仅在触发内部重哈希时才会阻塞于 _`x`_,则称该操作__阻塞于 _`x`_ 的重哈希过程__。 -When executed internally by a `boost::concurrent_node_set`, the following operations by a user-provided visitation function on the element passed do not introduce data races: +当由 `boost::concurrent++_++node++_++set` 内部执行时,用户提供的访问函数对传递的元素执行以下操作不会引入数据竞争: -* Read access to the element. -* Non-mutable modification of the element. -* Mutable modification of the element: -Any `boost::concurrent_node_set operation` that inserts or modifies an element `e` synchronizes with the internal invocation of a visitation function on `e`. +* 对元素的读取访问。 +* 对元素的非可变修改。 +* 对元素的可变修改: + ** 在容器接受两个访问函数的操作中,此条件始终适用于第一个访问函数。 + ** 在名称不包含 `cvisit` 的非常量容器函数中,此条件适用于最后一个(或唯一一个)访问函数。 -Visitation functions executed by a `boost::concurrent_node_set` `x` are not allowed to invoke any operation on `x`; invoking operations on a different `boost::concurrent_node_set` instance `y` is allowed only if concurrent outstanding operations on `y` do not access `x` directly or indirectly. +任何插入或修改元素 `e` 的 `boost::concurrent++_++node++_++set` 操作均与在 `e` 上内部调用的访问函数同步。 ---- +由 `boost::concurrent++_++node++_++set` `x` 执行的访问函数不得调用 `x` 上的任何操作;仅当对另一 `boost::concurrent++_++node++_++set` 实例 `y` 的并发未完成操作不直接或间接访问 `x` 时,才允许调用 `y` 上的操作。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_DISABLE_REENTRANCY_CHECK` +==== `BOOST++_++UNORDERED++_++DISABLE++_++REENTRANCY++_++CHECK` -In debug builds (more precisely, when link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`^] is not defined), __container reentrancies__ (illegaly invoking an operation on `m` from within a function visiting elements of `m`) are detected and signalled through `BOOST_ASSERT_MSG`. When run-time speed is a concern, the feature can be disabled by globally defining this macro. +在调试版本中(更准确地说,当未定义 link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST++_++ASSERT++_++IS++_++VOID`] 时),系统会检测__容器重入__行为(即在访问 `m` 元素的函数内部非法调用 `m` 上的操作),并通过 `BOOST++_++ASSERT++_++MSG` 发出信号。若需关注运行时速度,可通过全局定义此宏来禁用该功能。 --- -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the table. Note that this option decreases the overall performance of many operations. +全局定义此宏以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低多数操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted table elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存提取的表元素的类,建模为 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -390,40 +398,57 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `NodeType` = `node_type`. +其中 `NodeType` = `node++_++type` 。 --- -=== Constants +=== 常量 + +```cpp + +static constexpr size_type bulk_visit_size; + +``` + +在 xref:#concurrent_node_set_bulk_visit[批量访问] 操作中内部使用的数据块大小。 -```cpp static constexpr size_type bulk_visit_size; ``` +=== 构造函数 -Chunk size internally used in xref:concurrent_node_set_bulk_visit[bulk visit] operations. +==== 默认构造函数 +```c++ -=== Constructors +concurrent_node_set(); -==== Default Constructor -```c++ concurrent_node_set(); ``` +``` -Constructs an empty table using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +构造一个空容器,使用 `hasher()` 作为哈希函数, `key++_++equal()` 作为键相等性谓词, `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit concurrent_node_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +explicit concurrent_node_set(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_set(InputIterator f, InputIterator l, @@ -433,85 +458,115 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ concurrent_node_set(concurrent_node_set const& other); ``` +==== 复制构造函数 +```c++ + +concurrent_node_set(concurrent_node_set const& other); -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible Concurrency:;; Blocking on `other`. +要求;; `value++_++type` 必须满足可复制构造要求 +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor -```c++ concurrent_node_set(concurrent_node_set&& other); ``` +==== 移动构造函数 +```c++ + +concurrent_node_set(concurrent_node_set&& other); -The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +``` + +移动构造函数。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词及分配器均从 `other` 移动构造。若统计功能以 xref:#concurrent_node_set_boost_unordered_enable_stats[启用] ,则同时转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template concurrent_node_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + concurrent_node_set(InputIterator f, InputIterator l, const allocator_type& a); -Constructs an empty table using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +``` + +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit concurrent_node_set(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit concurrent_node_set(Allocator const& a); -Constructs an empty table, using allocator `a`. +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ concurrent_node_set(concurrent_node_set const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +concurrent_node_set(concurrent_node_set const& other, Allocator const& a); + +``` -Constructs a table, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor with Allocator -```c++ concurrent_node_set(concurrent_node_set&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +concurrent_node_set(concurrent_node_set&& other, Allocator const& a); + +``` -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +若 `a == other.get++_++allocator()` ,则 `other` 的元素直接转移至新容器;否则,元素从 `other` 移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。若统计功能已 xref:#concurrent_node_set_boost_unordered_enable_stats[启用] ,则当且仅当 `a == other.get++_++allocator()` 时,同时转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `other`. +并发性;; 阻塞于 `other` 。 --- -==== Move Constructor from unordered_node_set +==== 从 unordered++_++node++_++set 的移动构造函数 -```c++ concurrent_node_set(unordered_node_set&& other); ``` +```c++ -Move construction from a xref:#unordered_node_set[`unordered_node_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +concurrent_node_set(unordered_node_set&& other); + +``` + +从 xref:#unordered_node_set[`unordered_node_set`][`unordered++_++node++_++set`] 移动构造。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词及分配器均从 `other` 移动构造。若统计功能 xref:#concurrent_node_set_boost_unordered_enable_stats[已启用] ,则同时转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; O(`bucket_count()`) +复杂度;; O(`bucket++_++count()`) --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- concurrent_node_set(std::initializer_list il, size_type n = _implementation-defined_ @@ -520,772 +575,1189 @@ concurrent_node_set(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ concurrent_node_set(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +concurrent_node_set(size_type n, allocator_type const& a); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ concurrent_node_set(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +concurrent_node_set(size_type n, hasher const& hf, allocator_type const& a); -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template concurrent_node_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ + +concurrent_node_set(std::initializer_list il, const allocator_type& a); -```c++ concurrent_node_set(std::initializer_list il, const allocator_type& a); ``` +``` -Constructs an empty table using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ + +concurrent_node_set(std::initializer_list il, size_type n, const allocator_type& a); -```c++ concurrent_node_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +``` -Constructs an empty table with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 -```c++ concurrent_node_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```c++ -Constructs an empty table with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +concurrent_node_set(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~concurrent_node_set(); ``` +~concurrent_node_set(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ concurrent_node_set& operator=(concurrent_node_set const& other); ``` +concurrent_node_set& operator=(concurrent_node_set const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this` and `other`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Move Assignment -```c++ concurrent_node_set& operator=(concurrent_node_set&& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:concurrent_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +concurrent_node_set& operator=(concurrent_node_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value); + +``` +移动赋值操作符。该操作会销毁容器中原有的元素,并交换 `other` +的哈希函数与键相等性谓词。若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则直接将 `other` 的内部桶数组转移至 +`++*++this` ;否则,将插入 `other` 中元素的移动构造副本。若统计功能 +xref:#concurrent_node_set_boost_unordered_enable_stats[已启用] +,则当且仅当最终分配器与 `other.get++_++allocator()` +相等时,同时转移其内部统计信息,并始终调用 `other.reset++_++stats()` 。 [horizontal] -Concurrency:;; Blocking on `*this` and `other`. +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- -==== Initializer List Assignment -```c++ concurrent_node_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +concurrent_node_set& operator=(std::initializer_list il); -Assign from values in initializer list. All previously existing elements are destroyed. +``` + +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] Concurrency:;; Blocking on `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 +并发性;; 阻塞于 `++*++this` 。 --- -=== Visitation +=== 访问操作 + +==== ++[++c++]++visit( ++[++c++]++ 访问) + +```c++ -==== [c]visit +template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; -```c++ template size_t visit(const key_type& k, F f); template size_t visit(const key_type& k, F f) const; template size_t cvisit(const key_type& k, F f) const; template size_t visit(const K& k, F f); template size_t visit(const K& k, F f) const; template size_t cvisit(const K& k, F f) const; ``` +``` -If an element `x` exists with key equivalent to `k`, invokes `f` with a const reference to `x`. +若存在键等价于 `k` 的元素 `x` ,则以 `x` 的常量引用调用 `f` 。 [horizontal] -Returns:;; The number of elements visited (0 or 1). Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被访问的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Bulk visit +==== 批量访问 + +```c++ + +template + size_t visit(FwdIterator first, FwdIterator last, F f); +template + size_t visit(FwdIterator first, FwdIterator last, F f) const; +template + size_t cvisit(FwdIterator first, FwdIterator last, F f) const; -```c++ template size_t visit(FwdIterator first, FwdIterator last, F f); template size_t visit(FwdIterator first, FwdIterator last, F f) const; template size_t cvisit(FwdIterator first, FwdIterator last, F f) const; ``` +``` -For each element `k` in the range [`first`, `last`), if there is an element `x` in the container with key equivalent to `k`, invokes `f` with a const reference to `x`. +对范围 ++[++`first`, `last`) 内的每个元素 `k` ,若容器中存在键等价于 `k` 的元素 `x` ,则使用指向 `x` 的常量引用调用 `f` 。 -Although functionally equivalent to individually invoking xref:concurrent_node_set_cvisit[`[c\]visit`] for each key, bulk visitation performs generally faster due to internal streamlining optimizations. It is advisable that `std::distance(first,last)` be at least xref:#concurrent_node_set_constants[`bulk_visit_size`] to enjoy a performance gain: beyond this size, performance is not expected to increase further. +尽管批量访问在功能上等效于对每个键单独调用 xref:#concurrent_node_set_cvisit[`++[++c++]++visit`] ,但该操作因内部流线化优化而通常表现更优。建议 `std::distance(first,last)` 至少达到 xref:#concurrent_node_set_constants[`bulk++_++visit++_++size`] 以获得性能提升:超过此规模后,性能预计不会进一步增长。 [horizontal] -Requires:;; `FwdIterator` is a https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator^] ({cpp}11 to {cpp}17), or satisfies https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward_iterator^] ({cpp}20 and later). For `K` = `std::iterator_traits::value_type`, either `K` is `key_type` or else `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. In the latter case, the library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. Returns:;; The number of elements visited. +要求;; `FwdIterator` 需满足 https://en.cppreference.com/w/cpp/named_req/ForwardIterator[LegacyForwardIterator] 要求(C{plus}{plus}11 至 C{plus}{plus}17)或符合 https://en.cppreference.com/w/cpp/iterator/forward_iterator[std::forward++_++iterator] 规范(C{plus}{plus}20 及更高版本)。对于 `K` = `std::iterator++_++traits++<++FwdIterator++>++::value++_++type` ,需满足以下条件之一: `K` 与 `key++_++type` 类型相同,或 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名。对于后一种情况,该库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免了实例化 `Key` 类型对象所需的开销。 +返回;; 被访问的元素数量。 --- -==== [c]visit_all +==== ++[++c++]++visit++_++all -```c++ template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; ``` +```c++ -Successively invokes `f` with const references to each of the elements in the table. +template size_t visit_all(F f); template size_t visit_all(F f) const; template size_t cvisit_all(F f) const; + +``` + +依次使用指向容器中各元素的常量引用调用 `f` 。 [horizontal] -Returns:;; The number of elements visited. +返回;; 被访问的元素数量。 --- -==== Parallel [c]visit_all +==== 并行 ++[++c++]++visit++_++all + +```c++ -```c++ template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; ``` +template void visit_all(ExecutionPolicy&& policy, F f); template void visit_all(ExecutionPolicy&& policy, F f) const; template void cvisit_all(ExecutionPolicy&& policy, F f) const; -Invokes `f` with const references to each of the elements in the table. Execution is parallelized according to the semantics of the execution policy specified. +``` + +根据指定的执行策略语义并行化执行操作;使用指向容器中各元素的常量引用调用 `f` 。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== [c]visit_while +==== ++[++c++]++visit++_++while + +```c++ -```c++ template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; ``` +template bool visit_while(F f); template bool visit_while(F f) const; template bool cvisit_while(F f) const; -Successively invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. +``` + +依次使用指向容器中每个元素的常量引用调用 `f` ,直到 `f` 返回 `false` ,或所有元素均被访问。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 --- -==== Parallel [c]visit_while +==== 并行 ++[++c++]++visit++_++while + +```c++ + +template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; -```c++ template bool visit_while(ExecutionPolicy&& policy, F f); template bool visit_while(ExecutionPolicy&& policy, F f) const; template bool cvisit_while(ExecutionPolicy&& policy, F f) const; ``` +``` -Invokes `f` with const references to each of the elements in the table until `f` returns `false` or all the elements are visited. Execution is parallelized according to the semantics of the execution policy specified. +根据指定的执行策略语义并行化执行操作;使用指向容器中各元素的常量引用调用 `f` ,直到 `f` 返回 `false` 或所有元素均被访问完毕。 [horizontal] -Returns:;; `false` iff `f` ever returns `false`. Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + These overloads only participate in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. + + Parallelization implies that execution does not necessary finish as soon as `f` returns `false`, and as a result `f` may be invoked with further elements for which the return value is also `false`. +返回;; 当且仅当 `f` 曾返回 `false` 时,才返回 `false` 。 +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,这些重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 + ++ +并行化意味着执行不一定会因 `f` 返回 `false` 而立即结束,因此系统可能继续使用其他元素调用 `f` (即使其返回值同样为 `false` )。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 + +```c++ -==== empty +[[nodiscard]] bool empty() const noexcept; -```c++ [[nodiscard]] bool empty() const noexcept; ``` +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 -```c++ size_type size() const noexcept; ``` +```c++ + +size_type size() const noexcept; + +``` [horizontal] -Returns:;; The number of elements in the table. +返回;; 容器中的元素数量。 [horizontal] -Notes:;; In the presence of concurrent insertion operations, the value returned may not accurately reflect the true size of the table right after execution. +注意;; 在存在并发插入操作的情况下,返回值可能无法准确反映执行完成后容器的真实大小。 --- -==== max_size +==== max++_++size + +```c++ -```c++ size_type max_size() const noexcept; ``` +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回;; 返回该容器可能包含的最大元素数量 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ -==== emplace -```c++ template bool emplace(Args&&... args); ``` +template bool emplace(Args&&... args); -Inserts an object, constructed with the arguments `args`, in the table if and only if there is no element in the table with an equivalent key. +``` + +当且仅当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Copy Insert -```c++ bool insert(const value_type& obj); ``` +==== 复制插入 +```c++ + +bool insert(const value_type& obj); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Move Insert -```c++ bool insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +bool insert(value_type&& obj); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Transparent Insert -```c++ template bool insert(K&& k); ``` +==== 透明插入 +```c++ -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +template bool insert(K&& k); + +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,此重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range -```c++ template size_type insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template size_type insert(InputIterator first, InputIterator last); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_set_emplace[emplace](*first++); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List -```c++ size_type insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ + +size_type insert(std::initializer_list il); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_set_insert_iterator_range[insert](il.begin(), il.end()); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node -```c++ insert_return_type insert(node_type&& nh); ``` +==== 节点插入 +```c++ + +insert_return_type insert(node_type&& nh); + +``` -If `nh` is not empty, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`. `nh` is empty when the function returns. +若 `nh` 非空,则当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素。函数返回时 `nh` 为空。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +==== emplace++_++or++_[++c++]++visit +```c++ + +template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); + +``` -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +当容器中不存在具有等效键的元素时,插入一个由参数 `args` 构造的对象;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare a parameter `f` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此接口仅为说明,因 C{plus}{plus} 不允许在可变参数包后声明参数 `f` 。 --- -==== Copy insert_or_[c]visit -```c++ template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); ``` +==== 复制 insert++_++or++_[++c++]++visit +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +template bool insert_or_visit(const value_type& obj, F f); template bool insert_or_cvisit(const value_type& obj, F f); + +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 插入到容器中;否则,以该等价元素的常量引用为参数调用函数 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Move insert_or_[c]visit -```c++ template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); ``` +==== 移动 insert++_++or++_[++c++]++visit +```c++ + +template bool insert_or_visit(value_type&& obj, F f); template bool insert_or_cvisit(value_type&& obj, F f); + +``` -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +当且仅当容器中不存在等价键的元素时,将 `obj` 插入到容器中;否则,以该等价元素的常量引用为参数调用函数 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Transparent insert_or_[c]visit -```c++ template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); ``` +==== 透明 insert++_++or++_[++c++]++visit +```c++ -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. Otherwise, invokes `f` with a const reference to the equivalent element. +template bool insert_or_visit(K&& k, F f); template bool insert_or_cvisit(K&& k, F f); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入由 `std::forward++<++K++>++(k)` 构造的元素;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,这些重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range or Visit -```c++ template size_type insert_or_visit(InputIterator first, InputIterator last, F f); template size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); ``` +==== 迭代器范围插入或访问 +```c++ + +template + size_type insert_or_visit(InputIterator first, InputIterator last, F f); +template + size_type insert_or_cvisit(InputIterator first, InputIterator last, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_set_emplace_or_cvisit[emplace_or_[c\]visit](*first++, f); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List or Visit -```c++ template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); ``` +==== 初始化列表插入或访问 +```c++ + +template size_type insert_or_visit(std::initializer_list il, F f); template size_type insert_or_cvisit(std::initializer_list il, F f); -Equivalent to [listing,subs="+macros,+quotes"] +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_set_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), std::ref(f)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node or Visit -```c++ template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); ``` +==== 节点插入或访问 +```c++ + +template insert_return_type insert_or_visit(node_type&& nh, F f); template insert_return_type insert_or_cvisit(node_type&& nh, F f); + +``` -If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`. Otherwise, invokes `f` with a const reference to the equivalent element. +若 `nh` 为空,则不执行任何操作;否则,当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由调用 `hasher` 或调用 `f` 以外的操作抛出,则此函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== emplace_and_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F1&& f1, F2&& f2); template bool emplace_or_cvisit(Args&&... args, F1&& f1, F2&& f2); ``` +==== emplace++_++and++_[++c++]++visit +```c++ + +template + bool emplace_or_visit(Args&&... args, F1&& f1, F2&& f2); +template + bool emplace_or_cvisit(Args&&... args, F1&& f1, F2&& f2); + +``` -Inserts an object, constructed with the arguments `args`, in the table if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +当容器中不存在具有等效键的元素时,插入由参数 `args` 构造的对象,并使用指向新创建元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; The interface is exposition only, as C++ does not allow to declare parameters `f1` and `f2` after a variadic parameter pack. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 此接口仅为说明,因为 C{plus}{plus} 不允许在可变参数包后声明参数 `f1` 和 `f2` 。 --- -==== Copy insert_and_[c]visit -```c++ template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f2, F2 f2); ``` +==== 复制 insert++_++and++_[++c++]++visit +```c++ -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f` with a const reference to the equivalent element. +template bool insert_and_visit(const value_type& obj, F1 f1, F2 f2); template bool insert_and_cvisit(const value_type& obj, F1 f2, F2 f2); + +``` + +当且仅当容器中不存在具有等效键的元素时,插入 `obj` 并使用指向新创建元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Move insert_and_[c]visit -```c++ template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); ``` +==== 移动 insert++_++and++_[++c++]++visit +```c++ + +template bool insert_and_visit(value_type&& obj, F1 f1, F2 f2); template bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2); -Inserts `obj` in the table if and only if there is no element in the table with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在等价键的元素时,将 `obj` 对象插入到容器中,并以新元素的常量引用为参数调用函数 `f1` ;否则,以该等价元素的常量引用为参数调用函数 `f2` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; `true` if an insert took place. + Concurrency:;; Blocking on rehashing of `*this`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若发生插入,则返回 `true` 。 + +并发性;; 阻塞于 `++*++this` 的重哈希。 --- -==== Transparent insert_and_[c]visit -```c++ template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); ``` +==== 透明 insert++_++and++_[++c++]++visit(透明插入并 ++[++c++]++ 访问) +```c++ + +template bool insert_and_visit(K&& k, F1 f1, F2 f2); template bool insert_and_cvisit(K&& k, F1 f1, F2 f2); -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key, and then invokes `f1` with a const reference to the newly created element. Otherwise, invokes `f2` with a const reference to the equivalent element. +``` + +当且仅当容器中不存在具有等效键的元素时,插入由 `std::forward++<++K++>++(k)` 构造的元素,并使用指向新创建元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; `true` if an insert took place. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; These overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若发生插入,则返回 `true` 。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时,这些重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range and Visit -```c++ template size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); template size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); ``` +==== 迭代器范围插入并访问 +```c++ + +template + size_type insert_and_visit(InputIterator first, InputIterator last, F1 f1, F2 f2); +template + size_type insert_and_cvisit(InputIterator first, InputIterator last, F1 f1, F2 f2); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- while(first != last) this->xref:#concurrent_node_set_emplace_and_cvisit[emplace_and_[c\]visit](*first++, f1, f2); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Initializer List and Visit -```c++ template size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); template size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); ``` +==== 初始化列表插入并访问 +```c++ + +template + size_type insert_and_visit(std::initializer_list il, F1 f1, F2 f2); +template + size_type insert_and_cvisit(std::initializer_list il, F1 f1, F2 f2); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- this->xref:#concurrent_node_set_insert_iterator_range_and_visit[insert_and_[c\]visit](il.begin(), il.end(), std::ref(f1), std::ref(f2)); ----- [horizontal] -Returns:;; The number of elements inserted. +返回;; 插入的元素数量。 --- -==== Insert Node and Visit -```c++ template insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); template insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); ``` +==== 节点插入并访问 +```c++ -If `nh` is empty, does nothing. Otherwise, inserts the associated element in the table if and only if there is no element in the table with a key equivalent to `nh.value()`, and then invokes `f1` with a const reference to the newly inserted element. Otherwise, invokes `f2` with a const reference to the equivalent element. +template + insert_return_type insert_and_visit(node_type&& nh, F1 f1, F2 f2); +template + insert_return_type insert_and_cvisit(node_type&& nh, F1 f1, F2 f2); + +``` + +若 `nh` 为空,则不执行任何操作;否则,当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素,并使用指向新插入元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false` and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true and `node` is empty. -* If the insertion failed, `inserted` is false and `node` has the previous value of `nh`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` or call to `f1` or `f2`, the function has no effect. Concurrency:;; Blocking on rehashing of `*this`. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个基于 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` 且 `node` 为空。 +* 若插入操作成功,则 `inserted` 为 true, 且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 false ,且 `node` 保留 `nh` 的原值。 +抛出;; 若异常由调用 `hasher` 、 `f1` 或 `f2` 以外的操作抛出,则此函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 的重哈希。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== erase -```c++ size_type erase(const key_type& k); template size_type erase(const K& k); ``` +==== 擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(const K& k); -Erases the element with key equivalent to `k` if it exists. +``` + +若存在键等价于 `k` 的元素,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if by Key -```c++ template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); ``` +==== 通过键进行条件擦除 +```c++ + +template size_type erase_if(const key_type& k, F f); template size_type erase_if(const K& k, F f); -Erases the element `x` with key equivalent to `k` if it exists and `f(x)` is `true`. +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则擦除该元素。 [horizontal] -Returns:;; The number of elements erased (0 or 1). Throws:;; Only throws an exception if it is thrown by `hasher`, `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `std::is_execution_policy_v>` is `false`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 插入的元素数量(0 或 1)。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,本函数才会抛出异常。 +注意;; 仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `false` 时, `template++<++class K, class F++>++` 重载才会参与重载决议。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class F++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== erase_if -```c++ template size_type erase_if(F f); ``` +==== erase++_++if +```c++ + +template size_type erase_if(F f); + +``` -Successively invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. +依次使用指向容器中各元素的引用调用 `f` ,并擦除其中使 `f` 返回 `true` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `f`. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `f` 抛出异常时,才会抛出异常。 --- -==== Parallel erase_if -```c++ template void erase_if(ExecutionPolicy&& policy, F f); ``` +==== 并行条件擦除 +```c++ + +template void erase_if(ExecutionPolicy&& policy, F f); + +``` -Invokes `f` with references to each of the elements in the table, and erases those for which `f` returns `true`. Execution is parallelized according to the semantics of the execution policy specified. +使用指向容器中每个元素的引用调用 `f` ,并擦除其中使 `f` 返回 `true` 的元素。该执行根据指定的执行策略语义并行化。 [horizontal] -Throws:;; Depending on the exception handling mechanism of the execution policy used, may call `std::terminate` if an exception is thrown within `f`. Notes:;; Only available in compilers supporting C++17 parallel algorithms. + + This overload only participates in overload resolution if `std::is_execution_policy_v>` is `true`. + + Unsequenced execution policies are not allowed. +抛出;; 根据所用执行策略的异常处理机制,若在函数 `f` 内部抛出异常,则可能调用 `std::terminate` 。 +注意;; 仅在支持 C{plus}{plus}17 并行算法的编译器中可用。 + ++ +仅当 `std::is++_++execution++_++policy++_++v++<++std::remove++_++cvref++_++t++<++ExecutionPolicy++>>++` 为 `true` 时,此重载才会参与重载决议。 + ++ +不允许使用无序执行策略。 --- -==== swap -```c++ void swap(concurrent_node_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ -Swaps the contents of the table with the parameter. +void swap(concurrent_node_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the tables' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +若 `Allocator::propagate++_++on++_++container++_++swap` 已声明, 且其 `value` 为 `true` ,则交换容器的分配器;否则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. Concurrency:;; Blocking on `*this` and `other`. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 +并发性;; 阻塞于 `++*++this` 和 `other` 。 --- ==== extract -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); -Extracts the element with key equivalent to `k`, if it exists. +``` + +若存在键等价于 `k` 的元素,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== extract_if -```c++ template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); ``` +==== 条件提取 +```c++ + +template node_type extract_if(const key_type& k, F f); template node_type extract_if(K&& k, F f); -Extracts the element `x` with key equivalent to `k`, if it exists and `f(x)` is `true`. +``` + +若存在键等价于 `k` 的元素 `x` ,且 `f(x)` 为 `true` ,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal` or `f`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 、 `key++_++equal` 或 `f` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; -Erases all elements in the table. +``` + +擦除容器中所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` Concurrency:;; Blocking on `*this`. +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` +并发性;; 阻塞于 `++*++this` 。 --- -==== merge -```c++ template size_type merge(concurrent_node_set& source); template size_type merge(concurrent_node_set&& source); ``` +==== 合并 +```c++ + +template + size_type merge(concurrent_node_set& source); +template + size_type merge(concurrent_node_set&& source); -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +``` + +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 [horizontal] -Returns:;; The number of elements inserted. Concurrency:;; Blocking on `*this` and `source`. +返回;; 插入的元素数量。 +并发性;; 阻塞于 `++*++this` 和 `source` 。 --- -=== Observers +=== 观察器 + +==== get++_++allocator +``` + +allocator_type get_allocator() const noexcept; -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +``` [horizontal] -Returns:;; The table's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The table's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The table's key equality predicate. +返回;; 容器的键相等性谓词。 --- -=== Set Operations +=== 集合操作 ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k` (0 or 1). Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 键等价于 `k` 的元素数量(0 或 1)。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `k` in the table. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回布尔值,表示容器中是否存在键等于 `k` 的元素。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ + +float load_factor() const noexcept; -==== load_factor -```c++ float load_factor() const noexcept; ``` +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) -```c++ float max_load_factor() const noexcept; ``` +```c++ + +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the table's maximum load factor. +返回;; 返回容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++set` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) -```c++ size_type max_load() const noexcept; ``` +```c++ + +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the table can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the table's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. + + In the presence of concurrent insertion operations, the value returned may not accurately reflect the true state of the table right after execution. +返回;; 返回容器在无需重哈希的情况下所能容纳的最大元素数量(假设后续无元素被删除)。 +注意;; 在构造、重哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 + ++ +在存在并发插入操作的情况下,返回值可能无法准确反映函数执行完成后容器的真实状态。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the table. +``` -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 + +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. --- +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 +--- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +void reserve(size_type n); -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the table. +``` + +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 + +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the table's hash function or comparison function. Concurrency:;; Blocking on `*this`. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 +并发性;; 阻塞于 `++*++this` 。 --- -=== Statistics +=== 统计信息 + +==== get++_++stats +```c++ -==== get_stats -```c++ stats get_stats() const; ``` +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_set_boost_unordered_enable_stats[enabled]. +返回;; 返回容器截至目前所执行的插入与查找操作的统计信息。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#concurrent_node_set_boost_unordered_enable_stats[已启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the table. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:concurrent_node_set_boost_unordered_enable_stats[enabled]. +效果;; 将容器所保存的内部统计信息重置为零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#concurrent_node_set_boost_unordered_enable_stats[已启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const concurrent_node_set& x, + const concurrent_node_set& y); -==== operator -```c++ template bool operator==(const concurrent_node_set& x, const concurrent_node_set& y); ``` +``` -Returns `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `true` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const concurrent_node_set& x, const concurrent_node_set& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const concurrent_node_set& x, + const concurrent_node_set& y); + +``` -Returns `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,并且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Concurrency:;; Blocking on `x` and `y`. Notes:;; Behavior is undefined if the two tables don't have equivalent equality predicates. +并发性;; 阻塞于 `x` 和 `y` 。 +注意;; 若两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(concurrent_node_set& x, concurrent_node_set& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ -Equivalent to [listing,subs="+macros,+quotes"] +template + void swap(concurrent_node_set& x, + concurrent_node_set& y) + noexcept(noexcept(x.swap(y))); + +``` + +等价于 +[listing, subs="+macros,+quotes"] ----- x.xref:#concurrent_node_set_swap[swap](y); ----- --- -=== erase_if -```c++ template typename concurrent_node_set::size_type erase_if(concurrent_node_set& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename concurrent_node_set::size_type + erase_if(concurrent_node_set& c, Predicate pred); + +``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 +[listing, subs="+macros,+quotes"] ----- c.xref:#concurrent_node_set_erase_if[erase_if](pred); ----- -=== Serialization +=== 序列化 -``concurrent_node_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`concurrent++_++node++_++set` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an concurrent_node_set to an archive +==== 将 concurrent++_++node++_++set 保存到归档 -Saves all the elements of a `concurrent_node_set` `x` to an archive (XML archive) `ar`. +将 `concurrent++_++node++_++set` `x` 的所有元素保存至归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). Concurrency:;; Blocking on `x`. +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 +并发性;; 阻塞于 `x` 。 --- -==== Loading an concurrent_node_set from an archive +==== 从归档加载 concurrent++_++node++_++set -Deletes all preexisting elements of a `concurrent_node_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `concurrent_node_set` `other` saved to the storage read by `ar`. +删除 `concurrent++_++node++_++set` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `concurrent++_++node++_++set` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. Concurrency:;; Blocking on `x`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +并发性;; 阻塞于 `x` 。 diff --git a/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc index 72aa9f2..830e126 100644 --- a/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc @@ -1,11 +1,11 @@ [#hash_traits] -== Hash Traits +== 哈希特征 :idprefix: hash_traits_ -=== `` Synopsis +=== `++<++boost/unordered/hash++_++traits.hpp++>++` 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- #include @@ -14,13 +14,13 @@ namespace unordered { using boost::hash_is_avalanching; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- [horizontal] -Note:;; This header is deprecated. Use instead `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[boost::hash_is_avalanching]` defined in `link:../../../../../container_hash/doc/html/hash.html#ref_boostcontainer_hashhash_is_avalanching_hpp[]`. +注意;; 此头文件已弃用。请改用定义于 link:../../../../../container_hash/doc/html/hash.html#ref_boostcontainer_hashhash_is_avalanching_hpp[`++<++boost/container++_++hash/hash++_++is++_++avalanching.hpp++>++`] 中的 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`boost::hash++_++is++_++avalanching`] 。 -Open-addressing and concurrent containers use the provided hash function `Hash` as-is if `hash_is_avalanching::value` is `true`; otherwise, they implement a bit-mixing post-processing stage to increase the quality of hashing at the expense of extra computational cost. +当 `hash++_++is++_++avalanching++<++Hash++>++::value` 为 `true` 时,开放寻址和并发容器会直接使用所提供的哈希函数 `Hash` ;否则它们将实施位混合后处理阶段,以牺牲额外计算成本为代价来提升哈希质量。 --- diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc index 6261316..95c108a 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_concurrent_flat_map_fwd] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++flat++_++map++_++fwd.hpp++>++` 概要 :idprefix: header_concurrent_flat_map_fwd_ -Forward declares all the definitions in xref:reference/header_concurrent_flat_map.adoc[``]. +前向声明 xref:reference/header_concurrent_flat_map.adoc[`++<++boost/unordered/concurrent++_++flat++_++map.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc index 902cc6f..d717a66 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_concurrent_flat_map] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++flat++_++map.hpp++>++` 概要 :idprefix: header_concurrent_flat_map_ -Defines `xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[boost::concurrent_flat_map]` and associated functions and alias templates. +定义 xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[`boost::concurrent++_++flat++_++map`] 以及相关的函数与别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -18,7 +18,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/concurrent_flat_map.adoc#concurrent_flat_map[concurrent_flat_map]; - // Equality Comparisons + // 相等比较 template bool xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_operator[operator++==++](const concurrent_flat_map& x, const concurrent_flat_map& y); @@ -27,18 +27,18 @@ namespace unordered { bool xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_operator_2[operator!=](const concurrent_flat_map& x, const concurrent_flat_map& y); - // swap + // 交换 template void xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_swap_2[swap](concurrent_flat_map& x, concurrent_flat_map& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename concurrent_flat_map::size_type xref:reference/concurrent_flat_map.adoc#concurrent_flat_map_erase_if[erase_if](concurrent_flat_map& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr 别名 (C++17及以上版本) namespace pmr { template>>; - } // namespace pmr + } // 命名空间 pmr擦除 -} // namespace unordered +} // 命名空间 unordered using unordered::concurrent_flat_map; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc index a0c0fa3..f43c73b 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_concurrent_flat_set_fwd] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++flat++_++set++_++fwd.hpp++>++` 概要 :idprefix: header_concurrent_flat_set_fwd_ -Forward declares all the definitions in xref:reference/header_concurrent_flat_set.adoc[``]. +前向声明 xref:reference/header_concurrent_flat_set.adoc[`++<++boost/unordered/concurrent++_++flat++_++set.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc index 4d6ad6d..f68b461 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_flat_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_concurrent_flat_set] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++flat++_++set.hpp++>++` 概要 :idprefix: header_concurrent_flat_set_ -Defines `xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[boost::concurrent_flat_set]` and associated functions and alias templates. +定义 xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[`boost::concurrent++_++flat++_++set`] 及其相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -17,7 +17,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/concurrent_flat_set.adoc#concurrent_flat_set[concurrent_flat_set]; - // Equality Comparisons + // 相等比较 template bool xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_operator[operator++==++](const concurrent_flat_set& x, const concurrent_flat_set& y); @@ -26,18 +26,18 @@ namespace unordered { bool xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_operator_2[operator!=](const concurrent_flat_set& x, const concurrent_flat_set& y); - // swap + // 交换 template void xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_swap_2[swap](concurrent_flat_set& x, concurrent_flat_set& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename concurrent_flat_set::size_type xref:reference/concurrent_flat_set.adoc#concurrent_flat_set_erase_if[erase_if](concurrent_flat_set& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template, @@ -45,11 +45,11 @@ namespace unordered { using concurrent_flat_set = boost::unordered::concurrent_flat_set>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::concurrent_flat_set; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc index aabdc20..057c96e 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_concurrent_node_map_fwd] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++node++_++map++_++fwd.hpp++>++` 概要 :idprefix: header_concurrent_node_map_fwd_ -Forward declares all the definitions in xref:reference/header_concurrent_node_map.adoc[``]. +前向声明 xref:reference/header_concurrent_node_map.adoc[`++<++boost/unordered/concurrent++_++node++_++map.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc index 0a0c8ce..001550a 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_concurrent_node_map] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++node++_++map.hpp++>++` 概要 :idprefix: header_concurrent_node_map_ -Defines `xref:reference/concurrent_node_map.adoc#concurrent_node_map[boost::concurrent_node_map]` and associated functions and alias templates. +定义 xref:reference/concurrent_node_map.adoc#concurrent_node_map[`boost::concurrent++_++node++_++map`] 以及相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -18,7 +18,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/concurrent_node_map.adoc#concurrent_node_map[concurrent_node_map]; - // Equality Comparisons + // 相等比较 template bool xref:reference/concurrent_node_map.adoc#concurrent_node_map_operator[operator++==++](const concurrent_node_map& x, const concurrent_node_map& y); @@ -27,18 +27,18 @@ namespace unordered { bool xref:reference/concurrent_node_map.adoc#concurrent_node_map_operator_2[operator!=](const concurrent_node_map& x, const concurrent_node_map& y); - // swap + // 交换 template void xref:reference/concurrent_node_map.adoc#concurrent_node_map_swap_2[swap](concurrent_node_map& x, concurrent_node_map& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename concurrent_node_map::size_type xref:reference/concurrent_node_map.adoc#concurrent_node_map_erase_if[erase_if](concurrent_node_map& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template>>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::concurrent_node_map; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc index 2778990..29f3c69 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_concurrent_node_set_fwd] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++node++_++set++_++fwd.hpp++>++` 概要 :idprefix: header_concurrent_node_set_fwd_ -Forward declares all the definitions in xref:reference/header_concurrent_node_set.adoc[``]. +前向声明 xref:reference/header_concurrent_node_set.adoc[`++<++boost/unordered/concurrent++_++node++_++set.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc index 236963a..096dc13 100644 --- a/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_concurrent_node_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_concurrent_node_set] -== `` Synopsis +== `++<++boost/unordered/concurrent++_++node++_++set.hpp++>++` 概要 :idprefix: header_concurrent_node_set_ -Defines `xref:reference/concurrent_node_set.adoc#concurrent_node_set[boost::concurrent_node_set]` and associated functions and alias templates. +定义 xref:reference/concurrent_node_set.adoc#concurrent_node_set[`boost::concurrent++_++node++_++set`] 及其相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -17,7 +17,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/concurrent_node_set.adoc#concurrent_node_set[concurrent_node_set]; - // Equality Comparisons + // 相等比较 template bool xref:reference/concurrent_node_set.adoc#concurrent_node_set_operator[operator++==++](const concurrent_node_set& x, const concurrent_node_set& y); @@ -26,18 +26,18 @@ namespace unordered { bool xref:reference/concurrent_node_set.adoc#concurrent_node_set_operator_2[operator!=](const concurrent_node_set& x, const concurrent_node_set& y); - // swap + // 交换 template void xref:reference/concurrent_node_set.adoc#concurrent_node_set_swap_2[swap](concurrent_node_set& x, concurrent_node_set& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename concurrent_node_set::size_type xref:reference/concurrent_node_set.adoc#concurrent_node_set_erase_if[erase_if](concurrent_node_set& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template, @@ -45,11 +45,11 @@ namespace unordered { using concurrent_node_set = boost::unordered::concurrent_node_set>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::concurrent_node_set; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc index 94b123c..2b2574d 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_flat_map_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++flat++_++map++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_flat_map_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_flat_map.adoc[``]. +前向声明 xref:reference/header_unordered_flat_map.adoc[`++<++boost/unordered/unordered++_++flat++_++map.hpp++>++`] 中定义的所有内容。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc index 2a9f51e..7b19752 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_flat_map] -== `` Synopsis +== `++<++boost/unordered/unordered++_++flat++_++map.hpp++>++` 概要 :idprefix: header_unordered_flat_map_ -Defines `xref:reference/unordered_flat_map.adoc#unordered_flat_map[boost::unordered_flat_map]` and associated functions and alias templates. +定义 xref:reference/unordered_flat_map.adoc#unordered_flat_map[`boost::unordered++_++flat++_++map`] 以及相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -18,7 +18,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/unordered_flat_map.adoc#unordered_flat_map[unordered_flat_map]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_flat_map.adoc#unordered_flat_map_operator_2[operator++==++](const unordered_flat_map& x, const unordered_flat_map& y); @@ -27,18 +27,18 @@ namespace unordered { bool xref:reference/unordered_flat_map.adoc#unordered_flat_map_operator_3[operator!=](const unordered_flat_map& x, const unordered_flat_map& y); - // swap + // 交换 template void xref:reference/unordered_flat_map.adoc#unordered_flat_map_swap_2[swap](unordered_flat_map& x, unordered_flat_map& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_flat_map::size_type xref:reference/unordered_flat_map.adoc#unordered_flat_map_erase_if[erase_if](unordered_flat_map& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr 别名(C++17 及以上) namespace pmr { template>>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_flat_map; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc index 68f6891..54c2357 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_flat_set_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++flat++_++set++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_flat_set_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_flat_set.adoc[``]. +前向声明 xref:reference/header_unordered_flat_set.adoc[`++<++boost/unordered/unordered++_++flat++_++set.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc index 443c74a..6fc3e97 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_flat_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_flat_set] -== `` Synopsis +== `++<++boost/unordered/unordered++_++flat++_++set.hpp++>++` 概要 :idprefix: header_unordered_flat_set_ -Defines `xref:reference/unordered_flat_set.adoc#unordered_flat_set[boost::unordered_flat_set]` and associated functions and alias templates. +定义 xref:reference/unordered_flat_set.adoc#unordered_flat_set[`boost::unordered++_++flat++_++set`] 以及相关的函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -17,7 +17,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/unordered_flat_set.adoc#unordered_flat_set[unordered_flat_set]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_flat_set.adoc#unordered_flat_set_operator[operator++==++](const unordered_flat_set& x, const unordered_flat_set& y); @@ -26,18 +26,18 @@ namespace unordered { bool xref:reference/unordered_flat_set.adoc#unordered_flat_set_operator_2[operator!=](const unordered_flat_set& x, const unordered_flat_set& y); - // swap + // 交换 template void xref:reference/unordered_flat_set.adoc#unordered_flat_set_swap_2[swap](unordered_flat_set& x, unordered_flat_set& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_flat_set::size_type xref:reference/unordered_flat_set.adoc#unordered_flat_set_erase_if[erase_if](unordered_flat_set& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr 别名(C++17 及以上) namespace pmr { template, @@ -45,11 +45,11 @@ namespace unordered { using unordered_flat_set = boost::unordered::unordered_flat_set>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_flat_set; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc index 7367ae9..9b82999 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_map_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++map++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_map_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_map.adoc[``]. +前向声明 xref:reference/header_unordered_map.adoc[`++<++boost/unordered/unordered++_++map.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc index 129b0fc..3f26834 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc @@ -1,9 +1,9 @@ [#header_unordered_map_fwd_top] -== `` Synopsis +== `++<++boost/unordered++_++map.hpp++>++` 概要 :idprefix: header_unordered_map_top_ -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- #include xref:reference/header_unordered_map.adoc[] ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc index 8e1a206..5a89520 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_map] -== `` Synopsis +== `++<++boost/unordered/unordered++_++map.hpp++>++` 概要 :idprefix: header_unordered_map_ -Defines `xref:reference/unordered_map.adoc#unordered_map[boost::unordered_map]`, `xref:reference/unordered_multimap.adoc#unordered_multimap[boost::unordered_multimap]` and associated functions and alias templates. +定义 xref:reference/unordered_map.adoc#unordered_map[`boost::unordered++_++map`] 、 xref:reference/unordered_multimap.adoc#unordered_multimap[`boost::unordered++_++multimap`] 以及相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -18,7 +18,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/unordered_map.adoc#unordered_map[unordered_map]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_map.adoc#unordered_map_operator_2[operator++==++](const unordered_map& x, const unordered_map& y); @@ -27,13 +27,13 @@ namespace unordered { bool xref:reference/unordered_map.adoc#unordered_map_operator_3[operator!=](const unordered_map& x, const unordered_map& y); - // swap + // 交换 template void xref:reference/unordered_map.adoc#unordered_map_swap_2[swap](unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_map::size_type xref:reference/unordered_map.adoc#unordered_map_erase_if[erase_if](unordered_map& c, Predicate pred); @@ -45,7 +45,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/unordered_multimap.adoc#unordered_multimap[unordered_multimap]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_multimap.adoc#unordered_multimap_operator[operator++==++](const unordered_multimap& x, const unordered_multimap& y); @@ -54,18 +54,18 @@ namespace unordered { bool xref:reference/unordered_multimap.adoc#unordered_multimap_operator_2[operator!=](const unordered_multimap& x, const unordered_multimap& y); - // swap + // 交换 template void xref:reference/unordered_multimap.adoc#unordered_multimap_swap_2[swap](unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_multimap::size_type xref:reference/unordered_multimap.adoc#unordered_multimap_erase_if[erase_if](unordered_multimap& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template>>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_map; using unordered::unordered_multimap; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc index d9f06f3..5d182ea 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_map_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_node_map_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++node++_++map++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_node_map_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_node_map.adoc[``]. +前向声明 xref:reference/header_unordered_node_map.adoc[`++<++boost/unordered/unordered++_++node++_++map.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc index 26af620..5c30bd9 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_node_map] -== `` Synopsis +== `++<++boost/unordered/unordered++_++node++_++map.hpp++>++` 概要 :idprefix: header_unordered_node_map_ -Defines `xref:reference/unordered_node_map.adoc#unordered_node_map[boost::unordered_node_map]` and associated functions and alias templates. +定义 xref:reference/unordered_node_map.adoc#unordered_node_map[`boost::unordered++_++node++_++map`] 及相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -18,7 +18,7 @@ namespace unordered { class Allocator = std::allocator>> class xref:reference/unordered_node_map.adoc#unordered_node_map[unordered_node_map]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_node_map.adoc#unordered_node_map_operator_2[operator++==++](const unordered_node_map& x, const unordered_node_map& y); @@ -27,18 +27,18 @@ namespace unordered { bool xref:reference/unordered_node_map.adoc#unordered_node_map_operator_3[operator!=](const unordered_node_map& x, const unordered_node_map& y); - // swap + // 交换 template void xref:reference/unordered_node_map.adoc#unordered_node_map_swap_2[swap](unordered_node_map& x, unordered_node_map& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_node_map::size_type xref:reference/unordered_node_map.adoc#unordered_node_map_erase_if[erase_if](unordered_node_map& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上版本) namespace pmr { template>>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_node_map; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc index 5a6aa95..295c580 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_set_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_node_set_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++node++_++set++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_node_set_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_node_set.adoc[``]. +前向声明 xref:reference/header_unordered_node_set.adoc[`++<++boost/unordered/unordered++_++node++_++set.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc index fe822cd..2f7af6e 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_node_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_node_set] -== `` Synopsis +== `++<++boost/unordered/unordered++_++node++_++set.hpp++>++` 概要 :idprefix: header_unordered_node_set_ -Defines `xref:reference/unordered_node_set.adoc#unordered_node_set[boost::unordered_node_set]` and associated functions and alias templates. +定义 xref:reference/unordered_node_set.adoc#unordered_node_set[`boost::unordered++_++node++_++set`] 及其相关函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -17,7 +17,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/unordered_node_set.adoc#unordered_node_set[unordered_node_set]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_node_set.adoc#unordered_node_set_operator[operator++==++](const unordered_node_set& x, const unordered_node_set& y); @@ -26,18 +26,18 @@ namespace unordered { bool xref:reference/unordered_node_set.adoc#unordered_node_set_operator_2[operator!=](const unordered_node_set& x, const unordered_node_set& y); - // swap + // 交换 template void xref:reference/unordered_node_set.adoc#unordered_node_set_swap_2[swap](unordered_node_set& x, unordered_node_set& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_node_set::size_type xref:reference/unordered_node_set.adoc#unordered_node_set_erase_if[erase_if](unordered_node_set& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template, @@ -45,11 +45,11 @@ namespace unordered { using unordered_node_set = boost::unordered::unordered_node_set>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_node_set; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc index 0548ba8..293f2e5 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_fwd_zh_Hans.adoc @@ -1,6 +1,6 @@ [#header_unordered_set_fwd] -== `` Synopsis +== `++<++boost/unordered/unordered++_++set++_++fwd.hpp++>++` 概要 :idprefix: header_unordered_set_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_set.adoc[``]. +前向声明 xref:reference/header_unordered_set.adoc[`++<++boost/unordered/unordered++_++set.hpp++>++`] 中的所有定义。 diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc index 78728a4..1d2d87c 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc @@ -1,9 +1,9 @@ [#header_unordered_set_fwd_top] -== `` Synopsis +== `++<++boost/unordered++_++set.hpp++>++` 概要 :idprefix: header_unordered_set_top_ -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- #include xref:reference/header_unordered_set.adoc[] ----- diff --git a/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc index 8b3b4a1..84c4f42 100644 --- a/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/header_unordered_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#header_unordered_set] -== `` Synopsis +== `++<++boost/unordered/unordered++_++set.hpp++>++` 概要 :idprefix: header_unordered_set_ -Defines `xref:reference/unordered_set.adoc#unordered_set[boost::unordered_set]`, `xref:reference/unordered_multiset.adoc#unordered_multiset[boost::unordered_multiset]` and associated functions and alias templates. +定义 xref:reference/unordered_set.adoc#unordered_set[`boost::unordered++_++set`] 、 xref:reference/unordered_multiset.adoc#unordered_multiset[`boost::unordered++_++multiset`] 以及相关的函数和别名模板。 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- namespace boost { @@ -17,7 +17,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/unordered_set.adoc#unordered_set[unordered_set]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_set.adoc#unordered_set_operator[operator++==++](const unordered_set& x, const unordered_set& y); @@ -26,13 +26,13 @@ namespace unordered { bool xref:reference/unordered_set.adoc#unordered_set_operator_2[operator!=](const unordered_set& x, const unordered_set& y); - // swap + // 交换 template void xref:reference/unordered_set.adoc#unordered_set_swap_2[swap](unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_set::size_type xref:reference/unordered_set.adoc#unordered_set_erase_if[erase_if](unordered_set& c, Predicate pred); @@ -43,7 +43,7 @@ namespace unordered { class Allocator = std::allocator> class xref:reference/unordered_multiset.adoc#unordered_multiset[unordered_multiset]; - // Equality Comparisons + // 相等比较 template bool xref:reference/unordered_multiset.adoc#unordered_multiset_operator[operator++==++](const unordered_multiset& x, const unordered_multiset& y); @@ -52,18 +52,18 @@ namespace unordered { bool xref:reference/unordered_multiset.adoc#unordered_multiset_operator_2[operator!=](const unordered_multiset& x, const unordered_multiset& y); - // swap + // 交换 template void xref:reference/unordered_multiset.adoc#unordered_multiset_swap_2[swap](unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); - // Erasure + // 擦除 template typename unordered_multiset::size_type xref:reference/unordered_multiset.adoc#unordered_multiset_erase_if[erase_if](unordered_multiset& c, Predicate pred); - // Pmr aliases (C++17 and up) + // Pmr别名(C++17及以上) namespace pmr { template, @@ -78,12 +78,12 @@ namespace unordered { using unordered_multiset = boost::unordered::unordered_multiset>; - } // namespace pmr + } // 命名空间 pmr -} // namespace unordered +} // 命名空间 unordered using unordered::unordered_set; using unordered::unordered_multiset; -} // namespace boost +} // 命名空间 boost ----- diff --git a/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc index 5079ace..de6ca3e 100644 --- a/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc @@ -1,13 +1,13 @@ [#stats] -== Statistics +== 统计信息 :idprefix: stats_ -Open-addressing and concurrent containers can be configured to keep running statistics of some internal operations affected by the quality of the supplied hash function. +开放寻址和并发容器可配置为持续统计受所提供哈希函数质量影响的某些内部操作。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- struct xref:#stats_stats_summary_type[__stats-summary-type__] { @@ -37,26 +37,26 @@ struct xref:reference/stats.adoc#stats_stats_type[__stats-type__] }; ----- -==== __stats-summary-type__ +==== _统计摘要类型_ -Provides the average value, variance and standard deviation of a sequence of numerical values. +提供数值序列的平均值、方差和标准差。 -==== __insertion-stats-type__ +==== _插入统计类型_ -Provides the number of insertion operations performed by a container and statistics on the associated __probe length__ (number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed per operation). +提供容器执行的插入操作次数及相关__探查长度__(每次操作访问的 xref:structures.adoc#structures_open_addressing_containers[桶组] 数量)的统计信息。 -==== __lookup-stats-type__ +==== _查找统计类型_ -For successful (element found) or unsuccessful (not found) lookup, provides the number of operations performed by a container and statistics on the associated __probe length__ (number of xref:structures.adoc#structures_open_addressing_containers[bucket groups] accessed) and number of element comparisons per operation. +对于成功(找到元素)或失败(未找到)查找操作,提供容器执行的操作次数及相关__探查长度__(访问的 xref:structures.adoc#structures_open_addressing_containers[桶组] 数量)和每次操作的元素比较次数的统计信息。 -==== __stats-type__ +==== _stats-type_ -Provides statistics on insertion, successful and unsuccessful lookups performed by a container. If the supplied hash function has good quality, then: +提供容器执行的插入操作、成功及失败查找操作的统计信息。若提供的哈希函数质量良好,则: -* Average probe lenghts should be close to 1.0. -* For successful lookups, the average number of element comparisons should be close to 1.0. -* For unsuccessful lookups, the average number of element comparisons should be close to 0.0. +* 平均探查长度应接近1.0。 +* 对于成功查找,平均元素比较次数应接近 1.0。 +* 对于失败查找,平均元素比较次数应接近 0.0。 -These statistics can be used to determine if a given hash function can be marked as link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[__avalanching__]. +这些统计信息可用于判断给定的哈希函数是否可被标记为 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[_雪崩效应_] 。 --- diff --git a/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc index 262590d..f3af8e2 100644 --- a/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_flat_map_zh_Hans.adoc @@ -1,23 +1,27 @@ [#unordered_flat_map] -== Class Template unordered_flat_map +== 类模板 unordered++_++flat++_++map :idprefix: unordered_flat_map_ -`boost::unordered_flat_map` — An open-addressing unordered associative container that associates unique keys with another value. +`boost::unordered++_++flat++_++map` —— 一种开放寻址的无序关联容器,用于将唯一键与另一个值关联。 -The performance of `boost::unordered_flat_map` is much better than that of `boost::unordered_map` or other implementations of `std::unordered_map`. Unlike standard unordered associative containers, which are node-based, the elements of a `boost::unordered_flat_map` are held directly in the bucket array, and insertions into an already occupied bucket are diverted to available buckets in the vicinity of the original position. This type of data layout is known as _open addressing_. +`boost::unordered++_++flat++_++map` 的性能远优于 `boost::unordered++_++map` 或其他 `std::unordered++_++map` 的实现。与基于节点的标准无序关联容器不同, `boost::unordered++_++flat++_++map` 的元素直接存储在桶数组中,且当元素被插入到已被占用的桶时,会将其重定向到原始位置附近的可用桶。这种数据布局类型称为__开放寻址法__。 -As a result of its using open addressing, the interface of `boost::unordered_flat_map` deviates in a number of aspects from that of `boost::unordered_map`/`std::unordered_map`: +由于采用开放寻址法, `boost::unordered++_++flat++_++map` 的接口在多个方面与 `boost::unordered++_++map` / `std::unordered++_++map` 不同: -- `value_type` must be move-constructible. - Pointer stability is not kept under rehashing. - `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - The maximum load factor of the container is managed internally and can't be set by the user. + - `value++_++type` 必须支持移动构造。 + - 在重哈希的过程中,指针稳定性无法保持。 + - `begin()` 不是常数时间复杂度操作。 + - 未提供用于桶管理(除 `bucket++_++count` 外)或节点提取/插入的 API。 + - 容器的最大负载因子由内部管理,用户无法进行设置。 -Other than this, `boost::unordered_flat_map` is mostly a drop-in replacement of node-based standard unordered associative containers. +除此之外, `boost::unordered++_++flat++_++map` 基本可完全替代基于节点的标准无序关联容器。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- -// #include xref:reference/header_unordered_flat_map.adoc[``] +// #include namespace boost { namespace unordered { @@ -29,7 +33,7 @@ namespace unordered { class Allocator = std::allocator>> class unordered_flat_map { public: - // types + // 类型定义 using key_type = Key; using mapped_type = T; using value_type = std::pair; @@ -52,7 +56,7 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled] - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_flat_map_default_constructor[unordered_flat_map](); explicit xref:#unordered_flat_map_bucket_count_constructor[unordered_flat_map](size_type n, const hasher& hf = hasher(), @@ -98,7 +102,7 @@ namespace unordered { unordered_flat_map& xref:#unordered_flat_map_initializer_list_assignment[operator++=++](std::initializer_list); allocator_type xref:#unordered_flat_map_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_flat_map_begin[begin]() noexcept; const_iterator xref:#unordered_flat_map_begin[begin]() const noexcept; iterator xref:#unordered_flat_map_end[end]() noexcept; @@ -106,12 +110,12 @@ namespace unordered { const_iterator xref:#unordered_flat_map_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_flat_map_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_flat_map_empty[empty]() const noexcept; size_type xref:#unordered_flat_map_size[size]() const noexcept; size_type xref:#unordered_flat_map_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template std::pair xref:#unordered_flat_map_emplace[emplace](Args&&... args); template iterator xref:#unordered_flat_map_emplace_hint[emplace_hint](const_iterator position, Args&&... args); std::pair xref:#unordered_flat_map_copy_insert[insert](const value_type& obj); @@ -166,11 +170,11 @@ namespace unordered { template void xref:#unordered_flat_map_merge[merge](unordered_flat_map&& source); - // observers + // 观察器 hasher xref:#unordered_flat_map_hash_function[hash_function]() const; key_equal xref:#unordered_flat_map_key_eq[key_eq]() const; - // map operations + // 映射操作 iterator xref:#unordered_flat_map_find[find](const key_type& k); const_iterator xref:#unordered_flat_map_find[find](const key_type& k) const; template @@ -190,7 +194,7 @@ namespace unordered { template std::pair xref:#unordered_flat_map_equal_range[equal_range](const K& k) const; - // element access + // 元素访问 mapped_type& xref:#unordered_flat_map_operator[operator[+]+](const key_type& k); mapped_type& xref:#unordered_flat_map_operator[operator[+]+](key_type&& k); template mapped_type& xref:#unordered_flat_map_operator[operator[+]+](K&& k); @@ -199,10 +203,10 @@ namespace unordered { template mapped_type& xref:#unordered_flat_map_at[at](const K& k); template const mapped_type& xref:#unordered_flat_map_at[at](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_flat_map_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#unordered_flat_map_load_factor[load_factor]() const noexcept; float xref:#unordered_flat_map_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_flat_map_set_max_load_factor[max_load_factor](float z); @@ -210,12 +214,12 @@ namespace unordered { void xref:#unordered_flat_map_rehash[rehash](size_type n); void xref:#unordered_flat_map_reserve[reserve](size_type n); - // statistics (if xref:unordered_flat_map_boost_unordered_enable_stats[enabled]) + // 统计(若已启用) stats xref:#unordered_flat_map_get_stats[get_stats]() const; void xref:#unordered_flat_map_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -265,101 +269,118 @@ namespace unordered { Hash, Allocator) -> unordered_flat_map, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -.2+|`Key` and `T` must be https://en.cppreference.com/w/cpp/named_req/MoveConstructible[MoveConstructible^]. -`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +.2+|`Key` 和 `T` +必须满足 https://en.cppreference.com/w/cpp/named_req/MoveConstructible[可移动构造] 要求。容器中的 +`std::pair++<++const Key, T++>++` 必须可从任何可转换为它的 `std::pair` +对象 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] ,且必须可从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[擦除] 。 |_T_ |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements of the container are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素存储在内部的__桶数组__中。元素根据其哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 来调整。容器的__负载因子__(元素数量与桶数量的比值)始终不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. +全局定义此宏,以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低许多操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -An iterator whose value type is `value_type`. +一种迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_flat_map(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +unordered_flat_map(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、以及 `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_flat_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +explicit unordered_flat_map(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_map(InputIterator f, InputIterator l, @@ -369,76 +390,106 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_flat_map(unordered_flat_map const& other); ``` +==== 复制构造函数 +```c++ + +unordered_flat_map(unordered_flat_map const& other); -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +``` + +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_flat_map(unordered_flat_map&& other); ``` +==== 移动构造函数 +```c++ -The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +unordered_flat_map(unordered_flat_map&& other); + +``` + +移动构造函数。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。若统计功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_flat_map(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +template + unordered_flat_map(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_flat_map(Allocator const& a); ``` +==== 分配器构造函数 +```c++ -Constructs an empty container, using allocator `a`. +explicit unordered_flat_map(Allocator const& a); + +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_flat_map(unordered_flat_map const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_flat_map(unordered_flat_map const& other, Allocator const& a); -Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +``` + +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_flat_map(unordered_flat_map&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_flat_map(unordered_flat_map&& other, Allocator const& a); + +``` -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +若 `a == other.get++_++allocator()` ,则 `other` 的元素直接转移至新容器;否则,元素从 `other` 的元素移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。若统计功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] ,则当且仅当 `a == other.get++_++allocator()` 时,转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 --- -==== Move Constructor from concurrent_flat_map +==== 从 concurrent++_++flat++_++map 的移动构造函数 + +```c++ + +unordered_flat_map(concurrent_flat_map&& other); -```c++ unordered_flat_map(concurrent_flat_map&& other); ``` +``` -Move construction from a xref:#concurrent_flat_map[`concurrent_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +从 xref:#concurrent_flat_map[`concurrent_flat_map`][`concurrent++_++flat++_++map`] 移动构造。 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。若统计功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度;; 常数时间复杂度。 +并发性;; 阻塞于 `other` 。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_flat_map(std::initializer_list il, size_type n = _implementation-defined_ @@ -447,624 +498,1003 @@ unordered_flat_map(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_flat_map(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_flat_map(size_type n, allocator_type const& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_flat_map(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +unordered_flat_map(size_type n, hasher const& hf, allocator_type const& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 -```c++ unordered_flat_map(std::initializer_list il, const allocator_type& a); ``` +```c++ -Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +unordered_flat_map(std::initializer_list il, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 -```c++ unordered_flat_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +```c++ -Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +unordered_flat_map(std::initializer_list il, size_type n, const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 -```c++ unordered_flat_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +unordered_flat_map(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器、默认键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 -```c++ ~unordered_flat_map(); ``` +```c++ + +~unordered_flat_map(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ unordered_flat_map& operator=(unordered_flat_map const& other); ``` +unordered_flat_map& operator=(unordered_flat_map const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 --- -==== Move Assignment -```c++ unordered_flat_map& operator=(unordered_flat_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +unordered_flat_map& operator=(unordered_flat_map&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值操作符。该操作会销毁容器中原有的元素,并交换 `other` +的哈希函数和谓词,若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器等于 +`other.get++_++allocator()` ,则 `other` +的内部桶数组直接转移至新容器;否则,插入 `other` +元素的移动构造副本。若统计功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] ,则当且仅当最终分配器等于 +`other.get++_++allocator()` 时,转移 `other` 的内部统计信息,并始终调用 +`other.reset++_++stats()` 。 --- -==== Initializer List Assignment -```c++ unordered_flat_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +unordered_flat_map& operator=(std::initializer_list il); -Assign from values in initializer list. All previously existing elements are destroyed. +``` + +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 -```c++ size_type size() const noexcept; ``` +```c++ + +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size + +```c++ -```c++ size_type max_size() const noexcept; ``` +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template std::pair emplace(Args&&... args); -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +``` -`position` is a suggestion to where the element should be inserted. This implementation ignores it. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 + +`position` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。 --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); ``` +==== 复制插入 +```c++ + +std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); ``` +==== 移动插入 +```c++ + +std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); + +``` 当且仅当容器中不存在具有等价键的元素时,插入 `obj` 。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +对于 `insert(hint, x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并会选择 `init++_++type` 重载版本。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); ``` +==== 带提示的移动插入 +```c++ + +iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +对于 `insert(hint, x)` 形式的调用(其中 `x` 可同等地转换为 `value++_++type&&` 和 `init++_++type&&` ),该调用不会产生歧义,并会选择 `init++_++type` 重载版本。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 必须能够通过 `++*++first` 在容器中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +void insert(std::initializer_list); + +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== try_emplace -```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args); ``` +==== try++_++emplace +```c++ + +template + std::pair try_emplace(const key_type& k, Args&&... args); +template + std::pair try_emplace(key_type&& k, Args&&... args); +template + std::pair try_emplace(K&& k, Args&&... args); -Inserts a new element into the container if there is no existing element with key `k` contained within it. +``` -If there is an existing element with key `k` this function does nothing. +若容器中不存在键为 `k` 的元素,则插入一个新元素。 + +若存在键为 `k` 的元素,则此函数不执行任何操作。 [horizontal] -Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_flat_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_flat_map_emplace[emplace] 类似,区别在于:若已存在具有等效键的元素,则不会构造任何 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#unordered_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. +``` + +而非像 xref:#unordered_flat_map_emplace[emplace] 只是简单地将所有参数转发给 `value++_++type` 的构造函数。 -Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. +可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== try_emplace with Hint -```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` +==== 带提示的 try++_++emplace +```c++ -Inserts a new element into the container if there is no existing element with key `k` contained within it. +template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, K&& k, Args&&... args); -If there is an existing element with key `k` this function does nothing. +``` -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +若容器中不存在键为 `k` 的元素,则插入一个新元素。 + +若存在键为 `k` 的元素,则此函数不执行任何操作。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_flat_map_emplace_hint[emplace_hint], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_flat_map_emplace_hint[emplace++_++hint] 类似,区别在于:若已存在具有等效键的元素,则不会构造任何 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#unordered_flat_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. +``` + +而非像 xref:#unordered_flat_map_emplace_hint[emplace++_++hint] 只是简单地将所有参数转发给 `value++_++type` 的构造函数。 -Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. +可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== insert_or_assign -```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` +==== insert++_++or++_++assign +```c++ + +template + std::pair insert_or_assign(const key_type& k, M&& obj); +template + std::pair insert_or_assign(key_type&& k, M&& obj); +template + std::pair insert_or_assign(K&& k, M&& obj); -Inserts a new element into the container or updates an existing one by assigning to the contained value. +``` + +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` [horizontal] -Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== insert_or_assign with Hint -```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` +==== 带提示的 insert++_++or++_++assign +```c++ + +template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); -Inserts a new element into the container or updates an existing one by assigning to the contained value. +``` -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 + +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== Erase by Position +==== 通过位置擦除 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- _convertible-to-iterator_ erase(iterator position); _convertible-to-iterator_ erase(const_iterator position); ---- -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. +返回;; 返回一个不透明对象,该对象可隐式转换为擦除前紧接在 `position` 之后的 `iterator` 或 `const++_++iterator` 。 +抛出;; 无。 +注意;; 返回的不透明对象必须被立即丢弃或转换为 `iterator` 或 `const++_++iterator` 。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(K&& k); + +``` -Erase all elements with key equivalent to `k`. +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 -```c++ iterator erase(const_iterator first, const_iterator last); ``` +```c++ -Erases the elements in the range from `first` to `last`. +iterator erase(const_iterator first, const_iterator last); + +``` + +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 在此实现中不抛出任何异常(既不调用 `hasher` , 也不调用 `key++_++equal` 对象)。 --- -==== swap -```c++ void swap(unordered_flat_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ + +void swap(unordered_flat_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + +``` -Swaps the contents of the container with the parameter. +交换容器与参数的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- ==== pull -```c++ init_type pull(const_iterator position); ``` +```c++ -Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. +init_type pull(const_iterator position); + +``` + +从 `position` 指向的元素移动构造一个 `init++_++value` 对象 `x` ,擦除该元素并返回 `x` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ -Erases all elements in the container. +void clear() noexcept; + +``` + +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` --- -==== merge -```c++ template void merge(unordered_flat_map& source); template void merge(unordered_flat_map&& source); ``` +==== 合并 +```c++ -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +template + void merge(unordered_flat_map& source); +template + void merge(unordered_flat_map&& source); + +``` + +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 --- -=== Observers +=== 观察器 + +==== get++_++allocator +``` + +allocator_type get_allocator() const noexcept; -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +``` [horizontal] -Returns:;; The container's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器;若不存在这样的元素,则返回 `end()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== operator++[++++]++ -```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` +==== operator++[]++ +```c++ + +mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); + +``` [horizontal] -Effects:;; If the container does not already contain an element with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +效果;; 若容器中尚不存在键等价于 `k` 的元素,则插入值 `std::pair++<++key++_++type const, mapped++_++type++>++(k, mapped++_++type())` 。 +返回;; 返回一个引用,该引用指向容器中已存在的键等于 `k` 的元素 `x` 的 `x.second` 成员;若元素不存在,则指向新插入元素的该成员。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== at -```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` +```c++ + +mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; + +``` [horizontal] -Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个引用,该引用指向键等价于 `k` 的(唯一)元素 `x` 的 `x.second` 成员。 +抛出;; 如果不存在这样的元素,则抛出类型为 `std::out++_++of++_++range` 的异常对象。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 -==== load_factor -```c++ float load_factor() const noexcept; ``` +==== 负载因子 +```c++ + +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the container's maximum load factor. +返回;; 容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++map` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) + +```c++ -```c++ size_type max_load() const noexcept; ``` +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. +返回;; 返回容器在不重哈希的情况下可容纳的最大元素数(假设不再擦除元素)。 +注意;; 在构造、重新哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +void rehash(size_type n); -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. +``` -Invalidates iterators, pointers and references, and changes the order of elements. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 + +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。若使用的分配器采用花式指针,随后会执行默认分配操作。 + +使迭代器、指针和引用失效,并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +void reserve(size_type n); + +``` -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 -Invalidates iterators, pointers and references, and changes the order of elements. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 + +使迭代器、指针和引用失效,并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Statistics +=== 统计信息 + +==== get++_++stats +```c++ -==== get_stats -```c++ stats get_stats() const; ``` +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. +返回;; 返回容器直到目前已执行插入和查找操作的统计摘要。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. +效果;; 将容器维护的内部统计信息清零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_flat_map_boost_unordered_enable_stats[已启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1072,7 +1502,7 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-key-type__ = std::remove_const_t< @@ -1080,7 +1510,7 @@ template ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = @@ -1088,7 +1518,7 @@ template ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-to-alloc-type__ = std::pair< @@ -1096,80 +1526,123 @@ template std::tuple_element_t<1, xref:#unordered_flat_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const unordered_flat_map& x, + const unordered_flat_map& y); -==== operator -```c++ template bool operator==(const unordered_flat_map& x, const unordered_flat_map& y); ``` +``` -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_flat_map& x, const unordered_flat_map& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const unordered_flat_map& x, + const unordered_flat_map& y); + +``` -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 -=== Swap -```c++ template void swap(unordered_flat_map& x, unordered_flat_map& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_flat_map& x, + unordered_flat_map& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -=== erase_if -```c++ template typename unordered_flat_map::size_type erase_if(unordered_flat_map& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_flat_map::size_type + erase_if(unordered_flat_map& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` ++ +请注意,传递给 `pred` 的引用是非常量的。 -=== Serialization +=== 序列化 -``unordered_flat_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++flat++_++map` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_flat_map to an archive +==== 将 unordered++_++flat++_++map 保存到归档 -Saves all the elements of an `unordered_flat_map` `x` to an archive (XML archive) `ar`. +将 `unordered++_++flat++_++map` `x` 的所有元素保存到归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 --- -==== Loading an unordered_flat_map from an archive +==== 从归档加载 unordered++_++flat++_++map -Deletes all preexisting elements of an `unordered_flat_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_flat_map` `other` saved to the storage read by `ar`. +删除 `unordered++_++flat++_++map` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++flat++_++map` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_flat_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 所指向的 `unordered++_++flat++_++map` 容器 `x` 必须先前已保存至 `ar` ,且在保存 `x` 与保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_flat_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 若 `x` 是 `it` 所指向的 `unordered++_++flat++_++map` 容器,则在加载 `x` 与加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc index 9411234..c1a84f4 100644 --- a/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_flat_set_zh_Hans.adoc @@ -1,21 +1,25 @@ [#unordered_flat_set] -== Class Template unordered_flat_set +== 类模板 unordered++_++flat++_++set :idprefix: unordered_flat_set_ -`boost::unordered_flat_set` — An open-addressing unordered associative container that stores unique values. +`boost::unordered++_++flat++_++set` —— 一种使用开放寻址法的无序关联容器,用于存储唯一值。 -The performance of `boost::unordered_flat_set` is much better than that of `boost::unordered_set` or other implementations of `std::unordered_set`. Unlike standard unordered associative containers, which are node-based, the elements of a `boost::unordered_flat_set` are held directly in the bucket array, and insertions into an already occupied bucket are diverted to available buckets in the vicinity of the original position. This type of data layout is known as _open addressing_. +`boost::unordered++_++flat++_++set` 的性能远优于 `boost::unordered++_++set` 或其他 `std::unordered++_++set` 的实现。与基于节点的标准无序关联容器不同, `boost::unordered++_++flat++_++set` 的元素直接存储在桶数组中,插入到已占用桶中的元素会被重定向到原始位置附近的可用桶中。这种数据布局称为__开放寻址法__。 -As a result of its using open addressing, the interface of `boost::unordered_flat_set` deviates in a number of aspects from that of `boost::unordered_flat_set`/`std::unordered_flat_set`: +由于采用开放寻址法, `boost::unordered++_++flat++_++set` 的接口在多个方面与 `boost::unordered++_++set` / `std::unordered++_++set` 有所不同: -- `value_type` must be move-constructible. - Pointer stability is not kept under rehashing. - `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - The maximum load factor of the container is managed internally and can't be set by the user. + - `value++_++type` 必须支持移动构造。 + - 在重哈希的过程中,指针稳定性无法保持。 + - `begin()` 不是常数时间复杂度操作。 + - 未提供用于桶管理(除 `bucket++_++count` 外)或节点提取/插入的 API。 + - 容器的最大负载因子由内部管理,用户无法进行设置。 -Other than this, `boost::unordered_flat_set` is mostly a drop-in replacement of node-based standard unordered associative containers. +除此之外, `boost::unordered++_++flat++_++set` 几乎可以完全替代基于节点的标准无序关联容器。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_flat_set.adoc[``] @@ -47,7 +51,7 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled] - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_flat_set_default_constructor[unordered_flat_set](); explicit xref:#unordered_flat_set_bucket_count_constructor[unordered_flat_set](size_type n, const hasher& hf = hasher(), @@ -92,7 +96,7 @@ namespace unordered { unordered_flat_set& xref:#unordered_flat_set_initializer_list_assignment[operator++=++](std::initializer_list); allocator_type xref:#unordered_flat_set_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_flat_set_begin[begin]() noexcept; const_iterator xref:#unordered_flat_set_begin[begin]() const noexcept; iterator xref:#unordered_flat_set_end[end]() noexcept; @@ -100,12 +104,12 @@ namespace unordered { const_iterator xref:#unordered_flat_set_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_flat_set_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_flat_set_empty[empty]() const noexcept; size_type xref:#unordered_flat_set_size[size]() const noexcept; size_type xref:#unordered_flat_set_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template std::pair xref:#unordered_flat_set_emplace[emplace](Args&&... args); template iterator xref:#unordered_flat_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); std::pair xref:#unordered_flat_set_copy_insert[insert](const value_type& obj); @@ -133,11 +137,11 @@ namespace unordered { template void xref:#unordered_flat_set_merge[merge](unordered_flat_set&& source); - // observers + // 观察器 hasher xref:#unordered_flat_set_hash_function[hash_function]() const; key_equal xref:#unordered_flat_set_key_eq[key_eq]() const; - // set operations + // 集合操作 iterator xref:#unordered_flat_set_find[find](const key_type& k); const_iterator xref:#unordered_flat_set_find[find](const key_type& k) const; template @@ -157,10 +161,10 @@ namespace unordered { template std::pair xref:#unordered_flat_set_equal_range[equal_range](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_flat_set_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#unordered_flat_set_load_factor[load_factor]() const noexcept; float xref:#unordered_flat_set_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_flat_set_set_max_load_factor[max_load_factor](float z); @@ -168,12 +172,12 @@ namespace unordered { void xref:#unordered_flat_set_rehash[rehash](size_type n); void xref:#unordered_flat_set_reserve[reserve](size_type n); - // statistics (if xref:unordered_flat_set_boost_unordered_enable_stats[enabled]) + // 统计(如果启用) stats xref:#unordered_flat_set_get_stats[get_stats]() const; void xref:#unordered_flat_set_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -218,99 +222,116 @@ namespace unordered { unordered_flat_set(std::initializer_list, typename xref:#unordered_flat_set_deduction_guides[__see below__]::size_type, Hash, Allocator) -> unordered_flat_set, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^] into the container -and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +|`Key` 必须满足 +https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] +到容器中的要求,且需满足从容器中 +https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements of the container are held into an internal _bucket array_. An element is inserted into a bucket determined by its hash code, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素存储在内部的__桶数组__中。元素根据其哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则会使用原始位置附近可用的桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 来调整。容器的__负载因子__(元素数量与桶数量的比值)始终不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. +全局定义此宏,以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低许多操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_flat_set(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +unordered_flat_set(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、以及 `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_flat_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit unordered_flat_set(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_set(InputIterator f, InputIterator l, @@ -320,76 +341,106 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_flat_set(unordered_flat_set const& other); ``` +==== 复制构造函数 +```c++ -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +unordered_flat_set(unordered_flat_set const& other); -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +``` + +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_flat_set(unordered_flat_set&& other); ``` +==== 移动构造函数 +```c++ + +unordered_flat_set(unordered_flat_set&& other); + +``` -The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +移动构造函数。 `other` 的内部桶数组直接转移到新容器。哈希函数、谓词和分配器从 `other` 移动构造。如果统计功能已 xref:#unordered_flat_set_boost_unordered_enable_stats[启用] ,则同时转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_flat_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +template + unordered_flat_set(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_flat_set(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit unordered_flat_set(Allocator const& a); + +``` -Constructs an empty container, using allocator `a`. +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_flat_set(unordered_flat_set const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_flat_set(unordered_flat_set const& other, Allocator const& a); + +``` -Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_flat_set(unordered_flat_set&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_flat_set(unordered_flat_set&& other, Allocator const& a); -If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +``` + +如果 `a == other.get++_++allocator()` ,则 `other` 的元素直接转移到新容器;否则,元素从 `other` 的元素移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。如果统计功能已 xref:#unordered_flat_set_boost_unordered_enable_stats[启用] ,则当 `a == other.get++_++allocator()` 时,同时转移其内部统计信息,并始终调用 `other.reset++_++stats()` 。 --- -==== Move Constructor from concurrent_flat_set +==== 从 concurrent++_++flat++_++set 的移动构造函数 + +```c++ + +unordered_flat_set(concurrent_flat_set&& other); -```c++ unordered_flat_set(concurrent_flat_set&& other); ``` +``` -Move construction from a xref:#concurrent_flat_set[`concurrent_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +从 #xref:#concurrent_flat_set[`concurrent_flat_set`][`concurrent++_++flat++_++set`] 移动构造。 `other` 的内部桶数组直接转移到新容器。哈希函数、谓词和分配器从 `other` 移动构造。如果统计功能已 xref:#unordered_flat_set_boost_unordered_enable_stats[启用] ,则同时转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度;; 常数时间复杂度。 +并发性;; 阻塞于 `other` 。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_flat_set(std::initializer_list il, size_type n = _implementation-defined_ @@ -398,617 +449,946 @@ unordered_flat_set(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_flat_set(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_flat_set(size_type n, allocator_type const& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_flat_set(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +unordered_flat_set(size_type n, hasher const& hf, allocator_type const& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_flat_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ -```c++ unordered_flat_set(std::initializer_list il, const allocator_type& a); ``` +unordered_flat_set(std::initializer_list il, const allocator_type& a); -Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ + +unordered_flat_set(std::initializer_list il, size_type n, const allocator_type& a); -```c++ unordered_flat_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +``` -Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_flat_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +unordered_flat_set(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器、默认键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~unordered_flat_set(); ``` +~unordered_flat_set(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 -==== Copy Assignment +==== 复制赋值 -```c++ unordered_flat_set& operator=(unordered_flat_set const& other); ``` +```c++ -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +unordered_flat_set& operator=(unordered_flat_set const& other); + +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 --- -==== Move Assignment -```c++ unordered_flat_set& operator=(unordered_flat_set&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +unordered_flat_set& operator=(unordered_flat_set&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值操作符。该操作会销毁容器中原有的元素,交换 `other` +的哈希函数与键相等性谓词。若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则直接将 `other` +的内部桶数组转移至当前容器;否则,将插入 `other` +中元素的移动构造副本。若已启用统计功能,则当且仅当最终分配器与 +`other.get++_++allocator()` 相等时,同时转移其内部统计信息,并始终调用 +`other.reset++_++stats()` 。 --- -==== Initializer List Assignment -```c++ unordered_flat_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +unordered_flat_set& operator=(std::initializer_list il); -Assign from values in initializer list. All previously existing elements are destroyed. +``` + +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 -```c++ size_type size() const noexcept; ``` +```c++ + +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size -```c++ size_type max_size() const noexcept; ``` +```c++ + +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +==== 原地构造 +```c++ -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +template std::pair emplace(Args&&... args); + +``` + +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 -`position` is a suggestion to where the element should be inserted. This implementation ignores it. +`position` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +std::pair insert(const value_type& obj); + +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +std::pair insert(value_type&& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Transparent Insert -```c++ template std::pair insert(K&& k); ``` +==== 透明插入 +```c++ -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +template std::pair insert(K&& k); + +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ + +iterator insert(const_iterator hint, const value_type& obj); + +``` 当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +iterator insert(const_iterator hint, value_type&& obj); -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Transparent Insert with Hint -```c++ template std::pair insert(const_iterator hint, K&& k); ``` +==== 带提示的透明插入 +```c++ + +template std::pair insert(const_iterator hint, K&& k); + +``` -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +template void insert(InputIterator first, InputIterator last); + +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 必须能够通过 `++*++first` 在容器中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, pointers and references, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载大于最大负载时。 --- -==== Erase by Position +==== 通过位置擦除 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- _convertible-to-iterator_ erase(iterator position); _convertible-to-iterator_ erase(const_iterator position); ---- -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. +返回;; 返回一个不透明对象,该对象可隐式转换为擦除前紧接在 `position` 之后的 `iterator` 或 `const++_++iterator` 。 +抛出;; 无。 +注意;; 返回的不透明对象必须被立即丢弃或转换为 `iterator` 或 `const++_++iterator` 。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ -Erase all elements with key equivalent to `k`. +size_type erase(const key_type& k); template size_type erase(K&& k); + +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 -```c++ iterator erase(const_iterator first, const_iterator last); ``` +```c++ + +iterator erase(const_iterator first, const_iterator last); + +``` -Erases the elements in the range from `first` to `last`. +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 在此实现中不抛出任何异常(既不调用 `hasher` , 也不调用 `key++_++equal` 对象)。 --- -==== swap -```c++ void swap(unordered_flat_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ -Swaps the contents of the container with the parameter. +void swap(unordered_flat_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- ==== pull -```c++ init_type pull(const_iterator position); ``` +```c++ + +init_type pull(const_iterator position); + +``` -Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. +从 `position` 指向的元素移动构造一个 `init++_++value` 对象 `x` ,擦除该元素并返回 `x` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ -Erases all elements in the container. +void clear() noexcept; + +``` + +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` --- -==== merge -```c++ template void merge(unordered_flat_set& source); template void merge(unordered_flat_set&& source); ``` +==== 合并 +```c++ + +template + void merge(unordered_flat_set& source); +template + void merge(unordered_flat_set&& source); + +``` -Move-inserts all the elements from `source` whose key is not already present in `*this`, and erases them from `source`. +对 `source` 中所有键不在 `++*++this` 中的元素执行移动插入操作,并将这些元素从 `source` 中擦除。 --- -=== Observers +=== 观察器 -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +==== get++_++allocator +``` + +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The container's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器;若不存在这样的元素,则返回 `end()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the container's maximum load factor. +返回;; 容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++set` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) + +```c++ -```c++ size_type max_load() const noexcept; ``` +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. +返回;; 返回容器在不重哈希的情况下可容纳的最大元素数(假设不再擦除元素)。 +注意;; 在构造、重新哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。若使用的分配器采用花式指针,随后会执行默认分配操作。 -Invalidates iterators, pointers and references, and changes the order of elements. +使迭代器、指针和引用失效,并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +void reserve(size_type n); -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +``` + +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 + +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 -Invalidates iterators, pointers and references, and changes the order of elements. +使迭代器、指针和引用失效,并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Statistics +=== 统计信息 -==== get_stats -```c++ stats get_stats() const; ``` +==== get++_++stats +```c++ + +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. +返回;; 返回容器直到目前已执行插入和查找操作的统计摘要。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能被 xref:#unordered_flat_set_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. +效果;; 将容器维护的内部统计信息清零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能被 xref:#unordered_flat_set_boost_unordered_enable_stats[启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 -==== operator -```c++ template bool operator==(const unordered_flat_set& x, const unordered_flat_set& y); ``` +==== operator== +```c++ + +template + bool operator==(const unordered_flat_set& x, + const unordered_flat_set& y); + +``` -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_flat_set& x, const unordered_flat_set& y); ``` +==== operator!= +```c++ -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +template + bool operator!=(const unordered_flat_set& x, + const unordered_flat_set& y); + +``` + +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 -=== Swap -```c++ template void swap(unordered_flat_set& x, unordered_flat_set& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_flat_set& x, + unordered_flat_set& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -=== erase_if -```c++ template typename unordered_flat_set::size_type erase_if(unordered_flat_set& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_flat_set::size_type + erase_if(unordered_flat_set& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` -=== Serialization +=== 序列化 -``unordered_flat_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++flat++_++set` 可通过本库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_flat_set to an archive +==== 将 unordered++_++flat++_++set 保存到归档 -Saves all the elements of an `unordered_flat_set` `x` to an archive (XML archive) `ar`. +将 `unordered++_++flat++_++set` `x` 的所有元素保存到归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 --- -==== Loading an unordered_flat_set from an archive +==== 从归档加载 unordered++_++flat++_++set -Deletes all preexisting elements of an `unordered_flat_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_flat_set` `other` saved to the storage read by `ar`. +删除 `unordered++_++flat++_++set` 容器 `x` 中存在的所有现有元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++flat++_++set` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `x.key_equal()` is functionally equivalent to `other.key_equal()`. +要求;; `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_flat_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 所指向的 `unordered++_++flat++_++set` 容器 `x` 先前已被保存至 `ar` ,且在保存 `x` 与保存 `it` 期间未对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_flat_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 如果 `x` 为 `it` 所指向的 `unordered++_++flat++_++set` 容器,则在加载 `x` 和加载 `it` 期间未对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc index 74585c9..eff4b36 100644 --- a/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc @@ -1,13 +1,13 @@ [#unordered_map] -== Class Template unordered_map +== 类模板 unordered++_++map :idprefix: unordered_map_ -`boost::unordered_map` — An unordered associative container that associates unique keys with another value. +`boost::unordered++_++map` — 一个无序关联容器,用于将唯一的键与另一个值关联起来。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_map.adoc[] @@ -180,7 +180,7 @@ namespace unordered { CompatiblePredicate const& eq); template const_iterator xref:#unordered_map_find[find](CompatibleKey const& k, CompatibleHash const& hash, - CompatiblePredicate const& eq) const; + CompatiblePredicate const& eq) const; size_type xref:#unordered_map_count[count](const key_type& k) const; template size_type xref:#unordered_map_count[count](const K& k) const; @@ -273,112 +273,118 @@ namespace unordered { Allocator) -> unordered_map, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|_键_ +|`Key` +需满足从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求(即 +`allocator++_++traits` 能够销毁该对象)。 |_T_ -|`T` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|`T` +需满足从容器 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] +的要求(即 `allocator++_++traits` 能够销毁该对象)。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. +|_谓词_ +|一种二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` +的参数,并返回一个布尔类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. +元素被组织到多个桶中。具有相同哈希码的键存储在同一个桶内。 -The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. +桶的数量可通过调用插入操作来自动增加,也可通过调用重哈希操作来调整。 -=== Configuration macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` +==== `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` -Globally define this macro to support loading of ``unordered_map``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. +全局定义此宏,以支持加载在 Boost.Serialization 归档中保存的 `unordered++_++map` 容器,这些归档是保存在 Boost 1.84 之前的版本中。 -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -An iterator whose value type is `value_type`. +一种迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ local_iterator; ---- -An iterator with the same value type, difference type and pointer and reference type as iterator. +一种迭代器,其值类型、差值类型以及指针和引用类型均与 iterator 相同。 -A `local_iterator` object can be used to iterate through a single bucket. +`local++_++iterator` 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_local_iterator; ---- -A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. +一种常量迭代器,其值类型、差值类型以及指针和引用类型均与 const++_++iterator 相同。 -A const_local_iterator object can be used to iterate through a single bucket. +const++_++local++_++iterator 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存已提取容器元素的类,其建模自 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -389,34 +395,47 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `Iterator` = `iterator` and `NodeType` = `node_type`. +其中 `Iterator` = `iterator` ,且 `NodeType` = `node++_++type` 。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_map(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. +unordered_map(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、 `allocator++_++type()` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit unordered_map(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数, `eql` 作为键相等性谓词, `a` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_map(InputIterator f, InputIterator l, @@ -426,71 +445,98 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,将最大负载因子设为 `1.0` ,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_map(unordered_map const& other); ``` +==== 复制构造函数 +```c++ + +unordered_map(unordered_map const& other); + +``` -The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. +复制构造函数。复制其所含的元素、哈希函数、谓词、最大负载因子及分配器。 -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_map(unordered_map&& other); ``` +==== 移动构造函数 +```c++ + +unordered_map(unordered_map&& other); + +``` -The move constructor. +移动构造函数。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 必须满足可移动构造的要求。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_map(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + unordered_map(InputIterator f, InputIterator l, const allocator_type& a); + +``` -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并将最大负载因子设为 `1.0` ,然后将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_map(Allocator const& a); ``` +==== 分配器构造函数 +```c++ -Constructs an empty container, using allocator `a`. +explicit unordered_map(Allocator const& a); + +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_map(unordered_map const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_map(unordered_map const& other, Allocator const& a); -Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. +``` + +构造一个容器,复制 `other` 中的元素、哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_map(unordered_map&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_map(unordered_map&& other, Allocator const& a); + +``` -Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. +构造一个容器,移动 `other` 中所包含的元素,并获取其哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 需满足可移动插入要求。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_map(std::initializer_list il, size_type n = _implementation-defined_ @@ -499,755 +545,1256 @@ unordered_map(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、及 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_map(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_map(size_type n, allocator_type const& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数(应为默认哈希函数)、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_map(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +unordered_map(size_type n, hasher const& hf, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 -```c++ unordered_map(std::initializer_list il, const allocator_type& a); ``` +```c++ -Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +unordered_map(std::initializer_list il, const allocator_type& a); + +``` + +使用 `a` 作为分配器构造一个空容器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ + +unordered_map(std::initializer_list il, size_type n, const allocator_type& a); -```c++ unordered_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +``` -Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器,并设置最大负载因子为 1.0,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +unordered_map(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 -```c++ ~unordered_map(); ``` +```c++ + +~unordered_map(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ unordered_map& operator=(unordered_map const& other); ``` +unordered_map& operator=(unordered_map const& other); -The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. +``` + +赋值运算符。该操作会复制容器内的元素、哈希函数、谓词及最大负载因子,但不会复制分配器。 -If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. +如果 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Assignment -```c++ unordered_map& operator=(unordered_map&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. +==== 移动赋值 +```c++ -If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. +unordered_map& operator=(unordered_map&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + +``` +移动赋值运算符。 + +如果 `Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++move++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is move constructible. +要求;; `value++_++type` 需满足可移动构造要求。 --- -==== Initializer List Assignment -```c++ unordered_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +unordered_map& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. +将初始化列表中的值赋给容器。所有已存在的元素将被新元素覆盖或销毁。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. +要求;; `value++_++type` 必须满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 至容器以及 https://en.cppreference.com/w/cpp/named_req/CopyAssignable[可复制赋值] 的要求。 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 -```c++ size_type size() const noexcept; ``` +```c++ + +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size + +```c++ -```c++ size_type max_size() const noexcept; ``` +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template std::pair emplace(Args&&... args); -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。当映射的 `key++_++type` 可移动构造,或参数 `k` 的类型为 `key++_++type` 时,此优化生效。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 -`position` is a suggestion to where the element should be inserted. +`position` 是一个关于插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when the map's `key_type` is move constructible or when the `k` argument is a `key_type`. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +若 `args…` 的格式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。当映射的 `key++_++type` 可移动构造,或参数 `k` 的类型为 `key++_++type` 时,此优化生效。 --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +std::pair insert(const value_type& obj); + +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +std::pair insert(value_type&& obj); -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Emplace Insert -```c++ template std::pair insert(P&& obj); ``` +==== 原地插入 +```c++ -Inserts an element into the container by performing `emplace(std::forward

(value))`. +template std::pair insert(P&& obj); + +``` -Only participates in overload resolution if `std::is_constructible::value` is `true`. +通过执行 `emplace(std::forward++<++P++>++(value))` 将元素插入容器。 + +仅当 `std::is++_++constructible++<++value++_++type, P&&++>++::value` 为 `true` 时,才会参与重载决议。 [horizontal] -Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ + +iterator insert(const_iterator hint, const value_type& obj); -`hint` is a suggestion to where the element should be inserted. +``` 当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +iterator insert(const_iterator hint, value_type&& obj); -`hint` is a suggestion to where the element should be inserted. +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Emplace Insert with Hint +==== 带提示的原地插入 + +```c++ -```c++ template iterator insert(const_iterator hint, P&& obj); ``` +template iterator insert(const_iterator hint, P&& obj); -Inserts an element into the container by performing `emplace_hint(hint, std::forward

(value))`. +``` + +通过执行 `emplace++_++hint(hint, std::forward++<++P++>++(value))` 将元素插入容器。 -Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅当 `std::is++_++constructible++<++value++_++type, P&&++>++::value` 为 `true` 时,才会参与重载决议。 -`hint` is a suggestion to where the element should be inserted. +`hint` 是插入元素位置的建议。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须能够通过 `++*++first` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到 `X` 中。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== try_emplace -```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args) ``` +==== try++_++emplace +```c++ -Inserts a new element into the container if there is no existing element with key `k` contained within it. +template + std::pair try_emplace(const key_type& k, Args&&... args); +template + std::pair try_emplace(key_type&& k, Args&&... args); +template + std::pair try_emplace(K&& k, Args&&... args) -If there is an existing element with key `k` this function does nothing. +``` + +若容器中不存在键为 `k` 的元素,则插入一个新元素。 + +若存在键为 `k` 的元素,则此函数不执行任何操作。 [horizontal] -Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_map_emplace[emplace] except the `value_type` is constructed using: + + -- ```c++ +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_map_emplace[emplace] 类似,但 `value++_++type` 的构造方式为: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) + +``` -instead of xref:#unordered_map_emplace[emplace] which simply forwards all arguments to ``value_type``'s constructor. +而非 xref:#unordered_map_emplace[emplace] 直接转发所有参数到 ``value_type`` 的构造函数。 -Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时。 -Pointers and references to elements are never invalidated. +指向元素的指针和引用永远不会失效。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. -- +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 +-- --- -==== try_emplace with Hint -```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` +==== 带提示的 try++_++emplace +```c++ -Inserts a new element into the container if there is no existing element with key `k` contained within it. +template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, K&& k, Args&&... args); -If there is an existing element with key `k` this function does nothing. +``` + +若容器中不存在键为 `k` 的元素,则插入一个新元素。 -`hint` is a suggestion to where the element should be inserted. +若存在键为 `k` 的元素,则此函数不执行任何操作。 + +`hint` 是插入元素位置的建议。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_map_emplace_hint[emplace_hint] except the `value_type` is constructed using: + + -- ```c++ +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_map_emplace_hint[emplace++_++hint] 类似,但 `value++_++type` 的构造方式为: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) + +``` -instead of xref:#unordered_map_emplace_hint[emplace_hint] which simply forwards all arguments to ``value_type``'s constructor. +而非 xref:#unordered_map_emplace_hint[emplace_hint] 直接转发所有参数到 ``value_type`` 的构造函数。 -The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. +标准对提示的含义相当模糊。但唯一实用的使用方式(也是 Boost.Unordered 支持的唯一方式)是指向具有相同键的现有元素。 -Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时。 -Pointers and references to elements are never invalidated. +指向元素的指针和引用永远不会失效。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. -- +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 +-- --- -==== insert_or_assign -```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` +==== insert++_++or++_++assign +```c++ -Inserts a new element into the container or updates an existing one by assigning to the contained value. +template + std::pair insert_or_assign(const key_type& k, M&& obj); +template + std::pair insert_or_assign(key_type&& k, M&& obj); +template + std::pair insert_or_assign(K&& k, M&& obj); -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +``` + +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 + +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` [horizontal] -Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== insert_or_assign with Hint -```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` +==== 带提示的 insert++_++or++_++assign +```c++ -Inserts a new element into the container or updates an existing one by assigning to the contained value. +template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +``` + +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 + +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` -`hint` is a suggestion to where the element should be inserted. +`hint` 是插入元素位置的建议。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== Extract by Iterator -```c++ node_type extract(const_iterator position); ``` +==== 通过迭代器提取 +```c++ + +node_type extract(const_iterator position); + +``` -Removes the element pointed to by `position`. +移除由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. +返回;; 返回一个拥有该元素的 `node++_++type` 对象。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++multimap` 容器中。 --- -==== Extract by Key -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键提取 +```c++ -Removes an element with key equivalent to `k`. +node_type extract(const key_type& k); template node_type extract(K&& k); + +``` + +移除键等价于 `k` 的元素。 [horizontal] -Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_multimap`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果找到,则返回一个拥有该元素的 `node++_++type` 对象;否则返回一个空的 `node++_++type` 对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++multimap` 容器中。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert with `node_handle` -```c++ insert_return_type insert(node_type&& nh); ``` +==== 通过 `node++_++handle` 插入 +```c++ + +insert_return_type insert(node_type&& nh); -If `nh` is empty, has no effect. +``` + +若 `nh` 为空节点,则此操作不产生任何效果。 -Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. +否则,当且仅当容器中不存在等价键的元素时,才会插入 `nh` 所拥有的元素。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns an `insert_return_type` with: `inserted` equal to `false`, `position` equal to `end()` and `node` empty. + + Otherwise if there was already an element with an equivalent key, returns an `insert_return_type` with: `inserted` equal to `false`, `position` pointing to a matching element and `node` contains the node from `nh`. + + Otherwise if the insertion succeeded, returns an `insert_return_type` with: `inserted` equal to `true`, `position` pointing to the newly inserted element and `node` empty. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multimap`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 如果 `nh` 为空,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `false` , `position` 等于 `end()` ,且 `node` 为空。 + ++ +否则,如果已存在具有等价键的元素,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `false` , `position` 指向匹配的元素,且 `node` 包含来自 `nh` 的节点。 + ++ +否则,如果插入操作成功,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `true` , `position` 指向新插入的元素,且 `node` 为空。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++multimap` 容器中提取的节点。 --- -==== Insert with Hint and `node_handle` -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示和 `node++_++handle` 的插入 +```c++ -If `nh` is empty, has no effect. +iterator insert(const_iterator hint, node_type&& nh); + +``` -Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. +若 `nh` 为空节点,则此操作不产生任何效果。 -If there is already an element in the container with an equivalent key has no effect on `nh` (i.e. `nh` still contains the node.) +否则,当且仅当容器中不存在等价键的元素时,才会插入 `nh` 所拥有的元素。 -`hint` is a suggestion to where the element should be inserted. +如果容器中已存在具有等价键的元素,则对 `nh` 不产生任何影响.(即 `nh` 仍持有该节点.) + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty returns `end()`. + + If there was already an element in the container with an equivalent key returns an iterator pointing to that. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multimap`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 如果 `nh` 为空,则返回 `end()` 。 + ++ +若容器中已存在具有等效键的元素,则返回指向该元素的迭代器。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由调用 hasher 以外的操作抛出,则此函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++multimap` 容器中提取的节点。 --- -==== Erase by Position +==== 通过位置擦除 + +```c++ -```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` +iterator erase(iterator position); iterator erase(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. +返回;; 返回擦除操作前紧接在 `position` 之后的迭代器。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 在旧版本中,此操作可能效率较低,因为需要遍历多个桶来定位返回迭代器的位置。但数据结构现已优化,不再存在此问题,因此其他擦除方法已被弃用。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ -Erase all elements with key equivalent to `k`. +size_type erase(const key_type& k); template size_type erase(K&& k); + +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 -```c++ iterator erase(const_iterator first, const_iterator last); ``` +```c++ -Erases the elements in the range from `first` to `last`. +iterator erase(const_iterator first, const_iterator last); + +``` + +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 --- -==== quick_erase -```c++ void quick_erase(const_iterator position); ``` +==== quick++_++erase +```c++ -Erase the element pointed to by `position`. +void quick_erase(const_iterator position); + +``` + +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== erase_return_void -```c++ void erase_return_void(const_iterator position); ``` +==== erase++_++return++_++void +```c++ + +void erase_return_void(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== swap -```c++ void swap(unordered_map& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` +==== 交换 +```c++ + +void swap(unordered_map& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); + +``` -Swaps the contents of the container with the parameter. +交换容器与参数的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -==== clear -```c++ void clear(); ``` +==== 清空 +```c++ -Erases all elements in the container. +void clear(); + +``` + +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0` Throws:;; Never throws an exception. +后置条件;; `size() == 0` +抛出;; 从不抛出任何异常。 --- -==== merge -```c++ template void merge(unordered_map& source); template void merge(unordered_map&& source); template void merge(unordered_multimap& source); template void merge(unordered_multimap&& source); ``` +==== 合并 +```c++ + +template + void merge(unordered_map& source); +template + void merge(unordered_map&& source); +template + void merge(unordered_multimap& source); +template + void merge(unordered_multimap&& source); -Attempt to "merge" two containers by iterating `source` and extracting any node in `source` that is not contained in `*this` and then inserting it into `*this`. +``` + +通过遍历 `source` 容器,提取其中所有不包含在 `++*++this` 中的节点,并将其插入到 `++*++this` 中,以此尝试将两个容器"合并"。 -Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. +由于 `source` 可以有不同的哈希函数和键相等性谓词,因此会使用 `this-++>++hash++_++function()` 操作对 `source` 中每个节点的键进行重哈希,并在需要时使用 `this-++>++key++_++eq()` 进行比较。 -The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. +如果 `this-++>++get++_++allocator() != source.get++_++allocator()` ,则此函数的行为未定义。 -This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. +此函数不会复制或移动任何元素,而是直接将节点从 `source` 重新定位到 `++*++this` 中。 [horizontal] -Notes:;; + -- -* Pointers and references to transferred elements remain valid. -* Invalidates iterators to transferred elements. -* Invalidates iterators belonging to `*this`. -* Iterators to non-transferred elements in `source` remain valid. +注意;; ++ +-- +* 指向被转移元素的指针和引用保持有效。 +* 使指向被转移元素的迭代器失效。 +* 使属于 `++*++this` 的迭代器失效。 +* 指向 `source` 中未被转移元素的迭代器保持有效。 -- ---- +* --- -=== Observers +=== 观察器 -==== get_allocator -``` allocator_type get_allocator() const; ``` +==== get++_++allocator +``` + +allocator_type get_allocator() const; + +``` --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); +template + const_iterator find(const K& k) const; +template + iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); +template + const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器,若不存在这样的元素,则返回 `b.end()` 。 +注意;; 包含 `CompatibleKey` 、 `CompatibleHash` 和 `CompatiblePredicate` 的模板化重载是非标准扩展,允许用户使用兼容的哈希函数和相等性谓词来处理不同类型的键,以避免昂贵的类型转换。通常不鼓励使用此扩展,而应改用基于 `K` 的成员函数模板。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== operator++[++++]++ -```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` +==== operator++[]++ +```c++ + +mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); + +``` [horizontal] -Effects:;; If the container does not already contain an elements with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +效果;; 若容器中尚不存键等价于 `k` 的元素,则插入值 `std;;pair++<++key++_++type const, mapped++_++type++>++(k, mapped++_++type())` 。 +返回;; 返回一个引用,该引用指向容器中已存在的键等于 `k` 的元素 `x` 的 `x.second` 成员;若元素不存在,则指向新插入元素的该成员。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== at -```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` +```c++ + +mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; + +``` [horizontal] -Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个引用,该引用指向键等价于 `k` 的(唯一)元素 `x` 的 `x.second` 成员。 +抛出;; 如果不存在这样的元素,则抛出类型为 `std::out++_++of++_++range` 的异常对象。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The number of buckets. +返回;; 桶的数量。 --- -==== max_bucket_count -```c++ size_type max_bucket_count() const noexcept; ``` +==== max++_++bucket++_++count +```c++ + +size_type max_bucket_count() const noexcept; + +``` [horizontal] -Returns:;; An upper bound on the number of buckets. +返回;; 桶数量的上限。 --- -==== bucket_size -```c++ size_type bucket_size(size_type n) const; ``` +==== 桶大小 +```c++ + +size_type bucket_size(size_type n) const; + +``` [horizontal] -Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. +要求;; `n ++<++ bucket++_++count()` +返回;; 返回桶 `n` 中的元素数量。 --- -==== bucket -```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` +==== 桶 +```c++ + +size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; + +``` [horizontal] -Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键为 `k` 的元素所在桶的索引。 +后置条件;; 返回值应小于 `bucket++_++count()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== begin -```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` +```c++ + +local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的局部迭代器。 --- ==== end -```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` +```c++ + +local_iterator end(size_type n); const_local_iterator end(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的局部迭代器。 --- ==== cbegin -```c++ const_local_iterator cbegin(size_type n) const; ``` +```c++ + +const_local_iterator cbegin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的常量局部迭代器。 --- ==== cend -```c++ const_local_iterator cend(size_type n) const; ``` +```c++ + +const_local_iterator cend(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的常量局部迭代器。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; The average number of elements per bucket. +返回;; 返回每个桶的平均元素数量。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) -```c++ float max_load_factor() const noexcept; ``` +```c++ + +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the current maximum load factor. +返回;; 返回当前的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Changes the container's maximum load factor, using `z` as a hint. +效果;; 使用 `z` 作为提示来更改容器的最大负载因子。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +改变桶的数量,使其至少为 `n` 个,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器关联的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ + +void reserve(size_type n); + +``` -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` ,若 `n ++>++ 0` 且 `a.max++_++load++_++factor() == std::numeric++_++limits++<++float++>++::infinity()` ,则等价于 `a.rehash(1)` 。 -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1255,104 +1802,149 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template - using __iter-key-type__ = std::remove_const_t< - std::tuple_element_t<0, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only + using __iter-key-type__ = std;;remove_const_t< + std;;tuple_element_t<0, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = - std::tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>; // exposition only + std;;tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>; // exposition only ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template - using __iter-to-alloc-type__ = std::pair< - std::add_const_t>>, - std::tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only + using __iter-to-alloc-type__ = std;;pair< + std;;add_const_t>>, + std;;tuple_element_t<1, xref:#unordered_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 -==== operator -```c++ template bool operator==(const unordered_map& x, const unordered_map& y); ``` +==== operator== +```c++ -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +template + bool operator==(const unordered_map& x, + const unordered_map& y); + +``` + +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_map& x, const unordered_map& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const unordered_map& x, + const unordered_map& y); -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +``` + +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 -=== Swap -```c++ template void swap(unordered_map& x, unordered_map& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ -Swaps the contents of `x` and `y`. +template + void swap(unordered_map& x, + unordered_map& y) + noexcept(noexcept(x.swap(y))); + +``` -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +交换 `x` 与 `y` 的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -=== erase_if -```c++ template typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename unordered_map::size_type + erase_if(unordered_map& c, Predicate pred); + +``` -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` ++ +请注意,传递给 `pred` 的引用是非常量的。 -=== Serialization +=== 序列化 -``unordered_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++map` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_map to an archive +==== 将 unordered++_++map 保存到归档 -Saves all the elements of an `unordered_map` `x` to an archive (XML archive) `ar`. +将 `unordered++_++map` 容器 `x` 的所有元素保存到归档(XML 归档) `ar` 中。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 --- -==== Loading an unordered_map from an archive +==== 从归档加载 unordered++_++map -Deletes all preexisting elements of an `unordered_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_map` `other` saved to the storage read by `ar`. +删除 `unordered++_++map` 容器 `x` 的所有现有元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++map` `other` 的元素副本,这些副本是从 `ar` 读取的存储中恢复的。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `(std::remove_const::type&&, std::remove_const::type&&)`. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. +要求;; `value++_++type` 必须能够从 `(std::remove++_++const++<++key++_++type++>++::type&&, std::remove++_++const++<++mapped++_++type++>++::type&&)` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] ,且 `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +注意;; 若归档文件是使用 Boost 1.84 之前的版本保存的,则必须全局定义配置宏 `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` 才能成功执行此操作;否则将抛出异常。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 指向的 `unordered++_++map` `x` 必须先前已保存到 `ar` ,并且在保存 `x` 和保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 如果 `x` 是 `it` 所指向的 `unordered++_++map` 容器,则在加载 `x` 和加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc index 851edeb..9fb7d0a 100644 --- a/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc @@ -1,13 +1,13 @@ [#unordered_multimap] -== Class Template unordered_multimap +== 类模板 unordered++_++multimap :idprefix: unordered_multimap_ -`boost::unordered_multimap` — An unordered associative container that associates keys with another value. The same key can be stored multiple times. +`boost::unordered++_++multimap` —— 一种无序关联容器,用于将键与另一个值相关联。同一键可被存储多次。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_map.adoc[] @@ -240,128 +240,147 @@ namespace unordered { Hash, Allocator) -> unordered_multimap, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|_键_ +|`Key` +需满足从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求(即 +`allocator++_++traits` 能够销毁该对象)。 |_T_ -|`T` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|`T` +需满足从容器 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] +的要求(即 `allocator++_++traits` 能够销毁该对象)。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. +|_谓词_ +|一种二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` +的参数,并返回一个布尔类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. +元素被组织到多个桶中。具有相同哈希码的键存储在同一个桶内。 -The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. +桶的数量可通过调用插入操作来自动增加,也可通过调用重哈希操作来调整。 -=== Configuration macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` +==== `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` -Globally define this macro to support loading of ``unordered_multimap``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. +全局定义此宏以支持加载在 Boost 1.84 之前版本中保存到 Boost.Serialization 归档的 `unordered++_++multimap` 。 -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -An iterator whose value type is `value_type`. +一种迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ local_iterator; ---- -An iterator with the same value type, difference type and pointer and reference type as iterator. +一种迭代器,其值类型、差值类型以及指针和引用类型均与 iterator 相同。 -A `local_iterator` object can be used to iterate through a single bucket. +`local++_++iterator` 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_local_iterator; ---- -A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. +一种常量迭代器,其值类型、差值类型以及指针和引用类型均与 const++_++iterator 相同。 -A const_local_iterator object can be used to iterate through a single bucket. +const++_++local++_++iterator 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -See node_handle_map for details. +有关详细信息,请参阅 node++_++handle++_++map。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_multimap(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. +unordered_multimap(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、 `allocator++_++type()` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_multimap(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +explicit unordered_multimap(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数, `eql` 作为键相等性谓词, `a` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multimap(InputIterator f, InputIterator l, @@ -371,71 +390,98 @@ unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,将最大负载因子设为 `1.0` ,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_multimap(const unordered_multimap& other); ``` +==== 复制构造函数 +```c++ + +unordered_multimap(const unordered_multimap& other); -The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. +``` + +复制构造函数。复制其所含的元素、哈希函数、谓词、最大负载因子及分配器。 -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_multimap(unordered_multimap&& other); ``` +==== 移动构造函数 +```c++ -The move constructor. +unordered_multimap(unordered_multimap&& other); + +``` + +移动构造函数。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 必须满足可移动构造的要求。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +template + unordered_multimap(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并将最大负载因子设为 `1.0` ,然后将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_multimap(const Allocator& a); ``` +==== 分配器构造函数 +```c++ -Constructs an empty container, using allocator `a`. +explicit unordered_multimap(const Allocator& a); + +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_multimap(const unordered_multimap& other, const Allocator& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_multimap(const unordered_multimap& other, const Allocator& a); -Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. +``` + +构造一个容器,复制 `other` 中的元素、哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_multimap(unordered_multimap&& other, const Allocator& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_multimap(unordered_multimap&& other, const Allocator& a); + +``` -Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. +构造一个容器,移动 `other` 中所包含的元素,并获取其哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 需满足可移动插入要求。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_multimap(std::initializer_list il, size_type n = _implementation-defined_, @@ -444,643 +490,1017 @@ unordered_multimap(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、及 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_multimap(size_type n, const allocator_type& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_multimap(size_type n, const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数(应为默认哈希函数)、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_multimap(size_type n, const hasher& hf, const allocator_type& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +unordered_multimap(size_type n, const hasher& hf, const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 -```c++ unordered_multimap(std::initializer_list il, const allocator_type& a); ``` +```c++ + +unordered_multimap(std::initializer_list il, const allocator_type& a); + +``` -Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +使用 `a` 作为分配器构造一个空容器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 -```c++ unordered_multimap(std::initializer_list il, size_type n, const allocator_type& a); ``` +```c++ -Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +unordered_multimap(std::initializer_list il, size_type n, const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器,并设置最大负载因子为 1.0,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 -```c++ unordered_multimap(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +unordered_multimap(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~unordered_multimap(); ``` +~unordered_multimap(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 -==== Copy Assignment +==== 复制赋值 -```c++ unordered_multimap& operator=(const unordered_multimap& other); ``` +```c++ -The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. +unordered_multimap& operator=(const unordered_multimap& other); + +``` -If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. +赋值运算符。该操作会复制容器内的元素、哈希函数、谓词及最大负载因子,但不会复制分配器。 + +如果 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Assignment -```c++ unordered_multimap& operator=(unordered_multimap&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. +==== 移动赋值 +```c++ + +unordered_multimap& operator=(unordered_multimap&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); -If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. +``` +移动赋值运算符。 + +如果 `Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++move++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is move constructible. +要求;; `value++_++type` 需满足可移动构造要求。 --- -==== Initializer List Assignment -```c++ unordered_multimap& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +unordered_multimap& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. +将初始化列表中的值赋给容器。所有已存在的元素将被新元素覆盖或销毁。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. +要求;; `value++_++type` 必须满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 至容器以及 https://en.cppreference.com/w/cpp/named_req/CopyAssignable[可复制赋值] 的要求。 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ -```c++ size_type size() const noexcept; ``` +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size -```c++ size_type max_size() const noexcept; ``` +```c++ + +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ -==== emplace -```c++ template iterator emplace(Args&&... args); ``` +template iterator emplace(Args&&... args); -Inserts an object, constructed with the arguments `args`, in the container. +``` + +向容器中插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments args, in the container. +向容器中插入一个由参数 args 构造的对象。 -`position` is a suggestion to where the element should be inserted. +`position` 是一个关于插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Copy Insert -```c++ iterator insert(const value_type& obj); ``` +==== 复制插入 +```c++ + +iterator insert(const value_type& obj); + +``` -Inserts `obj` in the container. +向容器中插入 `obj` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert -```c++ iterator insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +iterator insert(value_type&& obj); + +``` -Inserts `obj` in the container. +向容器中插入 `obj` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Emplace Insert -```c++ template iterator insert(P&& obj); ``` +==== 原地插入 +```c++ + +template iterator insert(P&& obj); + +``` -Inserts an element into the container by performing `emplace(std::forward

(value))`. +通过执行 `emplace(std::forward++<++P++>++(value))` 将元素插入容器。 -Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅当 `std::is++_++constructible++<++value++_++type, P&&++>++::value` 为 `true` 时,才会参与重载决议。 [horizontal] -Returns:;; An iterator pointing to the inserted element. +返回;; 返回一个指向插入元素的迭代器。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container. +==== 带提示的复制插入 +```c++ -`hint` is a suggestion to where the element should be inserted. +iterator insert(const_iterator hint, const value_type& obj); + +``` 将 `obj` 插入容器中。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ -Inserts `obj` in the container. +iterator insert(const_iterator hint, value_type&& obj); + +``` -`hint` is a suggestion to where the element should be inserted. +向容器中插入 `obj` 。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Emplace Insert with Hint -```c++ template iterator insert(const_iterator hint, P&& obj); ``` +==== 带提示的原地插入 +```c++ + +template iterator insert(const_iterator hint, P&& obj); -Inserts an element into the container by performing `emplace_hint(hint, std::forward

(value))`. +``` -Only participates in overload resolution if `std::is_constructible::value` is `true`. +通过执行 `emplace++_++hint(hint, std::forward++<++P++>++(value))` 将元素插入容器。 -`hint` is a suggestion to where the element should be inserted. +仅当 `std::is++_++constructible++<++value++_++type, P&&++>++::value` 为 `true` 时,才会参与重载决议。 + +`hint` 是插入元素位置的建议。 [horizontal] -Returns:;; An iterator pointing to the inserted element. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +返回;; 返回一个指向插入元素的迭代器。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); + +``` -Inserts a range of elements into the container. +将元素范围插入容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须能够通过 `++*++first` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到 `X` 中。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list il); + +``` -Inserts a range of elements into the container. +将元素范围插入容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Extract by Iterator -```c++ node_type extract(const_iterator position); ``` +==== 通过迭代器提取 +```c++ -Removes the element pointed to by `position`. +node_type extract(const_iterator position); + +``` + +移除由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. +返回;; 返回一个拥有该元素的 `node++_++type` 对象。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++map` 容器中。 --- -==== Extract by Key -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键提取 +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); + +``` -Removes an element with key equivalent to `k`. +移除键等价于 `k` 的元素。 [horizontal] -Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_map`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果找到,则返回一个拥有该元素的 `node++_++type` 对象;否则返回一个空的 `node++_++type` 对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++map` 容器中。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert with `node_handle` -```c++ iterator insert(node_type&& nh); ``` +==== 通过 `node++_++handle` 插入 +```c++ -If `nh` is empty, has no effect. +iterator insert(node_type&& nh); -Otherwise inserts the element owned by `nh`. +``` + +若 `nh` 为空节点,则此操作不产生任何效果。 + +否则插入 `nh` 拥有的元素。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_map`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 若 `nh` 为空,则返回 `end()` 。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++map` 容器中提取的节点。 --- -==== Insert with Hint and `node_handle` -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示和 `node++_++handle` 的插入 +```c++ -If `nh` is empty, has no effect. +iterator insert(const_iterator hint, node_type&& nh); -Otherwise inserts the element owned by `nh`. +``` -`hint` is a suggestion to where the element should be inserted. +若 `nh` 为空节点,则此操作不产生任何效果。 + +否则插入 `nh` 拥有的元素。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_map`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 若 `nh` 为空,则返回 `end()` 。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由调用 hasher 以外的操作抛出,则此函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++map` 容器中提取的节点。 --- -==== Erase by Position +==== 通过位置擦除 + +```c++ -```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` +iterator erase(iterator position); iterator erase(const_iterator position); -Erase the element pointed to by `position`. +``` + +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. +返回;; 返回擦除操作前紧接在 `position` 之后的迭代器。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 在旧版本中,此操作可能效率较低,因为需要遍历多个桶来定位返回迭代器的位置。但数据结构现已优化,不再存在此问题,因此其他擦除方法已被弃用。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ -Erase all elements with key equivalent to `k`. +size_type erase(const key_type& k); template size_type erase(K&& k); + +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 + +```c++ -```c++ iterator erase(const_iterator first, const_iterator last); ``` +iterator erase(const_iterator first, const_iterator last); -Erases the elements in the range from `first` to `last`. +``` + +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 --- -==== quick_erase -```c++ void quick_erase(const_iterator position); ``` +==== quick++_++erase +```c++ + +void quick_erase(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== erase_return_void -```c++ void erase_return_void(const_iterator position); ``` +==== erase++_++return++_++void +```c++ + +void erase_return_void(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== swap -```c++ void swap(unordered_multimap& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` +==== 交换 +```c++ -Swaps the contents of the container with the parameter. +void swap(unordered_multimap& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the container. +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0` Throws:;; Never throws an exception. +后置条件;; `size() == 0` +抛出;; 从不抛出任何异常。 --- -==== merge -```c++ template void merge(unordered_multimap& source); template void merge(unordered_multimap&& source); template void merge(unordered_map& source); template void merge(unordered_map&& source); ``` +==== 合并 +```c++ -Attempt to "merge" two containers by iterating `source` and extracting all nodes in `source` and inserting them into `*this`. +template + void merge(unordered_multimap& source); +template + void merge(unordered_multimap&& source); +template + void merge(unordered_map& source); +template + void merge(unordered_map&& source); -Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. +``` + +通过遍历 `source` 容器,提取其中所有节点并将其插入到 `++*++this` 中,以此尝试将两个容器"合并"。 -The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. +由于 `source` 可以有不同的哈希函数和键相等性谓词,因此会使用 `this-++>++hash++_++function()` 操作对 `source` 中每个节点的键进行重哈希,并在需要时使用 `this-++>++key++_++eq()` 进行比较。 -This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. +如果 `this-++>++get++_++allocator() != source.get++_++allocator()` ,则此函数的行为未定义。 + +此函数不会复制或移动任何元素,而是直接将节点从 `source` 重新定位到 `++*++this` 中。 [horizontal] -Notes:;; + -- -* Pointers and references to transferred elements remain valid. -* Invalidates iterators to transferred elements. -* Invalidates iterators belonging to `*this`. -* Iterators to non-transferred elements in `source` remain valid. +注意;; ++ +-- +* 指向被转移元素的指针和引用保持有效。 +* 使指向被转移元素的迭代器失效。 +* 使属于 `++*++this` 的迭代器失效。 +* 指向 `source` 中未被转移元素的迭代器保持有效。 -- ---- +* --- + +=== 观察器 + +==== get++_++allocator +``` -=== Observers +allocator_type get_allocator() const; -==== get_allocator -``` allocator_type get_allocator() const; ``` +``` --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); +template + const_iterator find(const K& k) const; +template + iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); +template + const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器,若不存在这样的元素,则返回 `b.end()` 。 +注意;; 包含 `CompatibleKey` 、 `CompatibleHash` 和 `CompatiblePredicate` 的模板化重载是非标准扩展,允许用户使用兼容的哈希函数和相等性谓词来处理不同类型的键,以避免昂贵的类型转换。通常不鼓励使用此扩展,而应改用基于 `K` 的成员函数模板。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The number of buckets. +返回;; 桶的数量。 --- -==== max_bucket_count -```c++ size_type max_bucket_count() const noexcept; ``` +==== max++_++bucket++_++count +```c++ + +size_type max_bucket_count() const noexcept; + +``` [horizontal] -Returns:;; An upper bound on the number of buckets. +返回;; 桶数量的上限。 --- -==== bucket_size -```c++ size_type bucket_size(size_type n) const; ``` +==== 桶大小 +```c++ + +size_type bucket_size(size_type n) const; + +``` [horizontal] -Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. +要求;; `n ++<++ bucket++_++count()` +返回;; 返回桶 `n` 中的元素数量。 --- -==== bucket -```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` +==== 桶 +```c++ + +size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; + +``` [horizontal] -Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键为 `k` 的元素所在桶的索引。 +后置条件;; 返回值应小于 `bucket++_++count()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== begin -```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` +```c++ + +local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的局部迭代器。 --- ==== end -```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` +```c++ + +local_iterator end(size_type n); const_local_iterator end(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的局部迭代器。 --- ==== cbegin -```c++ const_local_iterator cbegin(size_type n) const; ``` +```c++ + +const_local_iterator cbegin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的常量局部迭代器。 --- ==== cend -```c++ const_local_iterator cend(size_type n) const; ``` +```c++ + +const_local_iterator cend(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的常量局部迭代器。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; The average number of elements per bucket. +返回;; 返回每个桶的平均元素数量。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the current maximum load factor. +返回;; 返回当前的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Changes the container's maximum load factor, using `z` as a hint. +效果;; 使用 `z` 作为提示来更改容器的最大负载因子。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); -Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +``` -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +改变桶的数量,使其至少为 `n` 个,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器关联的 `bucket++_++count()` 。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 + +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ + +void reserve(size_type n); + +``` -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` ,若 `n ++>++ 0` 且 `a.max++_++load++_++factor() == std::numeric++_++limits++<++float++>++::infinity()` ,则等价于 `a.rehash(1)` 。 -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1088,7 +1508,7 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-key-type__ = std::remove_const_t< @@ -1096,7 +1516,7 @@ template ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = @@ -1104,7 +1524,7 @@ template ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-to-alloc-type__ = std::pair< @@ -1112,82 +1532,127 @@ template std::tuple_element_t<1, xref:#unordered_multimap_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const unordered_multimap& x, + const unordered_multimap& y); -==== operator -```c++ template bool operator==(const unordered_multimap& x, const unordered_multimap& y); ``` +``` -Return `true` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). +若 `x.size() == y.size()` ,且对于 `x` 中的每个等效键组, `y` 中均存在一个对应相同键的组,且该组是原组的排列(使用 `operator==` 比较值类型),则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_multimap& x, const unordered_multimap& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const unordered_multimap& x, + const unordered_multimap& y); + +``` -Return `false` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types). +若 `x.size() != y.size()` ,或存在 `x` 中的某个等效键组,在 `y` 中不存在对应的相同键组,或该组不是原组的排列(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(unordered_multimap& x, unordered_multimap& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_multimap& x, + unordered_multimap& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -=== erase_if -```c++ template typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_multimap::size_type + erase_if(unordered_multimap& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` ++ +请注意,传递给 `pred` 的引用是非常量的。 -=== Serialization +=== 序列化 -``unordered_multimap``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++multimap` 可通过本库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_multimap to an archive +==== 将 unordered++_++multimap 保存到归档 -Saves all the elements of an `unordered_multimap` `x` to an archive (XML archive) `ar`. +将 `unordered++_++multimap` 容器 `x` 的所有元素保存到归档(XML 归档) `ar` 中。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 --- -==== Loading an unordered_multimap from an archive +==== 从归档加载 unordered++_++multimap -Deletes all preexisting elements of an `unordered_multimap` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_multimap` `other` saved to the storage read by `ar`. +删除 `unordered++_++multimap` 容器 `x` 中的所有预先存在的元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++multimap` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `(std::remove_const::type&&, std::remove_const::type&&)`. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. +要求;; `value++_++type` 必须能够从 `(std::remove++_++const++<++key++_++type++>++::type&&, std::remove++_++const++<++mapped++_++type++>++::type&&)` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] ,且 `x.key++_++equal()` 需要在功能上等价于 `other.key++_++equal()` 。 +注意;; 若归档文件是使用 Boost 1.84 之前的版本保存的,则必须全局定义配置宏 `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` 才能成功执行此操作;否则将抛出异常。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_multimap` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; 由 `it` 所指向的 `unordered++_++multimap` `x` 必须先前已保存到 `ar` ,且在保存 `x` 与保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_multimap` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 如果 `x` 是 `it` 所指向的 `unordered++_++multimap` 容器,则在加载 `x` 与加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc index a8433d8..4c3dc00 100644 --- a/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc @@ -1,13 +1,13 @@ [#unordered_multiset] -== Class Template unordered_multiset +== 类模板 unordered++_++multiset :idprefix: unordered_multiset_ -`boost::unordered_multiset` — An unordered associative container that stores values. The same key can be stored multiple times. +`boost::unordered++_++multiset` —— 一种用于存储值的无序关联容器。同一个键值可被多次存储。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_set.adoc[] @@ -20,7 +20,7 @@ namespace unordered { class Allocator = std::allocator> class unordered_multiset { public: - // types + // 类型 using key_type = Key; using value_type = Key; using hasher = Hash; @@ -39,7 +39,7 @@ namespace unordered { using const_local_iterator = _implementation-defined_; using node_type = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_multiset_default_constructor[unordered_multiset](); explicit xref:#unordered_multiset_bucket_count_constructor[unordered_multiset](size_type n, const hasher& hf = hasher(), @@ -84,7 +84,7 @@ namespace unordered { unordered_multiset& xref:#unordered_multiset_initializer_list_assignment[operator++=++](std::initializer_list il); allocator_type xref:#unordered_multiset_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_multiset_begin[begin]() noexcept; const_iterator xref:#unordered_multiset_begin[begin]() const noexcept; iterator xref:#unordered_multiset_end[end]() noexcept; @@ -92,12 +92,12 @@ namespace unordered { const_iterator xref:#unordered_multiset_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_multiset_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_multiset_empty[empty]() const noexcept; size_type xref:#unordered_multiset_size[size]() const noexcept; size_type xref:#unordered_multiset_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template iterator xref:#unordered_multiset_emplace[emplace](Args&&... args); template iterator xref:#unordered_multiset_emplace_hint[emplace_hint](const_iterator position, Args&&... args); iterator xref:#unordered_multiset_copy_insert[insert](const value_type& obj); @@ -135,22 +135,22 @@ namespace unordered { template void xref:#unordered_multiset_merge[merge](unordered_set&& source); - // observers + // 观察器 hasher xref:#unordered_multiset_hash_function[hash_function]() const; key_equal xref:#unordered_multiset_key_eq[key_eq]() const; - // set operations + // 集合操作 iterator xref:#unordered_multiset_find[find](const key_type& k); const_iterator xref:#unordered_multiset_find[find](const key_type& k) const; template iterator xref:#unordered_multiset_find[find](const K& k); template const_iterator xref:#unordered_multiset_find[find](const K& k) const; - template - iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, + template + iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&); - template - const_iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, + template + const_iterator xref:#unordered_multiset_find[find](CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&) const; size_type xref:#unordered_multiset_count[count](const key_type& k) const; template @@ -165,7 +165,7 @@ namespace unordered { template std::pair xref:#unordered_multiset_equal_range[equal_range](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_multiset_bucket_count[bucket_count]() const noexcept; size_type xref:#unordered_multiset_max_bucket_count[max_bucket_count]() const noexcept; size_type xref:#unordered_multiset_bucket_size[bucket_size](size_type n) const; @@ -178,7 +178,7 @@ namespace unordered { const_local_iterator xref:#unordered_multiset_cbegin_2[cbegin](size_type n) const; const_local_iterator xref:#unordered_multiset_cend_2[cend](size_type n) const; - // hash policy + // 哈希策略 float xref:#unordered_multiset_load_factor[load_factor]() const noexcept; float xref:#unordered_multiset_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_multiset_set_max_load_factor[max_load_factor](float z); @@ -186,7 +186,7 @@ namespace unordered { void xref:#unordered_multiset_reserve[reserve](size_type n); }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -231,125 +231,142 @@ namespace unordered { unordered_multiset(std::initializer_list, typename xref:#unordered_multiset_deduction_guides[__see below__]::size_type, Hash, Allocator) -> unordered_multiset, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|_键_ +|`Key` +需满足从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求(即 +`allocator++_++traits` 能够销毁该对象)。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. +|_谓词_ +|一种二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` +的参数,并返回一个布尔类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements are organized into buckets. Keys with the same hash code are stored in the same bucket and elements with equivalent keys are stored next to each other. +元素被组织到多个桶中。具有相同哈希码的键存储在同一个桶内,且等效键的元素彼此相邻存储。 -The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. +桶的数量可通过调用插入操作来自动增加,也可通过调用重哈希操作来调整。 -=== Configuration macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` +==== `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` -Globally define this macro to support loading of ``unordered_multiset``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. +全局定义此宏,以支持加载 Boost 1.84 之前版本保存到 Boost.Serialization 归档的 `unordered++_++multiset` 。 -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ local_iterator; ---- -An iterator with the same value type, difference type and pointer and reference type as iterator. +一种迭代器,其值类型、差值类型以及指针和引用类型均与 iterator 相同。 -A `local_iterator` object can be used to iterate through a single bucket. +`local++_++iterator` 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_local_iterator; ---- -A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. +一种常量迭代器,其值类型、差值类型以及指针和引用类型均与 const++_++iterator 相同。 -A const_local_iterator object can be used to iterate through a single bucket. +const++_++local++_++iterator 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -See node_handle_set for details. +详见 node++_++handle++_++set。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_multiset(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. +unordered_multiset(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、 `allocator++_++type()` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_multiset(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit unordered_multiset(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数, `eql` 作为键相等性谓词, `a` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multiset(InputIterator f, InputIterator l, @@ -359,71 +376,98 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,将最大负载因子设为 `1.0` ,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_multiset(const unordered_multiset& other); ``` +==== 复制构造函数 +```c++ + +unordered_multiset(const unordered_multiset& other); -The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所含的元素、哈希函数、谓词、最大负载因子及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_multiset(unordered_multiset&& other); ``` +==== 移动构造函数 +```c++ + +unordered_multiset(unordered_multiset&& other); -The move constructor. +``` + +移动构造函数。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 必须满足可移动构造的要求。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + unordered_multiset(InputIterator f, InputIterator l, const allocator_type& a); + +``` -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并将最大负载因子设为 `1.0` ,然后将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_multiset(const Allocator& a); ``` +==== 分配器构造函数 +```c++ + +explicit unordered_multiset(const Allocator& a); -Constructs an empty container, using allocator `a`. +``` + +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_multiset(const unordered_multiset& other, const Allocator& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_multiset(const unordered_multiset& other, const Allocator& a); -Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. +``` + +构造一个容器,复制 `other` 中的元素、哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_multiset(unordered_multiset&& other, const Allocator& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_multiset(unordered_multiset&& other, const Allocator& a); -Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. +``` + +构造一个容器,移动 `other` 中所包含的元素,并获取其哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 需满足可移动插入要求。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_multiset(std::initializer_list il, size_type n = _implementation-defined_, @@ -432,703 +476,1109 @@ unordered_multiset(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、及 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_multiset(size_type n, const allocator_type& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_multiset(size_type n, const allocator_type& a); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数(应为默认哈希函数)、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ + +unordered_multiset(size_type n, const hasher& hf, const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ + +unordered_multiset(std::initializer_list il, const allocator_type& a); -```c++ unordered_multiset(std::initializer_list il, const allocator_type& a); ``` +``` -Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +使用 `a` 作为分配器构造一个空容器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 -```c++ unordered_multiset(std::initializer_list il, size_type n, const allocator_type& a) ``` +```c++ -Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +unordered_multiset(std::initializer_list il, size_type n, const allocator_type& a) + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器,并设置最大负载因子为 1.0,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ + +unordered_multiset(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -```c++ unordered_multiset(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ + +~unordered_multiset(); -```c++ ~unordered_multiset(); ``` +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 + +```c++ -==== Copy Assignment +unordered_multiset& operator=(const unordered_multiset& other); -```c++ unordered_multiset& operator=(const unordered_multiset& other); ``` +``` -The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. +赋值运算符。该操作会复制容器内的元素、哈希函数、谓词及最大负载因子,但不会复制分配器。 -If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. +如果 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Assignment -```c++ unordered_multiset& operator=(unordered_multiset&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. +==== 移动赋值 +```c++ -If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. +unordered_multiset& operator=(unordered_multiset&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + +``` +移动赋值运算符。 + +如果 `Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++move++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is move constructible. +要求;; `value++_++type` 需满足可移动构造要求。 --- -==== Initializer List Assignment -```c++ unordered_multiset& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ + +unordered_multiset& operator=(std::initializer_list il); + +``` -Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. +将初始化列表中的值赋给容器。所有已存在的元素将被新元素覆盖或销毁。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. +要求;; `value++_++type` 必须满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 至容器以及 https://en.cppreference.com/w/cpp/named_req/CopyAssignable[可复制赋值] 的要求。 --- -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ + +size_type size() const noexcept; -```c++ size_type size() const noexcept; ``` +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template iterator emplace(Args&&... args); ``` +==== 原地构造 +```c++ -Inserts an object, constructed with the arguments args, in the container. +template iterator emplace(Args&&... args); + +``` + +向容器中插入一个由参数 args 构造的对象。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments args, in the container. +向容器中插入一个由参数 args 构造的对象。 -`hint` is a suggestion to where the element should be inserted. +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Copy Insert -```c++ iterator insert(const value_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the container. +iterator insert(const value_type& obj); + +``` + +向容器中插入 `obj` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert -```c++ iterator insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +iterator insert(value_type&& obj); -Inserts `obj` in the container. +``` + +向容器中插入 `obj` 。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` +==== 带提示的复制插入 +```c++ + +iterator insert(const_iterator hint, const value_type& obj); -Inserts `obj` in the container. +``` -`hint` is a suggestion to where the element should be inserted. +向容器中插入 `obj` 。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ + +iterator insert(const_iterator hint, value_type&& obj); -Inserts `obj` in the container. +``` -`hint` is a suggestion to where the element should be inserted. +向容器中插入 `obj` 。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; An iterator pointing to the inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 返回一个指向插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); -Inserts a range of elements into the container. +``` + +将元素范围插入容器。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须能够通过 `++*++first` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到 `X` 中。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list il); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list il); -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Extract by Iterator -```c++ node_type extract(const_iterator position); ``` +==== 通过迭代器提取 +```c++ + +node_type extract(const_iterator position); -Removes the element pointed to by `position`. +``` + +移除由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` owning the element. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. +返回;; 返回一个拥有该元素的 `node++_++type` 对象。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++set` 容器中。 --- -==== Extract by Value -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键值提取元素 +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); -Removes an element with key equivalent to `k`. +``` + +移除键等价于 `k` 的元素。 [horizontal] -Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; A node extracted using this method can be inserted into a compatible `unordered_set`. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果找到,则返回一个拥有该元素的 `node++_++type` 对象;否则返回一个空的 `node++_++type` 对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 通过此方法提取的节点可被插入到兼容的 `unordered++_++set` 容器中。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert with `node_handle` -```c++ iterator insert(node_type&& nh); ``` +==== 通过 `node++_++handle` 插入 +```c++ + +iterator insert(node_type&& nh); -If `nh` is empty, has no effect. +``` -Otherwise inserts the element owned by `nh`. +若 `nh` 为空节点,则此操作不产生任何效果。 + +否则插入 `nh` 拥有的元素。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_set`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 若 `nh` 为空,则返回 `end()` 。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++set` 容器中提取的节点。 --- -==== Insert with Hint and `node_handle` -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示和 `node++_++handle` 的插入 +```c++ + +iterator insert(const_iterator hint, node_type&& nh); + +``` -If `nh` is empty, has no effect. +若 `nh` 为空节点,则此操作不产生任何效果。 -Otherwise inserts the element owned by `nh`. +否则插入 `nh` 拥有的元素。 -`hint` is a suggestion to where the element should be inserted. +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns `end()`. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to hasher the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_set`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 若 `nh` 为空,则返回 `end()` 。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由调用 hasher 以外的操作抛出,则此函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此方法可用于插入从兼容的 `unordered++_++set` 容器中提取的节点。 --- -==== Erase by Position +==== 通过位置擦除 + +```c++ + +iterator erase(iterator position); iterator erase(const_iterator position); -```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. +返回;; 返回擦除操作前紧接在 `position` 之后的迭代器。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 在旧版本中,此操作可能效率较低,因为需要遍历多个桶来定位返回迭代器的位置。但数据结构现已优化,不再存在此问题,因此其他擦除方法已被弃用。 --- -==== Erase by Value -```c++ size_type erase(const key_type& k); template size_type erase(K&& x); ``` +==== 通过值擦除 +```c++ -Erase all elements with key equivalent to `k`. +size_type erase(const key_type& k); template size_type erase(K&& x); + +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 + +```c++ + +iterator erase(const_iterator first, const_iterator last); -```c++ iterator erase(const_iterator first, const_iterator last); ``` +``` -Erases the elements in the range from `first` to `last`. +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 --- -==== quick_erase -```c++ void quick_erase(const_iterator position); ``` +==== quick++_++erase +```c++ -Erase the element pointed to by `position`. +void quick_erase(const_iterator position); + +``` + +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== erase_return_void -```c++ void erase_return_void(const_iterator position); ``` +==== erase++_++return++_++void +```c++ + +void erase_return_void(const_iterator position); -Erase the element pointed to by `position`. +``` + +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== swap -```c++ void swap(unordered_multiset&) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` +==== 交换 +```c++ + +void swap(unordered_multiset&) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); -Swaps the contents of the container with the parameter. +``` -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +交换容器与参数的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; -Erases all elements in the container. +``` + +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0` Throws:;; Never throws an exception. +后置条件;; `size() == 0` +抛出;; 从不抛出任何异常。 --- -==== merge -```c++ template void merge(unordered_multiset& source); template void merge(unordered_multiset&& source); template void merge(unordered_set& source); template void merge(unordered_set&& source); ``` +==== 合并 +```c++ + +template + void merge(unordered_multiset& source); +template + void merge(unordered_multiset&& source); +template + void merge(unordered_set& source); +template + void merge(unordered_set&& source); -Attempt to "merge" two containers by iterating `source` and extracting all nodes in `source` and inserting them into `*this`. +``` -Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. +通过遍历 `source` 容器,提取其中所有节点并将其插入到 `++*++this` 中,以此尝试将两个容器"合并"。 -The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. +由于 `source` 可以有不同的哈希函数和键相等性谓词,因此会使用 `this-++>++hash++_++function()` 操作对 `source` 中每个节点的键进行重哈希,并在需要时使用 `this-++>++key++_++eq()` 进行比较。 -This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. +如果 `this-++>++get++_++allocator() != source.get++_++allocator()` ,则此函数的行为未定义。 + +此函数不会复制或移动任何元素,而是直接将节点从 `source` 重新定位到 `++*++this` 中。 [horizontal] -Notes:;; + -- -* Pointers and references to transferred elements remain valid. -* Invalidates iterators to transferred elements. -* Invalidates iterators belonging to `*this`. -* Iterators to non-transferred elements in `source` remain valid. +注意;; ++ +-- +* 指向被转移元素的指针和引用保持有效。 +* 使指向被转移元素的迭代器失效。 +* 使属于 `++*++this` 的迭代器失效。 +* 指向 `source` 中未被转移元素的迭代器保持有效。 -- ---- +* --- + +=== 观察器 + +==== get++_++allocator +``` -=== Observers +allocator_type get_allocator() const noexcept; -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +``` --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq +==== key++_++eq + +``` + +key_equal key_eq() const; -``` key_equal key_eq() const; ``` +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&); template const_iterator find(CompatibleKey const&, CompatibleHash const&, CompatiblePredicate const&) const; ``` +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); +template + const_iterator find(const K& k) const; +template + iterator find(CompatibleKey const&, CompatibleHash const&, + CompatiblePredicate const&); +template + const_iterator find(CompatibleKey const&, CompatibleHash const&, + CompatiblePredicate const&) const; + +``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器,若不存在这样的元素,则返回 `b.end()` 。 +注意;; 包含 `CompatibleKey` 、 `CompatibleHash` 和 `CompatiblePredicate` 的模板化重载是非标准扩展,允许用户使用兼容的哈希函数和相等性谓词来处理不同类型的键,以避免昂贵的类型转换。通常不鼓励使用此扩展,而应改用基于 `K` 的成员函数模板。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 + +==== bucket++_++count +```c++ -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The number of buckets. +返回;; 桶的数量。 --- -==== max_bucket_count -```c++ size_type max_bucket_count() const noexcept; ``` +==== max++_++bucket++_++count +```c++ + +size_type max_bucket_count() const noexcept; + +``` [horizontal] -Returns:;; An upper bound on the number of buckets. +返回;; 桶数量的上限。 --- -==== bucket_size -```c++ size_type bucket_size(size_type n) const; ``` +==== 桶大小 +```c++ + +size_type bucket_size(size_type n) const; + +``` [horizontal] -Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. +要求;; `n ++<++ bucket++_++count()` +返回;; 返回桶 `n` 中的元素数量。 --- -==== bucket -```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` +==== 桶 +```c++ + +size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; + +``` [horizontal] -Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键为 `k` 的元素所在桶的索引。 +后置条件;; 返回值应小于 `bucket++_++count()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== begin -```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` +```c++ + +local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的局部迭代器。 --- ==== end -```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` +```c++ + +local_iterator end(size_type n); const_local_iterator end(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的局部迭代器。 --- ==== cbegin -```c++ const_local_iterator cbegin(size_type n) const; ``` +```c++ + +const_local_iterator cbegin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的常量局部迭代器。 --- ==== cend -```c++ const_local_iterator cend(size_type n) const; ``` +```c++ + +const_local_iterator cend(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的常量局部迭代器。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; The average number of elements per bucket. +返回;; 返回每个桶的平均元素数量。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the current maximum load factor. +返回;; 返回当前的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Changes the container's maximum load factor, using `z` as a hint. +效果;; 使用 `z` 作为提示来更改容器的最大负载因子。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +改变桶的数量,使其至少为 `n` 个,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器关联的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. +void reserve(size_type n); -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +``` -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` ,若 `n ++>++ 0` 且 `a.max++_++load++_++factor() == std::numeric++_++limits++<++float++>++::infinity()` ,则等价于 `a.rehash(1)` 。 + +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 + +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ + +template + bool operator==(const unordered_multiset& x, + const unordered_multiset& y); -==== operator -```c++ template bool operator==(const unordered_multiset& x, const unordered_multiset& y); ``` +``` -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_multiset& x, const unordered_multiset& y); ``` +==== operator!= +```c++ -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +template + bool operator!=(const unordered_multiset& x, + const unordered_multiset& y); + +``` + +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(unordered_multiset& x, unordered_multiset& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_multiset& x, + unordered_multiset& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -=== erase_if -```c++ template typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_multiset::size_type + erase_if(unordered_multiset& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` -=== Serialization +=== 序列化 -``unordered_multiset``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++multiset` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_multiset to an archive +==== 保存 unordered++_++multiset 到归档 -Saves all the elements of an `unordered_multiset` `x` to an archive (XML archive) `ar`. +将 `unordered++_++multiset` `x` 的所有元素保存到归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 --- -==== Loading an unordered_multiset from an archive +==== 从归档加载 unordered++_++multiset -Deletes all preexisting elements of an `unordered_multiset` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_multiset` `other` saved to the storage read by `ar`. +删除 `unordered++_++multiset` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++multiset` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求,且 `x.key++_++equal()` 在功能上需等价于 `other.key++_++equal()` 。 +注意;; 若归档文件是使用 Boost 1.84 之前的版本保存的,则必须全局定义配置宏 `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` 才能成功执行此操作;否则将抛出异常。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_multiset` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 所指向的 `unordered++_++multiset` 容器 `x` 必须先前已保存至 `ar` ,且在保存 `x` 与保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_multiset` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 若 `x` 是 `it` 所指向的 `unordered++_++multiset` 容器,则在加载 `x` 与加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc index d8b0f72..277ec4f 100644 --- a/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_node_map_zh_Hans.adoc @@ -1,21 +1,23 @@ [#unordered_node_map] -== Class Template unordered_node_map +== 类模板 unordered++_++node++_++map :idprefix: unordered_node_map_ -`boost::unordered_node_map` — A node-based, open-addressing unordered associative container that associates unique keys with another value. +`boost::unordered++_++node++_++map` —— 一种基于节点、采用开放寻址法的无序关联容器,用于将唯一键与另一个值关联。 -`boost::unordered_node_map` uses an open-addressing layout like `boost::unordered_flat_map`, but, being node-based, it provides pointer stability and node handling functionalities. Its performance lies between those of `boost::unordered_map` and `boost::unordered_flat_map`. +`boost::unordered++_++node++_++map` 采用与 `boost::unordered++_++flat++_++map` 相似的开放寻址布局,但由于其基于节点的特性,该容器提供了指针稳定性和节点处理功能。其性能介于 `boost::unordered++_++map` 与 `boost::unordered++_++flat++_++map` 之间。 -As a result of its using open addressing, the interface of `boost::unordered_node_map` deviates in a number of aspects from that of `boost::unordered_map`/`std::unordered_map`: +由于采用开放寻址法, `boost::unordered++_++node++_++map` 的接口在多个方面与 `boost::unordered++_++map` / `std::unordered++_++map` 存在差异: -- `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`). - The maximum load factor of the container is managed internally and can't be set by the user. + - `begin()` 不是常数时间复杂度操作。 + - 未提供用于桶管理的 API(除 `bucket++_++count` 外)。 + - 容器的最大负载因子由内部管理,用户无法进行设置。 -Other than this, `boost::unordered_node_map` is mostly a drop-in replacement of standard unordered associative containers. +除此之外, `boost::unordered++_++node++_++map` 基本可直接替代标准无序关联容器。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_node_map.adoc[``] @@ -29,7 +31,7 @@ namespace unordered { class Allocator = std::allocator>> class unordered_node_map { public: - // types + // 类型定义 using key_type = Key; using mapped_type = T; using value_type = std::pair; @@ -55,7 +57,7 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled] - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_node_map_default_constructor[unordered_node_map](); explicit xref:#unordered_node_map_bucket_count_constructor[unordered_node_map](size_type n, const hasher& hf = hasher(), @@ -101,7 +103,7 @@ namespace unordered { unordered_node_map& xref:#unordered_node_map_initializer_list_assignment[operator++=++](std::initializer_list); allocator_type xref:#unordered_node_map_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_node_map_begin[begin]() noexcept; const_iterator xref:#unordered_node_map_begin[begin]() const noexcept; iterator xref:#unordered_node_map_end[end]() noexcept; @@ -109,12 +111,12 @@ namespace unordered { const_iterator xref:#unordered_node_map_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_node_map_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_node_map_empty[empty]() const noexcept; size_type xref:#unordered_node_map_size[size]() const noexcept; size_type xref:#unordered_node_map_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template std::pair xref:#unordered_node_map_emplace[emplace](Args&&... args); template iterator xref:#unordered_node_map_emplace_hint[emplace_hint](const_iterator position, Args&&... args); std::pair xref:#unordered_node_map_copy_insert[insert](const value_type& obj); @@ -174,11 +176,11 @@ namespace unordered { template void xref:#unordered_node_map_merge[merge](unordered_node_map&& source); - // observers + // 观察器 hasher xref:#unordered_node_map_hash_function[hash_function]() const; key_equal xref:#unordered_node_map_key_eq[key_eq]() const; - // map operations + // 映射操作 iterator xref:#unordered_node_map_find[find](const key_type& k); const_iterator xref:#unordered_node_map_find[find](const key_type& k) const; template @@ -198,7 +200,7 @@ namespace unordered { template std::pair xref:#unordered_node_map_equal_range[equal_range](const K& k) const; - // element access + // 元素访问 mapped_type& xref:#unordered_node_map_operator[operator[+]+](const key_type& k); mapped_type& xref:#unordered_node_map_operator[operator[+]+](key_type&& k); template mapped_type& xref:#unordered_node_map_operator[operator[+]+](K&& k); @@ -207,10 +209,10 @@ namespace unordered { template mapped_type& xref:#unordered_node_map_at[at](const K& k); template const mapped_type& xref:#unordered_node_map_at[at](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_node_map_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#unordered_node_map_load_factor[load_factor]() const noexcept; float xref:#unordered_node_map_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_node_map_set_max_load_factor[max_load_factor](float z); @@ -218,12 +220,12 @@ namespace unordered { void xref:#unordered_node_map_rehash[rehash](size_type n); void xref:#unordered_node_map_reserve[reserve](size_type n); - // statistics (if xref:unordered_node_map_boost_unordered_enable_stats[enabled]) + // 统计(若启用) stats xref:#unordered_node_map_get_stats[get_stats]() const; void xref:#unordered_node_map_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -273,96 +275,99 @@ namespace unordered { Hash, Allocator) -> unordered_node_map, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -.2+|`std::pair` must be https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] -into the container from any `std::pair` object convertible to it, and it also must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +.2+|`std::pair++<++const Key, T++>++` 必须可从任何可转换为它的 +`std::pair` +对象 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到容器中,并且必须可从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[擦除] 。 |_T_ |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The element nodes of the container are held into an internal _bucket array_. A node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素节点保存在内部的__桶数组__中。节点根据其元素的哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则使用原始位置附近的可用桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 来调整。容器的__负载因子__(元素数量与桶数量的比值)始终不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. +全局定义此宏,以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低许多操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -An iterator whose value type is `value_type`. +一种迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存已提取容器元素的类,其建模自 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -373,34 +378,47 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `Iterator` = `iterator` and `NodeType` = `node_type`. +其中 `Iterator` = `iterator` ,且 `NodeType` = `node++_++type` 。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_node_map(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +unordered_node_map(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、以及 `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_node_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit unordered_node_map(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_map(InputIterator f, InputIterator l, @@ -410,73 +428,103 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_node_map(unordered_node_map const& other); ``` +==== 复制构造函数 +```c++ -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +unordered_node_map(unordered_node_map const& other); + +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 --- -==== Move Constructor -```c++ unordered_node_map(unordered_node_map&& other); ``` +==== 移动构造函数 +```c++ + +unordered_node_map(unordered_node_map&& other); + +``` -The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +移动构造函数。将 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。若统计功能已 xref:#unordered_node_map_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_node_map(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +template + unordered_node_map(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_node_map(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit unordered_node_map(Allocator const& a); + +``` -Constructs an empty container, using allocator `a`. +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_node_map(unordered_node_map const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_node_map(unordered_node_map const& other, Allocator const& a); + +``` -Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_node_map(unordered_node_map&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ -If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +unordered_node_map(unordered_node_map&& other, Allocator const& a); + +``` + +若 `a == other.get++_++allocator()` ,则将 `other` 的元素节点直接转移至新容器;否则,从 `other` 的元素移动构造。哈希函数和谓词均从 `other` 移动构造,分配器从 `a` 复制构造。若统计功能已 xref:#unordered_node_map_boost_unordered_enable_stats[启用] ,则当 `a == other.get++_++allocator()` 时转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 --- -==== Move Constructor from concurrent_node_map +==== 从 concurrent++_++node++_++map 的移动构造函数 -```c++ unordered_node_map(concurrent_node_map&& other); ``` +```c++ -Move construction from a xref:#concurrent_node_map[`concurrent_node_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +unordered_node_map(concurrent_node_map&& other); + +``` + +从 #xref:#concurrent_node_map[`concurrent_node_map`][`concurrent++_++node++_++map`] 移动构造。将 `other` 的内部桶数组直接转移至新容器。哈希函数、谓词和分配器均从 `other` 移动构造。若统计功能已 xref:#unordered_node_map_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度;; 常数时间复杂度。 +并发性;; 阻塞于 `other` 。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_node_map(std::initializer_list il, size_type n = _implementation-defined_ @@ -485,673 +533,1075 @@ unordered_node_map(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_node_map(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +unordered_node_map(size_type n, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_node_map(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +unordered_node_map(size_type n, hasher const& hf, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ + +unordered_node_map(std::initializer_list il, const allocator_type& a); -```c++ unordered_node_map(std::initializer_list il, const allocator_type& a); ``` +``` -Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_node_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +unordered_node_map(std::initializer_list il, size_type n, const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 -```c++ unordered_node_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```c++ + +unordered_node_map(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器、默认键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 -```c++ ~unordered_node_map(); ``` +```c++ + +~unordered_node_map(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 -==== Copy Assignment +==== 复制赋值 -```c++ unordered_node_map& operator=(unordered_node_map const& other); ``` +```c++ -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +unordered_node_map& operator=(unordered_node_map const& other); + +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 --- -==== Move Assignment -```c++ unordered_node_map& operator=(unordered_node_map&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +unordered_node_map& operator=(unordered_node_map&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值运算符。该操作会销毁容器中原有的元素,交换 `other` +的哈希函数和谓词,若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则直接将 `other` +的内部桶数组转移至当前容器;否则,将插入 `other` +中元素的移动构造副本。若统计功能 xref:#unordered_node_map_boost_unordered_enable_stats[已启用] ,则当且仅当最终分配器与 +`other.get++_++allocator()` 相等时,同时转移其内部统计信息,并始终调用 +`other.reset++_++stats()` 。 --- -==== Initializer List Assignment -```c++ unordered_node_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ -Assign from values in initializer list. All previously existing elements are destroyed. +unordered_node_map& operator=(std::initializer_list il); + +``` + +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ -```c++ size_type size() const noexcept; ``` +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size -```c++ size_type max_size() const noexcept; ``` +```c++ + +size_type max_size() const noexcept; + +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template std::pair emplace(Args&&... args); -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when `key_type` is move constructible or when the `k` argument is a `key_type`. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +若 `args…` 的形式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。当 `key++_++type` 可移动构造,或参数 `k` 的类型为 `key++_++type` 时,此优化生效。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 -`position` is a suggestion to where the element should be inserted. This implementation ignores it. +`position` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + If `args...` is of the form `k,v`, it delays constructing the whole object until it is certain that an element should be inserted, using only the `k` argument to check. This optimization happens when `key_type` is move constructible or when the `k` argument is a `key_type`. +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +若 `args…` 的形式为 `k,v` ,该实现会延迟构造完整对象,直到确认需要插入元素时为止,在此期间仅使用参数 `k` 进行检查。当 `key++_++type` 可移动构造,或参数 `k` 的类型为 `key++_++type` 时,此优化生效。 --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); ``` +==== 复制插入 +```c++ + +std::pair insert(const value_type& obj); std::pair insert(const init_type& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); ``` +==== 移动插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +std::pair insert(value_type&& obj); std::pair insert(init_type&& obj); + +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +对于 `insert(x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),不会产生歧义,并选择 `init++_++type` 重载。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ + +iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_type& obj); -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +``` 当且仅当容器中不存在具有等价键的元素时,插入 `obj` 。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `const value_type&` and `const init_type&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +对于 `insert(hint, x)` 形式的调用(其中 `x` 可同等地转换为 `const value++_++type&` 和 `const init++_++type&` ),该调用不会产生歧义,并会选择 `init++_++type` 重载版本。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); ``` +==== 带提示的移动插入 +```c++ + +iterator insert(const_iterator hint, value_type&& obj); iterator insert(const_iterator hint, init_type&& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + A call of the form `insert(hint, x)`, where `x` is equally convertible to both `value_type&&` and `init_type&&`, is not ambiguous and selects the `init_type` overload. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +对于 `insert(hint, x)` 形式的调用(其中 `x` 可同等地转换为 `value++_++type&&` 和 `init++_++type&&` ),该调用不会产生歧义,并会选择 `init++_++type` 重载版本。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 必须能够通过 `++*++first` 在容器中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Insert Node -```c++ insert_return_type insert(node_type&& nh); ``` +==== 节点插入 +```c++ -If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.key()`. `nh` is empty when the function returns. +insert_return_type insert(node_type&& nh); + +``` + +若 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入其关联元素。函数返回时 `nh` 为空。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `position`, `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false`, `position` is `end()`, and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true, `position` points to the inserted element, and `node` is empty. -* If the insertion failed, `inserted` is false, `node` has the previous value of `nh`, and `position` points to an element with a key equivalent to `nh.key()`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个从 `position` 、 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` , `position` 为 `end()` ,且 `node` 为空。 +* 否则,若插入操作发生,则 `inserted` 为 `true` , `position` 指向被插入的元素,且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 `false` , `node` 保留 `nh` 的原始值,且 `position` 指向与 `nh.key()` 等效的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== Insert Node with Hint -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示的节点插入 +```c++ -If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.key()`. `nh` becomes empty if insertion took place, otherwise it is not changed. +iterator insert(const_iterator hint, node_type&& nh); -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +``` + +若 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入其关联的元素。若插入操作发生,则 `nh` 变为空;否则 `nh` 保持不变。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; The iterator returned is `end()` if `nh` is empty. If insertion took place, then the iterator points to the newly inserted element; otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 若 `nh` 为空,则返回的迭代器为 `end()` 。若插入操作发生,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== try_emplace -```c++ template std::pair try_emplace(const key_type& k, Args&&... args); template std::pair try_emplace(key_type&& k, Args&&... args); template std::pair try_emplace(K&& k, Args&&... args); ``` +==== try++_++emplace +```c++ + +template + std::pair try_emplace(const key_type& k, Args&&... args); +template + std::pair try_emplace(key_type&& k, Args&&... args); +template + std::pair try_emplace(K&& k, Args&&... args); -Inserts a new element into the container if there is no existing element with key `k` contained within it. +``` + +若容器中不存在键为 `k` 的元素,则插入一个新元素。 -If there is an existing element with key `k` this function does nothing. +若存在键为 `k` 的元素,则此函数不执行任何操作。 [horizontal] -Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_node_map_emplace[emplace], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_node_map_emplace[emplace] 类似,区别在于:若已存在具有等价键的元素,则不会构造任何 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#unordered_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor. +``` + +而非像 xref:#unordered_node_map_emplace[emplace] 会简单地将所有参数转发给 `value++_++type` 的构造函数。 -Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== try_emplace with Hint -```c++ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template iterator try_emplace(const_iterator hint, K&& k, Args&&... args); ``` +==== 带提示的 try++_++emplace +```c++ -Inserts a new element into the container if there is no existing element with key `k` contained within it. +template + iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); +template + iterator try_emplace(const_iterator hint, K&& k, Args&&... args); -If there is an existing element with key `k` this function does nothing. +``` -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +若容器中不存在键为 `k` 的元素,则插入一个新元素。 + +若存在键为 `k` 的元素,则此函数不执行任何操作。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; This function is similiar to xref:#unordered_node_map_emplace_hint[emplace_hint], with the difference that no `value_type` is constructed if there is an element with an equivalent key; otherwise, the construction is of the form: + + -- ```c++ +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 此函数与 xref:#unordered_node_map_emplace_hint[emplace++_++hint] 类似,区别在于:若已存在具有等效键的元素,则不会构造任何 `value++_++type` 对象;否则,将按以下形式构造: + ++ +-- +```c++ + // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(args)...)) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)) -unlike xref:#unordered_node_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor. +``` + +而非像 xref:#unordered_node_map_emplace_hint[emplace++_++hint] 会简单地将所有参数转发给 `value++_++type` 的构造函数。 -Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 -The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 隐式转换时, `template++<++class K, class... Args++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 -- --- -==== insert_or_assign -```c++ template std::pair insert_or_assign(const key_type& k, M&& obj); template std::pair insert_or_assign(key_type&& k, M&& obj); template std::pair insert_or_assign(K&& k, M&& obj); ``` +==== insert++_++or++_++assign +```c++ + +template + std::pair insert_or_assign(const key_type& k, M&& obj); +template + std::pair insert_or_assign(key_type&& k, M&& obj); +template + std::pair insert_or_assign(K&& k, M&& obj); -Inserts a new element into the container or updates an existing one by assigning to the contained value. +``` + +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 + +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` [horizontal] -Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载超过最大负载时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== insert_or_assign with Hint -```c++ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); ``` +==== 带提示的 insert++_++or++_++assign +```c++ + +template + iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); +template + iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + +``` + +向容器中插入新元素,或通过赋值给已存在的元素值来更新该元素。 -Inserts a new element into the container or updates an existing one by assigning to the contained value. +如果存在键为 `k` 的元素,则通过赋值 `std::forward++<++M++>++(obj)` 来更新该元素。 -If there is an element with key `k`, then it is updated by assigning `std::forward(obj)`. +若不存在该元素,则将其以如下方式添加到容器中: ```c++ -If there is no such element, it is added to the container as: ```c++ // first two overloads -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) // third overload -value_type(std::piecewise_construct, std::forward_as_tuple(std::forward(k)), std::forward_as_tuple(std::forward(obj))) ``` +value_type(std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(obj))) + +``` -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 和 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K, class M++>++` 才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。该机制支持异构查找,从而避免实例化 `Key` 类型对象所需的开销。 --- -==== Erase by Position +==== 通过位置擦除 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- _convertible-to-iterator_ erase(iterator position); _convertible-to-iterator_ erase(const_iterator position); ---- -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. +返回;; 返回一个不透明对象,该对象可隐式转换为擦除前紧接在 `position` 之后的 `iterator` 或 `const++_++iterator` 。 +抛出;; 无。 +注意;; 返回的不透明对象必须被立即丢弃或转换为 `iterator` 或 `const++_++iterator` 。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(K&& k); + +``` -Erase all elements with key equivalent to `k`. +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 -```c++ iterator erase(const_iterator first, const_iterator last); ``` +```c++ -Erases the elements in the range from `first` to `last`. +iterator erase(const_iterator first, const_iterator last); + +``` + +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 在此实现中不抛出任何异常(既不调用 `hasher` , 也不调用 `key++_++equal` 对象)。 --- -==== swap -```c++ void swap(unordered_node_map& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ -Swaps the contents of the container with the parameter. +void swap(unordered_node_map& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -==== Extract by Position -```c++ node_type extract(const_iterator position); ``` +==== 通过位置提取 +```c++ + +node_type extract(const_iterator position); -Extracts the element pointed to by `position`. +``` + +提取由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element. Throws:;; Nothing. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象。 +抛出;; 无。 --- -==== Extract by Key -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键提取 +```c++ -Extracts the element with key equivalent to `k`, if it exists. +node_type extract(const key_type& k); template node_type extract(K&& k); + +``` + +若存在键等价于 `k` 的元素,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== pull -```c++ init_type pull(const_iterator position); ``` +```c++ + +init_type pull(const_iterator position); + +``` -Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. +从 `position` 指向的元素移动构造一个 `init++_++value` 对象 `x` ,擦除该元素并返回 `x` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the container. +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` --- -==== merge -```c++ template void merge(unordered_node_map& source); template void merge(unordered_node_map&& source); ``` +==== 合并 +```c++ + +template + void merge(unordered_node_map& source); +template + void merge(unordered_node_map&& source); + +``` -Transfers all the element nodes from `source` whose key is not already present in `*this`. +转移 `source` 中所有键不在 `++*++this` 中的元素节点。 [horizontal] -Requires:;; `this\->get_allocator() == source.get_allocator()`. Notes:;; Invalidates iterators to the elements transferred. If the resulting size of `*this` is greater than its original maximum load, invalidates all iterators associated to `*this`. +要求;; `this-++>++get++_++allocator() == source.get++_++allocator()` 。 +注意;; 指向被转移元素的迭代器将失效。若 `++*++this` 的最终大小大于其原始最大负载,则与 `++*++this` 关联的所有迭代器将失效。 --- -=== Observers +=== 观察器 -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +==== get++_++allocator +``` + +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The container's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器;若不存在这样的元素,则返回 `end()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== operator++[++++]++ -```c++ mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); ``` +==== operator++[]++ +```c++ + +mapped_type& operator[](const key_type& k); mapped_type& operator[](key_type&& k); template mapped_type& operator[](K&& k); + +``` [horizontal] -Effects:;; If the container does not already contain an element with a key equivalent to `k`, inserts the value `std::pair(k, mapped_type())`. Returns:;; A reference to `x.second` where `x` is the element already in the container, or the newly inserted element with a key equivalent to `k`. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +效果;; 若容器中尚不存在键等价于 `k` 的元素,则插入值 `std::pair++<++key++_++type const, mapped++_++type++>++(k, mapped++_++type())` 。 +返回;; 返回一个引用,该引用指向容器中已存在的键等于 `k` 的元素 `x` 的 `x.second` 成员;若元素不存在,则指向新插入元素的该成员。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== at -```c++ mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; ``` +```c++ + +mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; template mapped_type& at(const K& k); template const mapped_type& at(const K& k) const; + +``` [horizontal] -Returns:;; A reference to `x.second` where `x` is the (unique) element whose key is equivalent to `k`. Throws:;; An exception object of type `std::out_of_range` if no such element is present. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个引用,该引用指向键等价于 `k` 的(唯一)元素 `x` 的 `x.second` 成员。 +抛出;; 如果不存在这样的元素,则抛出类型为 `std::out++_++of++_++range` 的异常对象。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ -==== load_factor -```c++ float load_factor() const noexcept; ``` +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) + +```c++ -```c++ float max_load_factor() const noexcept; ``` +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the container's maximum load factor. +返回;; 容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_map`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++map` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) + +```c++ + +size_type max_load() const noexcept; -```c++ size_type max_load() const noexcept; ``` +``` [horizontal] -Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. +返回;; 返回容器在不重哈希的情况下可容纳的最大元素数(假设不再擦除元素)。 +注意;; 在构造、重新哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。若使用的分配器采用花式指针,随后会执行默认分配操作。 -Invalidates iterators and changes the order of elements. +使迭代器失效并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ + +void reserve(size_type n); + +``` -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 -Invalidates iterators and changes the order of elements. +使迭代器失效并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Statistics +=== 统计信息 -==== get_stats -```c++ stats get_stats() const; ``` +==== get++_++stats +```c++ + +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. +返回;; 返回容器直到目前已执行插入和查找操作的统计摘要。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_node_map_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. +效果;; 将容器维护的内部统计信息清零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_node_map_boost_unordered_enable_stats[启用] 时可用。 --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = @@ -1159,7 +1609,7 @@ template ----- ==== __iter-key-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-key-type__ = std::remove_const_t< @@ -1167,7 +1617,7 @@ template ----- ==== __iter-mapped-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-mapped-type__ = @@ -1175,7 +1625,7 @@ template ----- ==== __iter-to-alloc-type__ -[listings,subs="+macros,+quotes"] +[listings, subs="+macros,+quotes"] ----- template using __iter-to-alloc-type__ = std::pair< @@ -1183,80 +1633,123 @@ template std::tuple_element_t<1, xref:#unordered_node_map_iter_value_type[__iter-value-type__]>>; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ -==== operator -```c++ template bool operator==(const unordered_node_map& x, const unordered_node_map& y); ``` +template + bool operator==(const unordered_node_map& x, + const unordered_node_map& y); -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +``` + +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_node_map& x, const unordered_node_map& y); ``` +==== operator!= +```c++ -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +template + bool operator!=(const unordered_node_map& x, + const unordered_node_map& y); + +``` + +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 + +=== 交换 +```c++ + +template + void swap(unordered_node_map& x, + unordered_node_map& y) + noexcept(noexcept(x.swap(y))); -=== Swap -```c++ template void swap(unordered_node_map& x, unordered_node_map& y) noexcept(noexcept(x.swap(y))); ``` +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -=== erase_if -```c++ template typename unordered_node_map::size_type erase_if(unordered_node_map& c, Predicate pred); ``` +=== erase++_++if +```c++ + +template + typename unordered_node_map::size_type + erase_if(unordered_node_map& c, Predicate pred); + +``` -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` + Note that the references passed to `pred` are non-const. +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` ++ +请注意,传递给 `pred` 的引用是非常量的。 -=== Serialization +=== 序列化 -``unordered_node_map``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++node++_++map` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_node_map to an archive +==== 将 unordered++_++node++_++map 保存到归档 -Saves all the elements of an `unordered_node_map` `x` to an archive (XML archive) `ar`. +将 `unordered++_++node++_++map` `x` 的所有元素保存到归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `std::remove_const::type` and `std::remove_const::type` are serializable (XML serializable), and they do support Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `std::remove++_++const++<++key++_++type++>++::type` 和 `std::remove++_++const++<++mapped++_++type++>++::type` 必须满足可序列化要求(XML 可序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求)。 --- -==== Loading an unordered_node_map from an archive +==== 从归档加载 unordered++_++node++_++map -Deletes all preexisting elements of an `unordered_node_map` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_node_map` `other` saved to the storage read by `ar`. +删除 `unordered++_++node++_++map` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++node++_++map` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `key_type` and `mapped_type` are constructible from `std::remove_const::type&&` and `std::remove_const::type&&`, respectively. `x.key_equal()` is functionally equivalent to `other.key_equal()`. +要求;; `key++_++type` 与 `mapped++_++type` 必须能够分别从 `std::remove++_++const++<++key++_++type++>++::type&&` 和 `std::remove++_++const++<++mapped++_++type++>++::type&&` 构造。且需要 `x.key++_++equal()` 在功能上等价于 `other.key++_++equal()` 。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_node_map` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 所指向的 `unordered++_++node++_++map` 容器 `x` 必须先前已保存至 `ar` ,且在保存 `x` 与保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_node_map` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 若 `x` 是 `it` 所指向的 `unordered++_++node++_++map` 容器,则在加载 `x` 与加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc index e1e5e27..f796a8f 100644 --- a/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_node_set_zh_Hans.adoc @@ -1,21 +1,23 @@ [#unordered_node_set] -== Class Template unordered_node_set +== 类模板 unordered++_++node++_++set :idprefix: unordered_node_set_ -`boost::unordered_node_set` — A node-based, open-addressing unordered associative container that stores unique values. +`boost::unordered++_++node++_++set` — 一种基于节点的开放寻址无序关联容器,用于存储唯一值。 -`boost::unordered_node_set` uses an open-addressing layout like `boost::unordered_flat_set`, but, being node-based, it provides pointer stability and node handling functionalities. Its performance lies between those of `boost::unordered_set` and `boost::unordered_flat_set`. +`boost::unordered++_++node++_++set` 采用与 `boost::unordered++_++flat++_++set` 相似的开放寻址布局,但由于其基于节点的特性,该容器提供了指针稳定性和节点处理功能。其性能介于 `boost::unordered++_++set` 与 `boost::unordered++_++flat++_++set` 之间。 -As a result of its using open addressing, the interface of `boost::unordered_node_set` deviates in a number of aspects from that of `boost::unordered_set`/`std::unordered_set`: +由于其采用开放寻址法, `boost::unordered++_++node++_++set` 的接口在多个方面与 `boost::unordered++_++set` / `std::unordered++_++set` 有所不同: -- `begin()` is not constant-time. - There is no API for bucket handling (except `bucket_count`). - The maximum load factor of the container is managed internally and can't be set by the user. + - `begin()` 不是常数时间复杂度操作。 + - 未提供用于桶管理的 API(除 `bucket++_++count` 外)。 + - 容器的最大负载因子由内部管理,用户无法进行设置。 -Other than this, `boost::unordered_node_set` is mostly a drop-in replacement of standard unordered associative containers. +除此之外, `boost::unordered++_++node++_++set` 几乎可以完全替代标准无序关联容器。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_node_set.adoc[``] @@ -28,7 +30,7 @@ namespace unordered { class Allocator = std::allocator> class unordered_node_set { public: - // types + // 类型 using key_type = Key; using value_type = Key; using init_type = Key; @@ -50,7 +52,7 @@ namespace unordered { using stats = xref:reference/stats.adoc#stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled] - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_node_set_default_constructor[unordered_node_set](); explicit xref:#unordered_node_set_bucket_count_constructor[unordered_node_set](size_type n, const hasher& hf = hasher(), @@ -96,7 +98,7 @@ namespace unordered { unordered_node_set& xref:#unordered_node_set_initializer_list_assignment[operator++=++](std::initializer_list); allocator_type xref:#unordered_node_set_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_node_set_begin[begin]() noexcept; const_iterator xref:#unordered_node_set_begin[begin]() const noexcept; iterator xref:#unordered_node_set_end[end]() noexcept; @@ -104,12 +106,12 @@ namespace unordered { const_iterator xref:#unordered_node_set_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_node_set_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_node_set_empty[empty]() const noexcept; size_type xref:#unordered_node_set_size[size]() const noexcept; size_type xref:#unordered_node_set_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template std::pair xref:#unordered_node_set_emplace[emplace](Args&&... args); template iterator xref:#unordered_node_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); std::pair xref:#unordered_node_set_copy_insert[insert](const value_type& obj); @@ -142,11 +144,11 @@ namespace unordered { template void xref:#unordered_node_set_merge[merge](unordered_node_set&& source); - // observers + // 观察器 hasher xref:#unordered_node_set_hash_function[hash_function]() const; key_equal xref:#unordered_node_set_key_eq[key_eq]() const; - // set operations + // 集合操作 iterator xref:#unordered_node_set_find[find](const key_type& k); const_iterator xref:#unordered_node_set_find[find](const key_type& k) const; template @@ -166,10 +168,10 @@ namespace unordered { template std::pair xref:#unordered_node_set_equal_range[equal_range](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_node_set_bucket_count[bucket_count]() const noexcept; - // hash policy + // 哈希策略 float xref:#unordered_node_set_load_factor[load_factor]() const noexcept; float xref:#unordered_node_set_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_node_set_set_max_load_factor[max_load_factor](float z); @@ -177,12 +179,12 @@ namespace unordered { void xref:#unordered_node_set_rehash[rehash](size_type n); void xref:#unordered_node_set_reserve[reserve](size_type n); - // statistics (if xref:unordered_node_set_boost_unordered_enable_stats[enabled]) + // 统计(如果启用) stats xref:#unordered_node_set_get_stats[get_stats]() const; void xref:#unordered_node_set_reset_stats[reset_stats]() noexcept; }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -227,93 +229,96 @@ namespace unordered { unordered_node_set(std::initializer_list, typename xref:#unordered_node_set_deduction_guides[__see below__]::size_type, Hash, Allocator) -> unordered_node_set, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container. +|_键_ +|`Key` 必须可从容器中 +https://en.cppreference.com/w/cpp/named_req/Erasable[擦除] 。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type `bool`. +|_谓词_ +|二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` 的参数,并返回一个 `bool` +类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The element nodes of the container are held into an internal _bucket array_. A node is inserted into a bucket determined by the hash code of its element, but if the bucket is already occupied (a _collision_), an available one in the vicinity of the original position is used. +容器的元素节点保存在内部的__桶数组__中。节点根据其元素的哈希码被插入到对应的桶中,但如果该桶已被占用(即发生__冲突__),则使用原始位置附近的可用桶。 -The size of the bucket array can be automatically increased by a call to `insert`/`emplace`, or as a result of calling `rehash`/`reserve`. The _load factor_ of the container (number of elements divided by number of buckets) is never greater than `max_load_factor()`, except possibly for small sizes where the implementation may decide to allow for higher loads. +桶数组的大小可通过调用 `insert` / `emplace` 自动增加,也可通过调用 `rehash` / `reserve` 来调整。容器的__负载因子__(元素数量与桶数量的比值)始终不会超过 `max++_++load++_++factor()` ,但在小规模数据情况下,实现可能允许更高的负载因子。 -If `link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[hash_is_avalanching]::value` is `true`, the hash function is used as-is; otherwise, a bit-mixing post-processing stage is added to increase the quality of hashing at the expense of extra computational cost. +若 link:../../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanchinghash[`hash++_++is++_++avalanching`]`++<++Hash++>++::value` 为 `true` ,则直接使用哈希函数;否则,会添加一个位混合后处理阶段以提高哈希质量,但会牺牲额外的计算成本。 --- -=== Configuration Macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_STATS` +==== `BOOST++_++UNORDERED++_++ENABLE++_++STATS` -Globally define this macro to enable xref:reference/stats.adoc#stats[statistics calculation] for the container. Note that this option decreases the overall performance of many operations. +全局定义此宏,以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低许多操作的总体性能。 --- -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存已提取容器元素的类,其建模自 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -324,34 +329,47 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `Iterator` = `iterator` and `NodeType` = `node_type`. +其中 `Iterator` = `iterator` ,且 `NodeType` = `node++_++type` 。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_node_set(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate and `allocator_type()` as the allocator. +unordered_node_set(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、以及 `allocator++_++type()` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_node_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, and `a` as the allocator. +explicit unordered_node_set(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_set(InputIterator f, InputIterator l, @@ -361,76 +379,106 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a` as the allocator, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_node_set(unordered_node_set const& other); ``` +==== 复制构造函数 +```c++ -The copy constructor. Copies the contained elements, hash function, predicate and allocator. +unordered_node_set(unordered_node_set const& other); -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +``` + +复制构造函数。复制其所包含的元素、哈希函数、谓词及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_node_set(unordered_node_set&& other); ``` +==== 移动构造函数 +```c++ + +unordered_node_set(unordered_node_set&& other); -The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +``` + +移动构造函数。 `other` 的内部桶数组直接转移给新容器。哈希函数、谓词和分配器均从 `other` 移动构造。如果统计功能已 xref:#unordered_node_set_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_node_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and inserts the elements from `[f, l)` into it. +template + unordered_node_set(InputIterator f, InputIterator l, const allocator_type& a); + +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_node_set(Allocator const& a); ``` +==== 分配器构造函数 +```c++ + +explicit unordered_node_set(Allocator const& a); + +``` -Constructs an empty container, using allocator `a`. +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_node_set(unordered_node_set const& other, Allocator const& a); ``` +==== 带分配器的复制构造函数 +```c++ -Constructs a container, copying ``other``'s contained elements, hash function, and predicate, but using allocator `a`. +unordered_node_set(unordered_node_set const& other, Allocator const& a); + +``` + +构造一个容器,复制 `other` 中的元素、哈希函数及谓词,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_node_set(unordered_node_set&& other, Allocator const& a); ``` +==== 带分配器的移动构造函数 +```c++ + +unordered_node_set(unordered_node_set&& other, Allocator const& a); + +``` -If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff `a == other.get_allocator()`, and always calls `other.reset_stats()`. +如果 `a == other.get++_++allocator()` ,则 `other` 的元素节点直接转移给新容器;否则,元素从 `other` 移动构造。哈希函数和谓词从 `other` 移动构造,分配器从 `a` 复制构造。如果统计功能已 xref:#unordered_node_set_boost_unordered_enable_stats[启用] ,则当 `a == other.get++_++allocator()` 时,转移 `other` 的内部统计信息,并始终调用 `other.reset++_++stats()` 。 --- -==== Move Constructor from concurrent_node_set +==== 从 concurrent++_++node++_++set 的移动构造函数 -```c++ unordered_node_set(concurrent_node_set&& other); ``` +```c++ -Move construction from a xref:#concurrent_node_set[`concurrent_node_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` and calls `other.reset_stats()`. +unordered_node_set(concurrent_node_set&& other); + +``` + +从 xref:#concurrent_node_set[`concurrent_node_set`][`concurrent++_++node++_++set`] 移动构造。 `other` 的内部桶数组直接转移给新容器。哈希函数、谓词和分配器均从 `other` 移动构造。若统计功能已 xref:#unordered_node_set_boost_unordered_enable_stats[启用] ,则转移 `other` 的内部统计信息,并调用 `other.reset++_++stats()` 。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度;; 常数时间复杂度。 +并发性;; 阻塞于 `other` 。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_node_set(std::initializer_list il, size_type n = _implementation-defined_ @@ -439,666 +487,1019 @@ unordered_node_set(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate and `a`, and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、以及 `a` 作为分配器,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_node_set(size_type n, allocator_type const& a); ``` +==== 带分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate and `a` as the allocator. +unordered_node_set(size_type n, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_node_set(size_type n, hasher const& hf, allocator_type const& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate and `a` as the allocator. +unordered_node_set(size_type n, hasher const& hf, allocator_type const& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词以及 `a` 作为分配器。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator and default hash function and key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_node_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate, and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器以及默认的键相等性谓词,并将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ -```c++ unordered_node_set(std::initializer_list il, const allocator_type& a); ``` +unordered_node_set(std::initializer_list il, const allocator_type& a); -Constructs an empty container using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +``` + +构造一个空容器,使用 `a` 作为分配器、以及默认的哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 -```c++ unordered_node_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +```c++ -Constructs an empty container with at least `n` buckets, using `a` and default hash function and key equality predicate, and inserts the elements from `il` into it. +unordered_node_set(std::initializer_list il, size_type n, const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认哈希函数和键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_node_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +unordered_node_set(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and default key equality predicate,and inserts the elements from `il` into it. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器、默认键相等性谓词,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~unordered_node_set(); ``` +~unordered_node_set(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 -==== Copy Assignment +```c++ -```c++ unordered_node_set& operator=(unordered_node_set const& other); ``` +unordered_node_set& operator=(unordered_node_set const& other); -The assignment operator. Destroys previously existing elements, copy-assigns the hash function and predicate from `other`, copy-assigns the allocator from `other` if `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, and finally inserts copies of the elements of `other`. +``` + +赋值操作符。该操作会销毁容器中原有的元素,并从 `other` 复制赋值哈希函数与键相等性谓词。若 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在,且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则从 `other` 复制赋值分配器,最后插入 `other` 中所有元素的副本。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 --- -==== Move Assignment -```c++ unordered_node_set& operator=(unordered_node_set&& other) noexcept((boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_move_assignment::value) && std::is_same::value); ``` The move assignment operator. Destroys previously existing elements, swaps the hash function and predicate from `other`, and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, and always calls `other.reset_stats()`. +==== 移动赋值 +```c++ + +unordered_node_set& operator=(unordered_node_set&& other) + noexcept((boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_move_assignment::value) && + std::is_same::value); + +``` +移动赋值操作符。该操作会销毁容器中原有的元素,交换 `other` +的哈希函数与键相等性谓词。若 +`Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 +`Alloc::propagate++_++on++_++container++_++move++_++assignment::value` +为 `true` ,则从 `other` 移动赋值分配器。若此时分配器与 +`other.get++_++allocator()` 相等,则直接将 `other` +的内部桶数组转移至当前容器;否则,将插入 `other` +中元素的移动构造副本。若统计功能已 +xref:#unordered_node_set_boost_unordered_enable_stats[启用] +,则当且仅当最终分配器与 `other.get++_++allocator()` +相等时,同时转移其内部统计信息,并始终调用 `other.reset++_++stats()` 。 --- -==== Initializer List Assignment -```c++ unordered_node_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ -Assign from values in initializer list. All previously existing elements are destroyed. +unordered_node_set& operator=(std::initializer_list il); + +``` + +从初始化列表中的值赋值。该操作销毁所有原有元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求 -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. Complexity:;; O(`bucket_count()`) +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 +复杂度;; O(`bucket++_++count()`) --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 + +```c++ -==== empty +[[nodiscard]] bool empty() const noexcept; -```c++ [[nodiscard]] bool empty() const noexcept; ``` +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ + +size_type size() const noexcept; -```c++ size_type size() const noexcept; ``` +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +template std::pair emplace(Args&&... args); + +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ + +template iterator emplace_hint(const_iterator position, Args&&... args); + +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在具有等价键的元素时,插入一个由参数 `args` 构造的对象。 -`position` is a suggestion to where the element should be inserted. This implementation ignores it. +`position` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is constructible from `args`. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + +要求;; `value++_++type` 必须能够从 `args` 参数构造。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); ``` +==== 复制插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +std::pair insert(const value_type& obj); + +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); ``` +==== 移动插入 +```c++ + +std::pair insert(value_type&& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Transparent Insert -```c++ template std::pair insert(K&& k); ``` +==== 透明插入 +```c++ -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +template std::pair insert(K&& k); + +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +iterator insert(const_iterator hint, const value_type& obj); + +``` 当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ + +iterator insert(const_iterator hint, value_type&& obj); -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The `bool` component of the return type is `true` if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 如果插入操作发生,则返回类型的 `bool` 分量为 `true` 。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Transparent Insert with Hint -```c++ template std::pair insert(const_iterator hint, K&& k); ``` +==== 带提示的透明插入 +```c++ + +template std::pair insert(const_iterator hint, K&& k); -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +template void insert(InputIterator first, InputIterator last); + +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into the container from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 必须能够通过 `++*++first` 在容器中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +void insert(std::initializer_list); + +``` + +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load to be greater than the maximum load. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能会导致迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 --- -==== Insert Node -```c++ insert_return_type insert(node_type&& nh); ``` +==== 节点插入 +```c++ + +insert_return_type insert(node_type&& nh); -If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.value()`. `nh` is empty when the function returns. +``` + +如果 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.value()` 的元素时,插入其关联的元素。函数返回时, `nh` 为空。 [horizontal] -Returns:;; An `insert_return_type` object constructed from `position`, `inserted` and `node`: + -* If `nh` is empty, `inserted` is `false`, `position` is `end()`, and `node` is empty. -* Otherwise if the insertion took place, `inserted` is true, `position` points to the inserted element, and `node` is empty. -* If the insertion failed, `inserted` is false, `node` has the previous value of `nh`, and `position` points to an element with a key equivalent to `nh.value()`. -Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 返回一个从 `position` 、 `inserted` 和 `node` 构造的 `insert++_++return++_++type` 对象: + +* 若 `nh` 为空,则 `inserted` 为 `false` , `position` 为 `end()` ,且 `node` 为空。 +* 否则,若插入操作发生,则 `inserted` 为 `true` , `position` 指向被插入的元素,且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 `false` , `node` 保留 `nh` 的原始值,且 `position` 指向一个键等价于 `nh.value()` 的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== Insert Node with Hint -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示的节点插入 +```c++ + +iterator insert(const_iterator hint, node_type&& nh); + +``` -If `nh` is not empty, inserts the associated element in the container if and only if there is no element in the container with a key equivalent to `nh.value()`. `nh` becomes empty if insertion took place, otherwise it is not changed. +如果 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.value()` 的元素时,插入关联的元素。如果插入操作发生,则 `nh` 变为空;否则不变。 -`hint` is a suggestion to where the element should be inserted. This implementation ignores it. +`hint` 是一个关于元素插入位置的提示,本实现将忽略该提示。 [horizontal] -Returns:;; The iterator returned is `end()` if `nh` is empty. If insertion took place, then the iterator points to the newly inserted element; otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` and the container are not equal. +返回;; 若 `nh` 为空,则返回的迭代器为 `end()` 。若插入操作发生,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 如果 `nh` 非空,且 `nh` 与容器的分配器不相等,则行为未定义。 --- -==== Erase by Position +==== 通过位置擦除 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- _convertible-to-iterator_ erase(iterator position); _convertible-to-iterator_ erase(const_iterator position); ---- -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator` immediately following `position` prior to the erasure. Throws:;; Nothing. Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`. +返回;; 返回一个不透明对象,该对象可隐式转换为擦除前紧接在 `position` 之后的 `iterator` 或 `const++_++iterator` 。 +抛出;; 无。 +注意;; 返回的不透明对象必须被立即丢弃或转换为 `iterator` 或 `const++_++iterator` 。 --- -==== Erase by Key -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过键擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(K&& k); -Erase all elements with key equivalent to `k`. +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 + +```c++ + +iterator erase(const_iterator first, const_iterator last); -```c++ iterator erase(const_iterator first, const_iterator last); ``` +``` -Erases the elements in the range from `first` to `last`. +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Nothing in this implementation (neither the `hasher` nor the `key_equal` objects are called). +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 在此实现中不抛出任何异常(既不调用 `hasher` , 也不调用 `key++_++equal` 对象)。 --- -==== swap -```c++ void swap(unordered_node_set& other) noexcept(boost::allocator_traits::is_always_equal::value || boost::allocator_traits::propagate_on_container_swap::value); ``` +==== 交换 +```c++ + +void swap(unordered_node_set& other) + noexcept(boost::allocator_traits::is_always_equal::value || + boost::allocator_traits::propagate_on_container_swap::value); + +``` -Swaps the contents of the container with the parameter. +交换容器与参数的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -==== Extract by Position -```c++ node_type extract(const_iterator position); ``` +==== 通过位置提取 +```c++ + +node_type extract(const_iterator position); + +``` -Extracts the element pointed to by `position`. +提取由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element. Throws:;; Nothing. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象。 +抛出;; 无。 --- -==== Extract by Key -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键提取 +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); + +``` -Extracts the element with key equivalent to `k`, if it exists. +若存在键等价于 `k` 的元素,则提取该元素。 [horizontal] -Returns:;; A `node_type` object holding the extracted element, or empty if no element was extracted. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个包含被提取元素的 `node++_++type` 对象;若未提取到元素,则返回空对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== pull -```c++ init_type pull(const_iterator position); ``` +```c++ + +init_type pull(const_iterator position); + +``` -Move-constructs an `init_value` `x` from the element pointed to by `position`, erases the element and returns `x`. +从 `position` 指向的元素移动构造一个 `init++_++value` 对象 `x` ,擦除该元素并返回 `x` 。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the container. +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` +后置条件;; `size() == 0` , `max++_++load() ++>++= max++_++load++_++factor() ++*++ bucket++_++count()` --- -==== merge -```c++ template void merge(unordered_node_set& source); template void merge(unordered_node_set&& source); ``` +==== 合并 +```c++ -Transfers all the element nodes from `source` whose key is not already present in `*this`. +template + void merge(unordered_node_set& source); +template + void merge(unordered_node_set&& source); + +``` + +转移 `source` 中所有键不在 `++*++this` 中的元素节点。 [horizontal] -Requires:;; `this\->get_allocator() == source.get_allocator()`. Notes:;; Invalidates iterators to the elements transferred. If the resulting size of `*this` is greater than its original maximum load, invalidates all iterators associated to `*this`. +要求;; `this-++>++get++_++allocator() == source.get++_++allocator()` 。 +注意;; 指向被转移元素的迭代器将失效。若 `++*++this` 的最终大小大于其原始最大负载,则与 `++*++this` 关联的所有迭代器将失效。 --- -=== Observers +=== 观察器 -==== get_allocator -``` allocator_type get_allocator() const noexcept; ``` +==== get++_++allocator +``` + +allocator_type get_allocator() const noexcept; + +``` [horizontal] -Returns:;; The container's allocator. +返回;; 容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq -``` key_equal key_eq() const; ``` +==== key++_++eq +``` + +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); ``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `end()` if no such element exists. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器;若不存在这样的元素,则返回 `end()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The size of the bucket array. +返回;; 桶数组的大小。 --- -=== Hash Policy +=== 哈希策略 -==== load_factor -```c++ float load_factor() const noexcept; ``` +==== 负载因子 +```c++ + +float load_factor() const noexcept; + +``` [horizontal] -Returns:;; `static_cast(size())/static_cast(bucket_count())`, or `0` if `bucket_count() == 0`. +返回;; 返回 `static++_++cast++<++float++>++(size())/static++_++cast++<++float++>++(bucket++_++count())` ,若 `bucket++_++count() == 0` , 则返回 `0` 。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) -```c++ float max_load_factor() const noexcept; ``` +```c++ + +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the container's maximum load factor. +返回;; 容器的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Does nothing, as the user is not allowed to change this parameter. Kept for compatibility with `boost::unordered_set`. +效果;; 不执行任何操作,因为用户不允许修改此参数。保留此接口是为了与 `boost::unordered++_++set` 保持兼容。 --- -==== max_load +==== max++_++load(最大负载) -```c++ size_type max_load() const noexcept; ``` +```c++ + +size_type max_load() const noexcept; + +``` [horizontal] -Returns:;; The maximum number of elements the container can hold without rehashing, assuming that no further elements will be erased. Note:;; After construction, rehash or clearance, the container's maximum load is at least `max_load_factor() * bucket_count()`. This number may decrease on erasure under high-load conditions. +返回;; 返回容器在不重哈希的情况下可容纳的最大元素数(假设不再擦除元素)。 +注意;; 在构造、重新哈希或清空操作后,容器的最大负载至少为 `max++_++load++_++factor() ++*++ bucket++_++count()` 。在高负载条件下执行擦除操作时,此数值可能会降低。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); + +``` -Changes if necessary the size of the bucket array so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. If the provided Allocator uses fancy pointers, a default allocation is subsequently performed. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。若使用的分配器采用花式指针,随后会执行默认分配操作。 -Invalidates iterators and changes the order of elements. +使迭代器失效并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`. +void reserve(size_type n); -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +``` + +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` 。 + +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 -Invalidates iterators and changes the order of elements. +使迭代器失效并改变元素顺序。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -=== Statistics +=== 统计信息 -==== get_stats -```c++ stats get_stats() const; ``` +==== get++_++stats +```c++ + +stats get_stats() const; + +``` [horizontal] -Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. +返回;; 返回容器直到目前已执行插入和查找操作的统计摘要。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_node_set_boost_unordered_enable_stats[启用] 时可用. --- -==== reset_stats -```c++ void reset_stats() noexcept; ``` +==== reset++_++stats +```c++ + +void reset_stats() noexcept; + +``` [horizontal] -Effects:;; Sets to zero the internal statistics kept by the container. Notes:;; Only available if xref:reference/stats.adoc#stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. +效果;; 将容器维护的内部统计信息清零。 +注意;; 仅当 xref:reference/stats.adoc#stats[统计计算] 功能 xref:#unordered_node_set_boost_unordered_enable_stats[启用] 时可用. --- -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 -==== operator -```c++ template bool operator==(const unordered_node_set& x, const unordered_node_set& y); ``` +==== operator== +```c++ + +template + bool operator==(const unordered_node_set& x, + const unordered_node_set& y); + +``` -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_node_set& x, const unordered_node_set& y); ``` +==== operator!= +```c++ -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +template + bool operator!=(const unordered_node_set& x, + const unordered_node_set& y); + +``` + +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 -=== Swap -```c++ template void swap(unordered_node_set& x, unordered_node_set& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_node_set& x, + unordered_node_set& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Nothing unless `key_equal` or `hasher` throw on swapping. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 在交换时抛出,否则本操作不会抛出任何异常。 --- -=== erase_if -```c++ template typename unordered_node_set::size_type erase_if(unordered_node_set& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_node_set::size_type + erase_if(unordered_node_set& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` -=== Serialization +=== 序列化 -``unordered_node_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++node++_++set` 可通过本组件库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 进行归档/检索。支持常规归档与 XML 归档两种格式。 -==== Saving an unordered_node_set to an archive +==== 将 unordered++_++node++_++set 保存到归档 -Saves all the elements of an `unordered_node_set` `x` to an archive (XML archive) `ar`. +将 `unordered++_++node++_++set` `x` 的所有元素保存到归档(XML 归档) `ar` 。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 --- -==== Loading an unordered_node_set from an archive +==== 从归档加载 unordered++_++node++_++set -Deletes all preexisting elements of an `unordered_node_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_node_set` `other` saved to the storage read by `ar`. +删除 `unordered++_++node++_++set` 容器 `x` 中所有已存在的元素,并从归档(XML 归档) `ar` 中插入原始 `unordered++_++node++_++set` 容器 `other` 的元素副本,这些副本是从 `ar` 所读取的存储中恢复的。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求,且 `x.key++_++equal()` 在功能上需等价于 `other.key++_++equal()` 。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_node_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; `it` 所指向的 `unordered++_++node++_++set` 容器 `x` 必须先前已保存至 `ar` ,且在保存 `x` 与保存 `it` 期间不得对 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_node_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 若 `x` 是 `it` 所指向的 `unordered++_++node++_++set` 容器,则在加载 `x` 与加载 `it` 期间不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc index 28bba85..f4c9f3e 100644 --- a/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc @@ -1,13 +1,13 @@ [#unordered_set] -== Class Template unordered_set +== 类模板 unordered++_++set :idprefix: unordered_set_ -`boost::unordered_set` — An unordered associative container that stores unique values. +`boost::unordered++_++set` — 一种用于存储唯一值的无序关联容器。 -=== Synopsis +=== 概要 -[listing,subs="+macros,+quotes"] +[listing, subs="+macros,+quotes"] ----- // #include xref:reference/header_unordered_set.adoc[] @@ -20,7 +20,7 @@ namespace unordered { class Allocator = std::allocator> class unordered_set { public: - // types + // 类型定义 using key_type = Key; using value_type = Key; using hasher = Hash; @@ -40,7 +40,7 @@ namespace unordered { using node_type = _implementation-defined_; using insert_return_type = _implementation-defined_; - // construct/copy/destroy + // 构造/复制/销毁 xref:#unordered_set_default_constructor[unordered_set](); explicit xref:#unordered_set_bucket_count_constructor[unordered_set](size_type n, const hasher& hf = hasher(), @@ -84,7 +84,7 @@ namespace unordered { unordered_set& xref:#unordered_set_initializer_list_assignment[operator++=++](std::initializer_list il); allocator_type xref:#unordered_set_get_allocator[get_allocator]() const noexcept; - // iterators + // 迭代器 iterator xref:#unordered_set_begin[begin]() noexcept; const_iterator xref:#unordered_set_begin[begin]() const noexcept; iterator xref:#unordered_set_end[end]() noexcept; @@ -92,12 +92,12 @@ namespace unordered { const_iterator xref:#unordered_set_cbegin[cbegin]() const noexcept; const_iterator xref:#unordered_set_cend[cend]() const noexcept; - // capacity + // 容量 ++[[nodiscard]]++ bool xref:#unordered_set_empty[empty]() const noexcept; size_type xref:#unordered_set_size[size]() const noexcept; size_type xref:#unordered_set_max_size[max_size]() const noexcept; - // modifiers + // 修改器 template std::pair xref:#unordered_set_emplace[emplace](Args&&... args); template iterator xref:#unordered_set_emplace_hint[emplace_hint](const_iterator position, Args&&... args); std::pair xref:#unordered_set_copy_insert[insert](const value_type& obj); @@ -137,11 +137,11 @@ namespace unordered { template void xref:#unordered_set_merge[merge](unordered_multiset&& source); - // observers + // 观察器 hasher xref:#unordered_set_hash_function[hash_function]() const; key_equal xref:#unordered_set_key_eq[key_eq]() const; - // set operations + // 集合操作 iterator xref:#unordered_set_find[find](const key_type& k); const_iterator xref:#unordered_set_find[find](const key_type& k) const; template @@ -167,7 +167,7 @@ namespace unordered { template std::pair xref:#unordered_set_equal_range[equal_range](const K& k) const; - // bucket interface + // 桶接口 size_type xref:#unordered_set_bucket_count[bucket_count]() const noexcept; size_type xref:#unordered_set_max_bucket_count[max_bucket_count]() const noexcept; size_type xref:#unordered_set_bucket_size[bucket_size](size_type n) const; @@ -180,7 +180,7 @@ namespace unordered { const_local_iterator xref:#unordered_set_cbegin_2[cbegin](size_type n) const; const_local_iterator xref:#unordered_set_cend_2[cend](size_type n) const; - // hash policy + // 哈希策略 float xref:#unordered_set_load_factor[load_factor]() const noexcept; float xref:#unordered_set_max_load_factor[max_load_factor]() const noexcept; void xref:#unordered_set_set_max_load_factor[max_load_factor](float z); @@ -188,7 +188,7 @@ namespace unordered { void xref:#unordered_set_reserve[reserve](size_type n); }; - // Deduction Guides + // 推导指引 template>, class Pred = std::equal_to>, @@ -232,109 +232,113 @@ namespace unordered { unordered_set(std::initializer_list, typename xref:#unordered_set_deduction_guides[__see below__]::size_type, Hash, Allocator) -> unordered_set, Allocator>; -} // namespace unordered -} // namespace boost +} // 命名空间 unordered +} // 命名空间 boost ----- --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== -|_Key_ -|`Key` must be https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the container (i.e. `allocator_traits` can destroy it). +|_键_ +|`Key` +需满足从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除] 的要求(即 +`allocator++_++traits` 能够销毁该对象)。 |_Hash_ -|A unary function object type that acts a hash function for a `Key`. It takes a single argument of type `Key` and returns a value of type `std::size_t`. +|一元函数对象类型,用作 `Key` 的哈希函数。它接受一个类型为 `Key` +的参数,并返回一个 `std::size++_++t` 类型的值。 -|_Pred_ -|A binary function object that implements an equivalence relation on values of type `Key`. A binary function object that induces an equivalence relation on values of type `Key`. It takes two arguments of type `Key` and returns a value of type bool. +|_谓词_ +|一种二元函数对象,用于在 `Key` +类型的值上建立等价关系。它接受两个类型为 `Key` +的参数,并返回一个布尔类型的值。 -|_Allocator_ -|An allocator whose value type is the same as the container's value type. -Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported. +|_分配器_ +|一种分配器,其值类型与容器的值类型相同,是一种支持使用 https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[花式指针] 的分配器。 |=== -The elements are organized into buckets. Keys with the same hash code are stored in the same bucket. +元素被组织到多个桶中。具有相同哈希码的键存储在同一个桶内。 -The number of buckets can be automatically increased by a call to insert, or as the result of calling rehash. +桶的数量可通过调用插入操作来自动增加,也可通过调用重哈希操作来调整。 -=== Configuration macros +=== 配置宏 -==== `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` +==== `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` -Globally define this macro to support loading of ``unordered_set``s saved to a Boost.Serialization archive with a version of Boost prior to Boost 1.84. +全局定义此宏可支持加载 Boost 1.84 之前版本保存至 Boost.Serialization 归档文件的 `unordered++_++set` 数据。 -=== Typedefs +=== 类型定义 -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 -Convertible to `const_iterator`. +可转换为 `const++_++iterator` 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_iterator; ---- -A constant iterator whose value type is `value_type`. +一个常量迭代器,其值类型为 `value++_++type` 。 -The iterator category is at least a forward iterator. +迭代器类别至少为前向迭代器。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ local_iterator; ---- -An iterator with the same value type, difference type and pointer and reference type as iterator. +一种迭代器,其值类型、差值类型以及指针和引用类型均与 iterator 相同。 -A `local_iterator` object can be used to iterate through a single bucket. +`local++_++iterator` 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ const_local_iterator; ---- -A constant iterator with the same value type, difference type and pointer and reference type as const_iterator. +一种常量迭代器,其值类型、差值类型以及指针和引用类型均与 const++_++iterator 相同。 -A const_local_iterator object can be used to iterate through a single bucket. +const++_++local++_++iterator 对象可用于遍历单个桶内的元素。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ node_type; ---- -A class for holding extracted container elements, modelling https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle]. +用于保存已提取容器元素的类,其建模自 https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle] 。 --- -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: -[source,c++,subs=+quotes] +[source, c++, subs=+quotes] ---- template struct _insert_return_type_ // name is exposition only @@ -345,34 +349,47 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `Iterator` = `iterator` and `NodeType` = `node_type`. +其中 `Iterator` = `iterator` ,且 `NodeType` = `node++_++type` 。 --- -=== Constructors +=== 构造函数 -==== Default Constructor -```c++ unordered_set(); ``` +==== 默认构造函数 +```c++ -Constructs an empty container using `hasher()` as the hash function, `key_equal()` as the key equality predicate, `allocator_type()` as the allocator and a maximum load factor of `1.0`. +unordered_set(); + +``` + +构造一个空容器,使用 `hasher()` 作为哈希函数、 `key++_++equal()` 作为键相等性谓词、 `allocator++_++type()` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor -```c++ explicit unordered_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```c++ + +explicit unordered_set(size_type n, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数, `eql` 作为键相等性谓词, `a` 作为分配器,并将最大负载因子设为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor -[source,c++,subs="+quotes"] +==== 迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_set(InputIterator f, InputIterator l, @@ -382,71 +399,98 @@ template const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、 `a` 作为分配器,将最大负载因子设为 `1.0` ,并将区间 `++[++f, l)` 中的元素插入其中。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Copy Constructor -```c++ unordered_set(const unordered_set& other); ``` +==== 复制构造函数 +```c++ + +unordered_set(const unordered_set& other); -The copy constructor. Copies the contained elements, hash function, predicate, maximum load factor and allocator. +``` -If `Allocator::select_on_container_copy_construction` exists and has the right signature, the allocator will be constructed from its result. +复制构造函数。复制其所含的元素、哈希函数、谓词、最大负载因子及分配器。 + +若 `Allocator::select++_++on++_++container++_++copy++_++construction` 存在且签名正确,则将根据其结果来构造分配器。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Constructor -```c++ unordered_set(unordered_set&& other); ``` +==== 移动构造函数 +```c++ + +unordered_set(unordered_set&& other); + +``` -The move constructor. +移动构造函数。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move-constructible. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 必须满足可移动构造的要求。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```c++ + +template + unordered_set(InputIterator f, InputIterator l, const allocator_type& a); -Constructs an empty container using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +``` + +构造一个空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并将最大负载因子设为 `1.0` ,然后将 `++[++f, l)` 范围内的元素插入其中。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Allocator Constructor -```c++ explicit unordered_set(const Allocator& a); ``` +==== 分配器构造函数 +```c++ + +explicit unordered_set(const Allocator& a); + +``` -Constructs an empty container, using allocator `a`. +使用分配器 `a` 构造一个空容器。 --- -==== Copy Constructor with Allocator -```c++ unordered_set(const unordered_set& other, const Allocator& a); ``` +==== 带分配器的复制构造函数 +```c++ + +unordered_set(const unordered_set& other, const Allocator& a); + +``` -Constructs an container, copying ``other``'s contained elements, hash function, predicate, maximum load factor, but using allocator `a`. +构造一个容器,复制 `other` 中的元素、哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 --- -==== Move Constructor with Allocator -```c++ unordered_set(unordered_set&& other, const Allocator& a); ``` +==== 带分配器的移动构造函数 +```c++ -Construct a container moving ``other``'s contained elements, and having the hash function, predicate and maximum load factor, but using allocate `a`. +unordered_set(unordered_set&& other, const Allocator& a); + +``` + +构造一个容器,移动 `other` 中所包含的元素,并获取其哈希函数、谓词及最大负载因子,但使用分配器 `a` 。 [horizontal] -Notes:;; This is implemented using Boost.Move. Requires:;; `value_type` is move insertable. +注意;; 此函数通过 Boost.Move 实现。 +要求;; `value++_++type` 需满足可移动插入要求。 --- -==== Initializer List Constructor -[source,c++,subs="+quotes"] +==== 初始化列表构造函数 +[source, c++, subs="+quotes"] ---- unordered_set(std::initializer_list il, size_type n = _implementation-defined_, @@ -455,723 +499,1165 @@ unordered_set(std::initializer_list il, const allocator_type& a = allocator_type()); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `eql` as the key equality predicate, `a` as the allocator and a maximum load factor of `1.0` and inserts the elements from `il` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `eql` 作为键相等性谓词、及 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; If the defaults are used, `hasher`, `key_equal` and `allocator_type` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; 若使用默认值,则 `hasher` 、 `key++_++equal` 和 `allocator++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Allocator -```c++ unordered_set(size_type n, const allocator_type& a); ``` +==== 带分配器的桶数构造函数 +```c++ + +unordered_set(size_type n, const allocator_type& a); + +``` -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default hash function and key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数(应为默认哈希函数)、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Bucket Count Constructor with Hasher and Allocator -```c++ unordered_set(size_type n, const hasher& hf, const allocator_type& a); ``` +==== 带哈希函数和分配器的桶数构造函数 +```c++ -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, the default key equality predicate, `a` as the allocator and a maximum load factor of `1.0`. +unordered_set(size_type n, const hasher& hf, const allocator_type& a); + +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` 。 [horizontal] -Postconditions:;; `size() == 0` Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +后置条件;; `size() == 0` +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Allocator -[source,c++,subs="+quotes"] +==== 带桶数和分配器的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `a` as the allocator, with the default hash function and key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器、默认的哈希函数和键相等性谓词,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== Iterator Range Constructor with Bucket Count and Hasher -[source,c++,subs="+quotes"] +==== 带桶数和哈希函数的迭代器范围构造函数 +[source, c++, subs="+quotes"] ---- template unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a); ---- -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator, with the default key equality predicate and a maximum load factor of `1.0` and inserts the elements from `[f, l)` into it. +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、默认的键相等性谓词、 `a` 作为分配器,并设置最大负载因子为 `1.0` ,随后将区间 `++[++f, l)` 中的元素插入该容器。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 + +```c++ -```c++ unordered_set(std::initializer_list il, const allocator_type& a); ``` +unordered_set(std::initializer_list il, const allocator_type& a); -Constructs an empty container using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +``` + +使用 `a` 作为分配器构造一个空容器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Allocator +==== 带桶数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +unordered_set(std::initializer_list il, size_type n, const allocator_type& a); -Constructs an empty container with at least `n` buckets, using `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `a` 作为分配器,并设置最大负载因子为 1.0,随后将 `il` 中的元素插入该容器。 [horizontal] -Requires:;; `hasher` and `key_equal` need to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `hasher` 和 `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -==== initializer_list Constructor with Bucket Count and Hasher and Allocator +==== 带桶数、哈希函数和分配器的初始化列表构造函数 + +```c++ -```c++ unordered_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +unordered_set(std::initializer_list il, size_type n, const hasher& hf, + const allocator_type& a); -Constructs an empty container with at least `n` buckets, using `hf` as the hash function, `a` as the allocator and a maximum load factor of 1.0 and inserts the elements from `il` into it. +``` + +构造一个至少包含 `n` 个桶的空容器,使用 `hf` 作为哈希函数、 `a` 作为分配器,设置最大负载因子为 1.0,并将 `il` 中的元素插入其中。 [horizontal] -Requires:;; `key_equal` needs to be https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^]. +要求;; `key++_++equal` 需满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求。 --- -=== Destructor +=== 析构函数 + +```c++ -```c++ ~unordered_set(); ``` +~unordered_set(); + +``` [horizontal] -Note:;; The destructor is applied to every element, and all memory is deallocated +注意;; 析构函数会作用于每个元素,并释放所有内存 --- -=== Assignment +=== 赋值操作 + +==== 复制赋值 + +```c++ -==== Copy Assignment +unordered_set& operator=(const unordered_set& other); -```c++ unordered_set& operator=(const unordered_set& other); ``` +``` -The assignment operator. Copies the contained elements, hash function, predicate and maximum load factor but not the allocator. +赋值运算符。该操作会复制容器内的元素、哈希函数、谓词及最大负载因子,但不会复制分配器。 -If `Alloc::propagate_on_container_copy_assignment` exists and `Alloc::propagate_on_container_copy_assignment::value` is `true`, the allocator is overwritten, if not the copied elements are created using the existing allocator. +如果 `Alloc::propagate++_++on++_++container++_++copy++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++copy++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is copy constructible +要求;; `value++_++type` 必须满足可复制构造要求 --- -==== Move Assignment -```c++ unordered_set& operator=(unordered_set&& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_move_assignable_v && boost::is_nothrow_move_assignable_v); ``` The move assignment operator. +==== 移动赋值 +```c++ + +unordered_set& operator=(unordered_set&& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_move_assignable_v && + boost::is_nothrow_move_assignable_v); + +``` +移动赋值运算符。 -If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator. +如果 `Alloc::propagate++_++on++_++container++_++move++_++assignment` 存在且 `Alloc::propagate++_++on++_++container++_++move++_++assignment::value` 为 `true` ,则覆盖原分配器;否则将使用现有分配器创建被复制的元素。 [horizontal] -Requires:;; `value_type` is move constructible. +要求;; `value++_++type` 需满足可移动构造要求。 --- -==== Initializer List Assignment -```c++ unordered_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```c++ -Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed. +unordered_set& operator=(std::initializer_list il); + +``` + +将初始化列表中的值赋给容器。所有已存在的元素将被新元素覆盖或销毁。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container and https://en.cppreference.com/w/cpp/named_req/CopyAssignable[CopyAssignable^]. +要求;; `value++_++type` 必须满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 至容器以及 https://en.cppreference.com/w/cpp/named_req/CopyAssignable[可复制赋值] 的要求。 --- -=== Iterators +=== 迭代器 ==== begin -```c++ iterator begin() noexcept; const_iterator begin() const noexcept; ``` +```c++ + +iterator begin() noexcept; const_iterator begin() const noexcept; + +``` [horizontal] -Returns:;; An iterator referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的迭代器;若容器为空,则返回容器的结束迭代器。 --- ==== end -```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` +```c++ + +iterator end() noexcept; const_iterator end() const noexcept; + +``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回;; 返回指向容器结束位置的迭代器。 --- ==== cbegin -```c++ const_iterator cbegin() const noexcept; ``` +```c++ + +const_iterator cbegin() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` referring to the first element of the container, or if the container is empty the past-the-end value for the container. +返回;; 返回一个指向容器第一个元素的 `const++_++iterator` (常量迭代器);若容器为空,则返回容器的结束迭代器。 --- ==== cend -```c++ const_iterator cend() const noexcept; ``` +```c++ + +const_iterator cend() const noexcept; + +``` [horizontal] -Returns:;; A `const_iterator` which refers to the past-the-end value for the container. +返回;; 返回一个指向容器结束位置的 `const++_++iterator` (常量迭代器)。 --- -=== Size and Capacity +=== 大小与容量 + +==== 空 -==== empty +```c++ -```c++ [[nodiscard]] bool empty() const noexcept; ``` +[[nodiscard]] bool empty() const noexcept; + +``` [horizontal] -Returns:;; `size() == 0` +返回;; `size() == 0` --- -==== size +==== 大小 + +```c++ -```c++ size_type size() const noexcept; ``` +size_type size() const noexcept; + +``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回;; `std::distance(begin(), end())` --- -==== max_size +==== max++_++size + +```c++ + +size_type max_size() const noexcept; -```c++ size_type max_size() const noexcept; ``` +``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回;; 返回该容器可能容纳的最大值 `size()` 。 --- -=== Modifiers +=== 修改器 + +==== 原地构造 +```c++ + +template std::pair emplace(Args&&... args); -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +``` -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent value. +当且仅当容器中不存在等价元素时,插入一个由参数 `args` 构造的对象。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价值的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +==== emplace++_++hint +```c++ -Inserts an object, constructed with the arguments `args`, in the container if and only if there is no element in the container with an equivalent value. +template iterator emplace_hint(const_iterator position, Args&&... args); -`position` is a suggestion to where the element should be inserted. +``` + +当且仅当容器中不存在等价元素时,插入一个由参数 `args` 构造的对象。 + +`position` 是一个关于插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `args`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须满足从 `args` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原位构造] 到 `X` 容器的要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Copy Insert -```c++ std::pair insert(const value_type& obj); ``` +==== 复制插入 +```c++ + +std::pair insert(const value_type& obj); + +``` -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert -```c++ std::pair insert(value_type&& obj); ``` +==== 移动插入 +```c++ -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +std::pair insert(value_type&& obj); + +``` + +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Transparent Insert -```c++ template std::pair insert(K&& k); ``` +==== 透明插入 +```c++ + +template std::pair insert(K&& k); -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +``` + +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; The bool component of the return type is true if an insert took place. + + If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则返回类型的布尔分量为 true。 + ++ +若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Copy Insert with Hint -```c++ iterator insert(const_iterator hint, const value_type& obj); ``` Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +==== 带提示的复制插入 +```c++ + +iterator insert(const_iterator hint, const value_type& obj); -`hint` is a suggestion to where the element should be inserted. +``` 当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Move Insert with Hint -```c++ iterator insert(const_iterator hint, value_type&& obj); ``` +==== 带提示的移动插入 +```c++ + +iterator insert(const_iterator hint, value_type&& obj); -Inserts `obj` in the container if and only if there is no element in the container with an equivalent key. +``` -`hint` is a suggestion to where the element should be inserted. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Transparent Insert with Hint -```c++ template iterator insert(const_iterator hint, K&& k); ``` +==== 带提示的透明插入 +```c++ + +template iterator insert(const_iterator hint, K&& k); -Inserts an element constructed from `std::forward(k)` in the container if and only if there is no element in the container with an equivalent key. +``` -`hint` is a suggestion to where the element should be inserted. +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] from `k`. Returns:;; If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +要求;; `value++_++type` 需满足从 `k` 参数 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 的要求。 +返回;; 若插入成功,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时,该重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert Iterator Range -```c++ template void insert(InputIterator first, InputIterator last); ``` +==== 迭代器范围插入 +```c++ + +template void insert(InputIterator first, InputIterator last); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] into `X` from `*first`. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 必须能够通过 `++*++first` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到 `X` 中。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Insert Initializer List -```c++ void insert(std::initializer_list); ``` +==== 初始化列表插入 +```c++ + +void insert(std::initializer_list); + +``` -Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key. +将元素范围插入容器中。仅当容器中不存在等价键的元素时,才会插入相应元素。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/CopyInsertable[CopyInsertable^] into the container. Throws:;; When inserting a single element, if an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/CopyInsertable[可复制插入] 到容器中的要求。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 --- -==== Extract by Iterator -```c++ node_type extract(const_iterator position); ``` +==== 通过迭代器提取 +```c++ -Removes the element pointed to by `position`. +node_type extract(const_iterator position); + +``` + +移除由 `position` 指向的元素。 [horizontal] -Returns:;; A `node_type` owning the element. Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multiset`, but that is not supported yet. +返回;; 返回一个拥有该元素的 `node++_++type` 对象。 +注意;; 在 C{plus}{plus}17 标准中,通过此方法提取的节点可被插入到兼容的 `unordered++_++multiset` 中,但该特性暂未获得支持。 --- -==== Extract by Value -```c++ node_type extract(const key_type& k); template node_type extract(K&& k); ``` +==== 通过键值提取元素 +```c++ + +node_type extract(const key_type& k); template node_type extract(K&& k); + +``` -Removes an element with key equivalent to `k`. +移除键等价于 `k` 的元素。 [horizontal] -Returns:;; A `node_type` owning the element if found, otherwise an empty `node_type`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In C++17 a node extracted using this method can be inserted into a compatible `unordered_multiset`, but that is not supported yet. + + The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 如果找到,则返回一个拥有该元素的 `node++_++type` 对象;否则返回一个空的 `node++_++type` 对象。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 在 C{plus}{plus}17 标准中,通过此方法提取的节点可被插入到兼容的 `unordered++_++multiset` 中,但该特性暂未获得支持。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Insert with `node_handle` -```c++ insert_return_type insert(node_type&& nh); ``` +==== 通过 `node++_++handle` 插入 +```c++ -If `nh` is empty, has no effect. +insert_return_type insert(node_type&& nh); -Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. +``` + +若 `nh` 为空节点,则此操作不产生任何效果。 + +否则,当且仅当容器中不存在等价键的元素时,才会插入 `nh` 所拥有的元素。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty, returns an `insert_return_type` with: `inserted` equal to `false`, `position` equal to `end()` and `node` empty. + + Otherwise if there was already an element with an equivalent key, returns an `insert_return_type` with: `inserted` equal to `false`, `position` pointing to a matching element and `node` contains the node from `nh`. + + Otherwise if the insertion succeeded, returns an `insert_return_type` with: `inserted` equal to `true`, `position` pointing to the newly inserted element and `node` empty. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + In C++17 this can be used to insert a node extracted from a compatible `unordered_multiset`, but that is not supported yet. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 如果 `nh` 为空,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `false` , `position` 等于 `end()` ,且 `node` 为空。 + ++ +否则,如果已存在具有等价键的元素,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `false` , `position` 指向匹配的元素,且 `node` 包含来自 `nh` 的节点。 + ++ +否则,如果插入操作成功,则返回一个 `insert++_++return++_++type` ,其中: `inserted` 等于 `true` , `position` 指向新插入的元素,且 `node` 为空。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; 可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +在 C{plus}{plus}17 标准中,此方法可用于插入从兼容的 `unordered++_++multiset` 中提取的节点,但该功能暂未获得支持。 --- -==== Insert with Hint and `node_handle` -```c++ iterator insert(const_iterator hint, node_type&& nh); ``` +==== 带提示和 `node++_++handle` 的插入 +```c++ + +iterator insert(const_iterator hint, node_type&& nh); -If `nh` is empty, has no effect. +``` -Otherwise inserts the element owned by `nh` if and only if there is no element in the container with an equivalent key. +若 `nh` 为空节点,则此操作不产生任何效果。 -If there is already an element in the container with an equivalent key has no effect on `nh` (i.e. `nh` still contains the node.) +否则,当且仅当容器中不存在等价键的元素时,才会插入 `nh` 所拥有的元素。 -`hint` is a suggestion to where the element should be inserted. +如果容器中已存在具有等价键的元素,则对 `nh` 不产生任何影响.(即 `nh` 仍持有该节点.) + +`hint` 是插入元素位置的建议。 [horizontal] -Requires:;; `nh` is empty or `nh.get_allocator()` is equal to the container's allocator. Returns:;; If `nh` was empty returns `end()`. + + If there was already an element in the container with an equivalent key returns an iterator pointing to that. + + Otherwise returns an iterator pointing to the newly inserted element. Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect. Notes:;; The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. + + Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. + + Pointers and references to elements are never invalidated. + + This can be used to insert a node extracted from a compatible `unordered_multiset`. +要求;; `nh` 必须是空节点,或其分配器 `nh.get++_++allocator()` 需与容器的分配器相等。 +返回;; 如果 `nh` 为空,则返回 `end()` 。 + ++ +若容器中已存在具有等效键的元素,则返回指向该元素的迭代器。 + ++ +否则,返回指向新插入元素的迭代器。 +抛出;; 若异常由 `hasher` 调用之外的操作引发,则该函数不产生任何效果。 +注意;; C{plus}{plus}标准对提示参数含义的规定相当笼统。在实际使用中唯一有效的方式(也是Boost.Unordered唯一支持的用法)是指向具有相同键的现有元素。 + ++ +可能引发迭代器失效,但仅当插入操作导致负载因子大于或等于最大负载因子时才会发生。 + ++ +指向元素的指针和引用永远不会失效。 + ++ +此操作用于插入从兼容的 `unordered++_++multiset` 中提取的节点。 --- -==== Erase by Position +==== 通过位置擦除 + +```c++ -```c++ iterator erase(iterator position); iterator erase(const_iterator position); ``` +iterator erase(iterator position); iterator erase(const_iterator position); -Erase the element pointed to by `position`. +``` + +擦除由 `position` 指向的元素。 [horizontal] -Returns:;; The iterator following `position` before the erasure. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; In older versions this could be inefficient because it had to search through several buckets to find the position of the returned iterator. The data structure has been changed so that this is no longer the case, and the alternative erase methods have been deprecated. +返回;; 返回擦除操作前紧接在 `position` 之后的迭代器。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 在旧版本中,此操作可能效率较低,因为需要遍历多个桶来定位返回迭代器的位置。但数据结构现已优化,不再存在此问题,因此其他擦除方法已被弃用。 --- -==== Erase by Value -```c++ size_type erase(const key_type& k); template size_type erase(K&& k); ``` +==== 通过值擦除 +```c++ + +size_type erase(const key_type& k); template size_type erase(K&& k); -Erase all elements with key equivalent to `k`. +``` + +擦除所有键等价于 `k` 的元素。 [horizontal] -Returns:;; The number of elements erased. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 被擦除的元素数量。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,才会抛出异常。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名,且 `iterator` 和 `const++_++iterator` 均不能从 `K` 类型隐式转换时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 + +```c++ -```c++ iterator erase(const_iterator first, const_iterator last); ``` +iterator erase(const_iterator first, const_iterator last); -Erases the elements in the range from `first` to `last`. +``` + +擦除从 `first` 到 `last` 范围内(包含 `first` ,不包含 `last` )的元素。 [horizontal] -Returns:;; The iterator following the erased elements - i.e. `last`. Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. +返回;; 返回被擦除元素之后的迭代器——即 `last` 。 +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 --- -==== quick_erase -```c++ void quick_erase(const_iterator position); ``` +==== quick++_++erase +```c++ + +void quick_erase(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== erase_return_void -```c++ void erase_return_void(const_iterator position); ``` +==== erase++_++return++_++void +```c++ + +void erase_return_void(const_iterator position); + +``` -Erase the element pointed to by `position`. +擦除由 `position` 指向的元素。 [horizontal] -Throws:;; Only throws an exception if it is thrown by `hasher` or `key_equal`. + + In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations. Notes:;; This method was implemented because returning an iterator to the next element from erase was expensive, but the container has been redesigned so that is no longer the case. So this method is now deprecated. +抛出;; 仅当 `hasher` 或 `key++_++equal` 抛出异常时,本函数才会抛出异常。 + ++ +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 +注意;; 此方法被实现是因为从擦除操作返回下一个元素的迭代器代价高昂,但容器经过重新设计后该问题已得到解决,因此该方法现已被弃用。 --- -==== swap -```c++ void swap(unordered_set& other) noexcept(boost::allocator_traits::is_always_equal::value && boost::is_nothrow_swappable_v && boost::is_nothrow_swappable_v); ``` +==== 交换 +```c++ -Swaps the contents of the container with the parameter. +void swap(unordered_set& other) + noexcept(boost::allocator_traits::is_always_equal::value && + boost::is_nothrow_swappable_v && + boost::is_nothrow_swappable_v); -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +``` + +交换容器与参数的内容。 + +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -==== clear -```c++ void clear() noexcept; ``` +==== 清空 +```c++ + +void clear() noexcept; + +``` -Erases all elements in the container. +擦除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0` Throws:;; Never throws an exception. +后置条件;; `size() == 0` +抛出;; 从不抛出任何异常。 --- -==== merge -```c++ template void merge(unordered_set& source); template void merge(unordered_set&& source); template void merge(unordered_multiset& source); template void merge(unordered_multiset&& source); ``` +==== 合并 +```c++ -Attempt to "merge" two containers by iterating `source` and extracting any node in `source` that is not contained in `*this` and then inserting it into `*this`. +template + void merge(unordered_set& source); +template + void merge(unordered_set&& source); +template + void merge(unordered_multiset& source); +template + void merge(unordered_multiset&& source); -Because `source` can have a different hash function and key equality predicate, the key of each node in `source` is rehashed using `this\->hash_function()` and then, if required, compared using `this\->key_eq()`. +``` -The behavior of this function is undefined if `this\->get_allocator() != source.get_allocator()`. +通过遍历 `source` 容器,提取其中所有不包含在 `++*++this` 中的节点,并将其插入到 `++*++this` 中,以此尝试将两个容器"合并"。 -This function does not copy or move any elements and instead simply relocates the nodes from `source` into `*this`. +由于 `source` 可以有不同的哈希函数和键相等性谓词,因此会使用 `this-++>++hash++_++function()` 操作对 `source` 中每个节点的键进行重哈希,并在需要时使用 `this-++>++key++_++eq()` 进行比较。 + +如果 `this-++>++get++_++allocator() != source.get++_++allocator()` ,则此函数的行为未定义。 + +此函数不会复制或移动任何元素,而是直接将节点从 `source` 重新定位到 `++*++this` 中。 [horizontal] -Notes:;; + -- -* Pointers and references to transferred elements remain valid. -* Invalidates iterators to transferred elements. -* Invalidates iterators belonging to `*this`. -* Iterators to non-transferred elements in `source` remain valid. +注意;; ++ +-- +* 指向被转移元素的指针和引用保持有效。 +* 使指向被转移元素的迭代器失效。 +* 使属于 `++*++this` 的迭代器失效。 +* 指向 `source` 中未被转移元素的迭代器保持有效。 -- ---- +* --- + +=== 观察器 -=== Observers +==== get++_++allocator +``` -==== get_allocator -``` allocator_type get_allocator() const; ``` +allocator_type get_allocator() const; + +``` --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +``` + +hasher hash_function() const; + +``` [horizontal] -Returns:;; The container's hash function. +返回;; 容器的哈希函数。 --- -==== key_eq +==== key++_++eq + +``` -``` key_equal key_eq() const; ``` +key_equal key_eq() const; + +``` [horizontal] -Returns:;; The container's key equality predicate +返回;; 容器的键相等性谓词 --- -=== Lookup +=== 查找 ==== find -```c++ iterator find(const key_type& k); const_iterator find(const key_type& k) const; template iterator find(const K& k); template const_iterator find(const K& k) const; template iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq); template const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, CompatiblePredicate const& eq) const; ``` +```c++ + +iterator find(const key_type& k); +const_iterator find(const key_type& k) const; +template + iterator find(const K& k); +template + const_iterator find(const K& k) const; +template + iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq); +template + const_iterator find(CompatibleKey const& k, CompatibleHash const& hash, + CompatiblePredicate const& eq) const; + +``` [horizontal] -Returns:;; An iterator pointing to an element with key equivalent to `k`, or `b.end()` if no such element exists. Notes:;; The templated overloads containing `CompatibleKey`, `CompatibleHash` and `CompatiblePredicate` are non-standard extensions which allow you to use a compatible hash function and equality predicate for a key of a different type in order to avoid an expensive type cast. In general, its use is not encouraged and instead the `K` member function templates should be used. + + The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个指向键等价于 `k` 的元素的迭代器,若不存在这样的元素,则返回 `b.end()` 。 +注意;; 包含 `CompatibleKey` 、 `CompatibleHash` 和 `CompatiblePredicate` 的模板化重载是非标准扩展,允许用户使用兼容的哈希函数和相等性谓词来处理不同类型的键,以避免昂贵的类型转换。通常不鼓励使用此扩展,而应改用基于 `K` 的成员函数模板。 + ++ +仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== count -```c++ size_type count(const key_type& k) const; template size_type count(const K& k) const; ``` +```c++ + +size_type count(const key_type& k) const; +template + size_type count(const K& k) const; + +``` [horizontal] -Returns:;; The number of elements with key equivalent to `k`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键等价于 `k` 的元素数量。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== contains -```c++ bool contains(const key_type& k) const; template bool contains(const K& k) const; ``` +==== 包含 +```c++ + +bool contains(const key_type& k) const; +template + bool contains(const K& k) const; + +``` [horizontal] -Returns:;; A boolean indicating whether or not there is an element with key equal to `key` in the container Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回一个布尔值,来表示容器中是否存在键等于 `key` 的元素 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -==== equal_range -```c++ std::pair equal_range(const key_type& k); std::pair equal_range(const key_type& k) const; template std::pair equal_range(const K& k); template std::pair equal_range(const K& k) const; ``` +==== equal++_++range +```c++ + +std::pair equal_range(const key_type& k); +std::pair equal_range(const key_type& k) const; +template + std::pair equal_range(const K& k); +template + std::pair equal_range(const K& k) const; + +``` [horizontal] -Returns:;; A range containing all elements with key equivalent to `k`. If the container doesn't contain any such elements, returns `std::make_pair(b.end(), b.end())`. Notes:;; The `template` overloads only participate in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回包含所有键等价于 `k`的元素的范围。若容器中不存在此类元素,则返回 `std::make++_++pair(b.end(), b.end())` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假定 `Hash` 可同时被 `K` 和 `Key` 类型调用,且 `Pred` 为透明谓词。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count -```c++ size_type bucket_count() const noexcept; ``` +==== bucket++_++count +```c++ + +size_type bucket_count() const noexcept; + +``` [horizontal] -Returns:;; The number of buckets. +返回;; 桶的数量。 --- -==== max_bucket_count -```c++ size_type max_bucket_count() const noexcept; ``` +==== max++_++bucket++_++count +```c++ + +size_type max_bucket_count() const noexcept; + +``` [horizontal] -Returns:;; An upper bound on the number of buckets. +返回;; 桶数量的上限。 --- -==== bucket_size -```c++ size_type bucket_size(size_type n) const; ``` +==== 桶大小 +```c++ + +size_type bucket_size(size_type n) const; + +``` [horizontal] -Requires:;; `n < bucket_count()` Returns:;; The number of elements in bucket `n`. +要求;; `n ++<++ bucket++_++count()` +返回;; 返回桶 `n` 中的元素数量。 --- -==== bucket -```c++ size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; ``` +==== 桶 +```c++ + +size_type bucket(const key_type& k) const; template size_type bucket(const K& k) const; + +``` [horizontal] -Returns:;; The index of the bucket which would contain an element with key `k`. Postconditions:;; The return value is less than `bucket_count()`. Notes:;; The `template` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type. +返回;; 返回键为 `k` 的元素所在桶的索引。 +后置条件;; 返回值应小于 `bucket++_++count()` 。 +注意;; 仅当 `Hash::is++_++transparent` 与 `Pred::is++_++transparent` 均为有效的成员类型别名时, `template++<++class K++>++` 重载才会参与重载决议。标准库假设 `Hash` 可同时被 `K` 与 `Key` 类型调用,且 `Pred` 为透明的。这支持异构查找,该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- ==== begin -```c++ local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; ``` +```c++ + +local_iterator begin(size_type n); const_local_iterator begin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的局部迭代器。 --- ==== end -```c++ local_iterator end(size_type n); const_local_iterator end(size_type n) const; ``` +```c++ + +local_iterator end(size_type n); const_local_iterator end(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的局部迭代器。 --- ==== cbegin -```c++ const_local_iterator cbegin(size_type n) const; ``` +```c++ + +const_local_iterator cbegin(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the first element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中第一个元素的常量局部迭代器。 --- ==== cend -```c++ const_local_iterator cend(size_type n) const; ``` +```c++ + +const_local_iterator cend(size_type n) const; + +``` [horizontal] -Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A constant local iterator pointing the 'one past the end' element in the bucket with index `n`. +要求;; `n` 的取值范围应为 `++[++0, bucket++_++count())` 。 +返回;; 返回指向索引为 `n` 的桶中“末尾之后”元素的常量局部迭代器。 --- -=== Hash Policy +=== 哈希策略 + +==== 负载因子 +```c++ + +float load_factor() const noexcept; -==== load_factor -```c++ float load_factor() const noexcept; ``` +``` [horizontal] -Returns:;; The average number of elements per bucket. +返回;; 返回每个桶的平均元素数量。 --- -==== max_load_factor +==== max++_++load++_++factor(最大负载因子) -```c++ float max_load_factor() const noexcept; ``` +```c++ + +float max_load_factor() const noexcept; + +``` [horizontal] -Returns:;; Returns the current maximum load factor. +返回;; 返回当前的最大负载因子。 --- -==== Set max_load_factor -```c++ void max_load_factor(float z); ``` +==== 设置最大负载因子 +```c++ + +void max_load_factor(float z); + +``` [horizontal] -Effects:;; Changes the container's maximum load factor, using `z` as a hint. +效果;; 使用 `z` 作为提示来更改容器的最大负载因子。 --- -==== rehash -```c++ void rehash(size_type n); ``` +==== 重哈希 +```c++ + +void rehash(size_type n); -Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container. +``` -When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array. +改变桶的数量,使其至少为 `n` 个,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器关联的 `bucket++_++count()` 。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 + +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 --- -==== reserve -```c++ void reserve(size_type n); ``` +==== 保留 +```c++ + +void reserve(size_type n); -Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits::infinity()`. +``` -Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container. +等价于 `a.rehash(ceil(n / a.max++_++load++_++factor()))` ,若 `n ++>++ 0` 且 `a.max++_++load++_++factor() == std::numeric++_++limits++<++float++>++::infinity()` ,则等价于 `a.rehash(1)` 。 -Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated. +与 `rehash` 类似,此函数可用于增加或减少容器中的桶数量。 + +使迭代器失效,并改变元素顺序。指向元素的指针和引用不会失效。 [horizontal] -Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +抛出;; 若抛出异常(除非异常由容器的哈希函数或比较函数抛出),则该函数不产生任何效果。 -=== Deduction Guides -A deduction guide will not participate in overload resolution if any of the following are true: +=== 推导指引 +如果以下任何一条件为真,则推导指引将不参与重载决议: -- It has an `InputIterator` template parameter and a type that does not qualify as an input iterator is deduced for that parameter. - It has an `Allocator` template parameter and a type that does not qualify as an allocator is deduced for that parameter. - It has a `Hash` template parameter and an integral type or a type that qualifies as an allocator is deduced for that parameter. - It has a `Pred` template parameter and a type that qualifies as an allocator is deduced for that parameter. + - 该推导指引包含 `InputIterator` 模板参数,且为此参数推导出的类型不符合输入迭代器的要求。 + - 该推导指引包含 `Allocator` 模板参数,且为该参数推导出的类型不符合分配器要求。 + - 该推导指引包含 `Hash` 模板参数,且为该参数推导出的类型为整型或符合分配器要求。 + - 该推导指引包含 `Pred` 模板参数,且为该参数推导出的类型符合分配器要求。 -A `size_­type` parameter type in a deduction guide refers to the `size_­type` member type of the container type deduced by the deduction guide. Its default value coincides with the default value of the constructor selected. +推导指引中的 `size++_++type` 参数类型,指向由该推导指引所推导容器类型的 `size++_++type` 成员类型。其默认值与所选构造函数的默认值一致。 -==== __iter-value-type__ -[listings,subs="+macros,+quotes"] +==== _iter-value-type_ +[listings, subs="+macros,+quotes"] ----- template using __iter-value-type__ = typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 + +==== operator== +```c++ -==== operator -```c++ template bool operator==(const unordered_set& x, const unordered_set& y); ``` +template + bool operator==(const unordered_set& x, + const unordered_set& y); -Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +``` + +若 `x.size() == y.size()` 且对于 `x` 中的每个元素, `y` 中均存在一个具有相同键和相等值(使用 `operator==` 比较值类型)的元素,则返回 `true` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -==== operator! -```c++ template bool operator!=(const unordered_set& x, const unordered_set& y); ``` +==== operator!= +```c++ + +template + bool operator!=(const unordered_set& x, + const unordered_set& y); + +``` -Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types). +如果 `x.size() == y.size()` ,且对于 `x` 中的每个元素,在 `y` 中均存在一个具有相同键且值相等的元素(使用 `operator==` 比较值类型),则返回 `false` 。 [horizontal] -Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates. +注意;; 如果两个容器的相等性谓词不等价,则行为未定义。 --- -=== Swap -```c++ template void swap(unordered_set& x, unordered_set& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```c++ + +template + void swap(unordered_set& x, + unordered_set& y) + noexcept(noexcept(x.swap(y))); + +``` -Swaps the contents of `x` and `y`. +交换 `x` 与 `y` 的内容。 -If `Allocator::propagate_on_container_swap` is declared and `Allocator::propagate_on_container_swap::value` is `true` then the containers' allocators are swapped. Otherwise, swapping with unequal allocators results in undefined behavior. +如果声明了 `Allocator::propagate++_++on++_++container++_++swap` 且 `Allocator::propagate++_++on++_++container++_++swap::value` 为 `true` ,则交换容器的分配器。则,在分配器不相等的情况下进行交换将导致未定义行为。 [horizontal] -Effects:;; `x.swap(y)` Throws:;; Doesn't throw an exception unless it is thrown by the copy constructor or copy assignment operator of `key_equal` or `hasher`. Notes:;; The exception specifications aren't quite the same as the C++11 standard, as the equality predicate and hash function are swapped using their copy constructors. +效果;; `x.swap(y)` +抛出;; 除非异常由 `key++_++equal` 或 `hasher` 的复制构造函数或复制赋值运算符抛出,否则本操作不会抛出异常。 +注意;; 此处的异常规范与 C{plus}{plus}11 标准不完全一致,因为相等性谓词和哈希函数是通过其复制构造函数完成交换的。 --- -=== erase_if -```c++ template typename unordered_set::size_type erase_if(unordered_set& c, Predicate pred); ``` +=== erase++_++if +```c++ -Traverses the container `c` and removes all elements for which the supplied predicate returns `true`. +template + typename unordered_set::size_type + erase_if(unordered_set& c, Predicate pred); + +``` + +遍历容器 `c` ,并删除所有使提供的谓词返回 `true` 的元素。 [horizontal] -Returns:;; The number of erased elements. Notes:;; Equivalent to: + + ```c++ auto original_size = c.size(); for (auto i = c.begin(), last = c.end(); i != last; ) { if (pred(*i)) { i = c.erase(i); } else { ++i; } } return original_size - c.size(); ``` +返回;; 被擦除的元素数量。 +注意;; 等价于: + ++ +```c++ + +auto original_size = c.size(); +for (auto i = c.begin(), last = c.end(); i != last; ) { + if (pred(*i)) { + i = c.erase(i); + } else { + ++i; + } +} +return original_size - c.size(); + +``` -=== Serialization +=== 序列化 -``unordered_set``s can be archived/retrieved by means of link:../../../../../serialization/index.html[Boost.Serialization^] using the API provided by this library. Both regular and XML archives are supported. +`unordered++_++set` 可通过本库提供的 API,借助 link:../../../../../serialization/index.html[Boost.Serialization] 实现序列化存档与读取功能。同时支持常规格式与 XML 格式的归档。 -==== Saving an unordered_set to an archive +==== 将 unordered++_++set 保存到归档 -Saves all the elements of an `unordered_set` `x` to an archive (XML archive) `ar`. +将 `unordered++_++set` 对象 `x` 的所有元素保存到归档(XML 归档) `ar` 中。 [horizontal] -Requires:;; `value_type` is serializable (XML serializable), and it supports Boost.Serialization `save_construct_data`/`load_construct_data` protocol (automatically suported by https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[DefaultConstructible^] types). +要求;; `value++_++type` 必须可序列化(支持 XML 序列化),且需要支持 Boost.Serialization 的 `save++_++construct++_++data` / `load++_++construct++_++data` 协议(该协议自动支持满足 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[可默认构造] 要求的类型)。 --- -==== Loading an unordered_set from an archive +==== 从归档加载 unordered++_++set -Deletes all preexisting elements of an `unordered_set` `x` and inserts from an archive (XML archive) `ar` restored copies of the elements of the original `unordered_set` `other` saved to the storage read by `ar`. +删除 `unordered++_++set` 对象 `x` 的所有预先存在的元素,并从归档(XML 归档) `ar` 中读取原始 `unordered++_++set` 对象 `other` 先前保存至存储的元素副本并插入到 `x` 中。 [horizontal] -Requires:;; `value_type` is https://en.cppreference.com/w/cpp/named_req/MoveInsertable[MoveInsertable^]. `x.key_equal()` is functionally equivalent to `other.key_equal()`. Note:;; If the archive was saved using a release of Boost prior to Boost 1.84, the configuration macro `BOOST_UNORDERED_ENABLE_SERIALIZATION_COMPATIBILITY_V0` has to be globally defined for this operation to succeed; otherwise, an exception is thrown. +要求;; `value++_++type` 需满足 https://en.cppreference.com/w/cpp/named_req/MoveInsertable[可移动插入] 要求,且 `x.key++_++equal()` 在功能上需等价于 `other.key++_++equal()` 。 +注意;; 若归档文件是使用 Boost 1.84 之前的版本保存的,则必须全局定义配置宏 `BOOST++_++UNORDERED++_++ENABLE++_++SERIALIZATION++_++COMPATIBILITY++_++V0` 才能成功执行此操作;否则将抛出异常。 --- -==== Saving an iterator/const_iterator to an archive +==== 将迭代器/常量迭代器保存到归档 -Saves the positional information of an `iterator` (`const_iterator`) `it` to an archive (XML archive) `ar`. `it` can be and `end()` iterator. +将 `iterator` ( `const++_++iterator` )常量迭代器 `it` 的位置信息保存到归档(XML 归档) `ar` 中。 `it` 可以是 `end()` 迭代器。 [horizontal] -Requires:;; The `unordered_set` `x` pointed to by `it` has been previously saved to `ar`, and no modifying operations have been issued on `x` between saving of `x` and saving of `it`. +要求;; 迭代器 `it` 指向的 `unordered++_++set` `x` 必须已预先保存至归档 `ar` ,且在保存 `x` 和保存 `it` 的时间间隔内 `x` 执行任何修改操作。 --- -==== Loading an iterator/const_iterator from an archive +==== 从归档加载迭代器/常量迭代器 -Makes an `iterator` (`const_iterator`) `it` point to the restored position of the original `iterator` (`const_iterator`) saved to the storage read by an archive (XML archive) `ar`. +使 `iterator` ( `const++_++iterator` ) `it` 指向原始 `iterator` ( `const++_++iterator` )所恢复的位置。该原始迭代器已被保存到由归档(XML 归档) `ar` 读取的存储中。 [horizontal] -Requires:;; If `x` is the `unordered_set` `it` points to, no modifying operations have been issued on `x` between loading of `x` and loading of `it`. +要求;; 如果 `x` 是 `it` 指向的 `unordered++_++set` ,则在加载 `x` 与加载 `it` 的时间间隔内,不得对 `x` 执行任何修改操作。 diff --git a/doc/modules/ROOT/pages/regular_zh_Hans.adoc b/doc/modules/ROOT/pages/regular_zh_Hans.adoc index f17b37a..99445db 100644 --- a/doc/modules/ROOT/pages/regular_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/regular_zh_Hans.adoc @@ -1,13 +1,14 @@ -[#regular] = Regular Containers +[#regular] += 常规容器 :idprefix: regular_ -Boost.Unordered closed-addressing containers (`boost::unordered_set`, `boost::unordered_map`, `boost::unordered_multiset` and `boost::unordered_multimap`) are fully conformant with the C++ specification for unordered associative containers, so for those who know how to use `std::unordered_set`, `std::unordered_map`, etc., their homonyms in Boost.Unordered are drop-in replacements. The interface of open-addressing containers (`boost::unordered_node_set`, `boost::unordered_node_map`, `boost::unordered_flat_set` and `boost::unordered_flat_map`) is very similar, but they present some minor differences listed in the dedicated xref:compliance.adoc#compliance_open_addressing_containers[standard compliance section]. +Boost.Unordered 的闭寻址容器( `boost::unordered++_++set` 、 `boost::unordered++_++map` 、 `boost::unordered++_++multiset` 与 `boost::unordered++_++multimap` )完全符合 C{plus}{plus} 无序关联容器的标准规范。因此,对于熟悉 `std::unordered++_++set` 、 `std::unordered++_++map` 等用法的用户,可直接将其替换为Boost.Unordered 中的同名容器。开放寻址容器( `boost::unordered++_++node++_++set` 、 `boost::unordered++_++node++_++map` 、 `boost::unordered++_++flat++_++set` 和 `boost::unordered++_++flat++_++map` )的接口与之高度相似,但存在一些细微差异,详见专门的 xref:compliance.adoc#compliance_open_addressing_containers[标准符合性章节] 。 -For readers without previous experience with hash containers but familiar with normal associative containers (`std::set`, `std::map`, `std::multiset` and `std::multimap`), Boost.Unordered containers are used in a similar manner: +对于没有哈希容器经验但熟悉常规关联容器( `std::set` 、 `std::map` 、 `std::multiset` 和 `std::multimap` )的读者,Boost.Unordered 容器的使用方式与之类似: -[source,cpp] +[source, cpp] ---- typedef boost::unordered_map map; map x; @@ -19,16 +20,16 @@ assert(x.at("one") == 1); assert(x.find("missing") == x.end()); ---- -But since the elements aren't ordered, the output of: +但由于元素不按顺序存储,以下代码的输出结果: -[source,c++] +[source, c++] ---- for(const map::value_type& i: x) { std::cout<`, `>=` operators. -|Can be compared using the `==` and `!=` operators. +[caption=",", title='Table {counter:table-counter} Interface differences'] +[cols="1,1", frame=all,, grid=rows] +|=== +|关联容器 |无序关联容器 + +|通过排序关系 `Compare` 进行 参数化 +|通过函数对象 `Hash` 和等价关系 +`Pred` 进行参数化 + +|可通过成员函数 `key++_++comp()` 获取用于比较键的 +`key++_++compare` 类型对象,通过成员函数 `value++_++comp()` +获取用于比较值的 `value++_++compare` 类型对象。 +|可通过成员函数 +`hash++_++function()` 获取用于计算键哈希值的 `hasher` +函数,通过成员函数 `key++_++eq()` 获取用于判断键等价的 `key++_++equal` +函数。未提供用于比较或哈希整个键值对的函数。 + +|构造函数提供用于指定比较函数对象的可选参数。 +|构造函数提供可选参数,用于指定初始最小桶数量、哈希函数及相等性判断对象。 + +|当 `!Compare(k1, k2) && !Compare(k2, k1)` 为真(TRUE) 时,键 `k1` 与 `k2` +视为等价。 +|当 `Pred(k1, k2)` 返回 `TRUE` 时 ,键 `k1` 与 `k2` 视为等价 + +|成员函数 `lower++_++bound(k)` 和 `upper++_++bound(k)` +|无等效操作。由于元素非有序存储, `lower++_++bound` 和 `upper++_++bound` +无意义。 + +|当键 `k` 不存在于容器中时, `equal++_++range(k)` 返回 `k` +应插入位置的空范围。 +|当键 `k` 不存在于容器中时, `equal++_++range(k)` +返回的区间位于容器末尾。由于 `k` +可能被插入到多个位置,因此无法返回一个具有确定位置的区间。 + +*闭寻址容器:* 如需查找 `k` 将被插入的桶,可使用 `bucket(k)` +方法。但需注意,插入操作可能引发容器重哈希——这意味着元素最终可能被存入不同的桶中。 + +|`iterator` 与 `const++_++iterator` 属于双向迭代器类别。 +|`iterator` 与 `const++_++iterator` 至少属于前向迭代器类别。 + +|指向容器元素的迭代器、指针及引用永不失效。 +|xref:regular.adoc#regular_iterator_invalidation[插入或重哈希操作可能引发迭代器失效] 。 + +*基于节点的容器:* 元素的指针和引用永不失效。 + +*扁平容器:* 当发生重哈希时,元素的指针和引用将失效。 + +|迭代器按比较对象定义的顺序遍历容器。 +|迭代器以任意顺序遍历容器,该顺序可能随元素插入而改变,但等价元素始终相邻排列。 + +|无等效功能 +|*闭寻址容器:* +可通过局部迭代器遍历单个桶内的元素.(不要求局部迭代器与容器迭代器的遍历顺序存在任何关联.) + +|可通过 `==` 、 `!=` 、 `++<++` 、 `++<++=` 、 `++>++` 、 `++>++=` +运算符进行比较。 +|可通过 `==` 与 `!=` 运算符进行比较。 | -|When inserting with a hint, implementations are permitted to ignore the hint. +|使用提示符插入时,实现允许忽略提示信息。 |=== --- -[caption=, title='Table {counter:table-counter} Complexity Guarantees'] -[cols="1,1,1", frame=all, grid=rows] +[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. +|空容器的构造 +|常数时间 +|O(_n_),其中 _n_ 表示桶的最小数量。 -|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^_) +|构建包含 _N_ 个元素范围的容器 +|O(_N log N_),若该范围按 +`value++_++comp()` 排序则为 O(_N_) +|平均 O(_N_),最差 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). +|使用提示插入单个元素 +|若在提示后立即插入 `t` +个元素,则均摊常数时间,否为则对数时间 +|平均情况常数时间,最坏情况线性时间(与常规插入操作相同)。 -|Inserting a range of _N_ elements -|_N_ log(`size()` + _N_) -|Average case O(_N_), worst case O(_N_ * `size()`) +|插入包含 _N_ 个元素的范围 +|_N_ log(`size()` {plus} _N_) +|平均情况 +O(_N_),最坏情况 O(_N_ ++*++ `size()`) -|Erase by key, `k` -|O(log(`size()`) + `count(k)`) -|Average case: O(`count(k)`), Worst case: O(`size()`) +|按键 `k` 删除 +|O(log(`size()`) {plus} `count(k)`) +|平均情况:O(`count(k)`),最差情况:O(`size()`) -|Erase a single element by iterator -|Amortized constant -|Average case: O(1), Worst case: O(`size()`) +|通过迭代器删除单个元素 +|均摊常数时间 +|平均情况:O(1),最差情况:O(`size()`) -|Erase a range of _N_ elements -|O(log(`size()`) + _N_) -|Average case: O(_N_), Worst case: O(`size()`) +|删除包含 _N_ 个元素的范围 +|O(log(`size()`) {plus} _N_) +|平均情况:O(_N_),最差情况:O(`size()`) -|Clearing the container +|清空容器 |O(`size()`) |O(`size()`) -|Find -|logarithmic -|Average case: O(1), Worst case: O(`size()`) +|查找 +|对数时间 +|平均情况:O(1),最差情况:O(`size()`) -|Count -|O(log(`size()`) + `count(k)`) -|Average case: O(1), Worst case: O(`size()`) +|统计 +|O(log(`size()`) {plus} `count(k)`) +|平均情况:O(1),最差情况:O(`size()`) -|`equal_range(k)` -|logarithmic -|Average case: O(`count(k)`), Worst case: O(`size()`) +|`equal++_++range(k)` +|对数时间 +|平均情况:O(`count(k)`),最差情况:O(`size()`) -|`lower_bound`,`upper_bound` -|logarithmic -|n/a +|`lower++_++bound` 、 `upper++_++bound` +|对数时间 +|不适用 |=== diff --git a/doc/modules/ROOT/pages/structures_zh_Hans.adoc b/doc/modules/ROOT/pages/structures_zh_Hans.adoc index dba552d..15fd66e 100644 --- a/doc/modules/ROOT/pages/structures_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/structures_zh_Hans.adoc @@ -1,8 +1,9 @@ -[#structures] = Data Structures +[#structures] += 数据结构 :idprefix: structures_ -== Closed-addressing Containers +== 闭寻址容器 ++++ ++++ -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: +Boost.Unordered 提供了速度最快的闭寻址实现之一,该结构通常被称为 https://en.wikipedia.org/wiki/Hash_table#Separate_chaining[分离链接法] 。其数据结构示例如下: -[#img-bucket-groups,.text-center] -.A simple bucket group approach +[#img-bucket-groups, .text-center] +.基础桶组实现方案 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())`. +系统分配一个"桶"数组,其中每个桶分别指向其专属的链表。这种结构使得桶迭代能直接满足标准要求。但采用此布局进行整体容器迭代通常较慢,因为需检查每个桶的占用状态,其时间复杂度为 `O(bucket++_++count() {plus} size())` ,而标准要求复杂度应为 `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=_images/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]. +值得注意的是,此方案仅被libc{plus}{plus}和libstdc{plus}{plus}采用;MSVC Dinkumware实现则使用了不同方案。关于标准库容器的更详细分析可参阅 http://bannalia.blogspot.com/2013/10/implementation-of-c-unordered.html[此文] 。 -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 // ... } ``` +```c++ -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 // ... } ``` +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 + // ... +} -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: +``` + +若采用基础的桶组布局,则仅需执行以下操作: +```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 + // ... +} + +``` + +实际上,这种额外的间接访问会对常见操作(如 `insert` 、 `find` 和 `erase` )产生显著的性能影响。但为了保持容器迭代的高效性,Boost.Unordered 引入了一种新颖的数据结构——“桶组”。桶组是桶数组某个分区的定宽视图,它包含一个位掩码( `std::size++_++t` 类型)用于跟踪桶的占用状态,并包含两个指针以形成非空组之间的双向链表。其结构示例如下: [#img-fca-layout] -.The new layout used by Boost +.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. +过将容器全局迭代转换为遍历非空桶组(该操作具有常数时间复杂度),系统将整体时间复杂度恢复至 `O(size())` 。每个桶组仅占用 4 个机器字长的空间,其管理的桶数量为 `sizeof(std::size++_++t) ++*++ CHAR++_++BIT` ,这意味着在所有常见实现架构中,桶组为每个桶引入的空间开销仅为 4 比特。 -A more detailed description of Boost.Unordered's closed-addressing implementation is given in an https://bannalia.blogspot.com/2022/06/advancing-state-of-art-for.html[external article]. For more information on implementation rationale, read the xref:rationale.adoc#rationale_closed_addressing_containers[corresponding section]. +关于 Boost.Unordered 闭寻址实现的更详细说明请参阅 https://bannalia.blogspot.com/2022/06/advancing-state-of-art-for.html[外部文章] 。 若需了解实现原理的更多信息,请参阅 xref:rationale.adoc#rationale_closed_addressing_containers[相关说明章节] 。 -== Open-addressing Containers +== 开放寻址容器 -The diagram shows the basic internal layout of `boost::unordered_flat_set`/`unordered_node_set` and `boost:unordered_flat_map`/`unordered_node_map`. +下图展示 `boost::unordered++_++flat++_++set` / `unordered++_++node++_++set` 及 `boost:unordered++_++flat++_++map` / `unordered++_++node++_++map` 的基础内部布局. [#img-foa-layout] -.Open-addressing layout used by Boost.Unordered. +.Boost.Unordered采用的开放寻址布局结构. image::foa.png[align=center] -As with all open-addressing containers, elements (or pointers to the element nodes in the case of `boost::unordered_node_set` and `boost::unordered_node_map`) are stored directly in the bucket array. This array is logically divided into 2^_n_^ _groups_ of 15 elements each. In addition to the bucket array, there is an associated _metadata array_ with 2^_n_^ 16-byte words. +与所有开放寻址容器一样,元素(对于 `boost::unordered++_++node++_++set` 和 `boost::unordered++_++node++_++map`则是元素节点的指针)直接存储在桶数组中。 该数组在逻辑上被划分为 2^_n_^个组,每组包含 15个元素。 除桶数组外,还存在一个关联的__元数据数组__,其中包含 2^_n_^ 个 16 字节的字。 [#img-foa-metadata] -.Breakdown of a metadata word. +.元数据字结构解析。 image::foa-metadata.png[align=center] -A metadata word is divided into 15 _h_~_i_~ bytes (one for each associated bucket), and an _overflow byte_ (_ofw_ in the diagram). The value of _h_~_i_~ is: +每个元数据字被划分为 15 个 _h_~_i_~ 字节(每个对应一个关联的桶)和一个__溢出字节__(图示中的_ofw_)。_h_~_i_~ 的取值为: -- 0 if the corresponding bucket is empty. - 1 to encode a special empty bucket called a _sentinel_, which is used internally to stop iteration when the container has been fully traversed. - If the bucket is occupied, a _reduced hash value_ obtained from the hash value of the element. + - 0 表示对应桶为空. + - 1 用于表示一种特殊的空桶(称为__哨兵桶__),该机制在容器完全遍历时内部用于终止迭代 + 停止迭代当容器已被完全遍历。 + - 若桶已被占用,则存储从元素哈希值推导出的__缩减哈希值__。 + 该元素。 -When looking for an element with hash value _h_, SIMD technologies such as https://en.wikipedia.org/wiki/SSE2[SSE2] and https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(Neon)[Neon] allow us to very quickly inspect the full metadata word and look for the reduced value of _h_ among all the 15 buckets with just a handful of CPU instructions: non-matching buckets can be readily discarded, and those whose reduced hash value matches need be inspected via full comparison with the corresponding element. If the looked-for element is not present, the overflow byte is inspected: +当用哈希值__h__查找元素时, https://en.wikipedia.org/wiki/SSE2[SSE2] 和 https://en.wikipedia.org/wiki/ARM_architecture_family#Advanced_SIMD_(Neon)[Neon] 等 SIMD技术能以少量CPU指令快速扫描整个元数据字: 不匹配桶立即排除, 缩减哈希值匹配的桶需与对应元素进行完整比对。 若未找到目标元素, 则检查溢出字节: -- If the bit in the position _h_ mod 8 is zero, lookup terminates (and the element is not present). - If the bit is set to 1 (the group has been _overflowed_), further groups are checked using https://en.wikipedia.org/wiki/Quadratic_probing[_quadratic probing_], and the process is repeated. +- 若位置 _h_ mod 8 的比特位为零,则查找终止(确认元素不存在)。 元素不存在)。 +- 若该比特位为1(表示该组已__溢出__),则通过 https://en.wikipedia.org/wiki/Quadratic_probing[_二次探查法_] 检查后续组,并重复此过程。 -Insertion is algorithmically similar: empty buckets are located using SIMD, and when going past a full group its corresponding overflow bit is set to 1. +插入操作的算法逻辑类似:通过 SIMD 技术定位空桶,当遍历到已满的组时,会将其对应的溢出位设置为 1。 -In architectures without SIMD support, the logical layout stays the same, but the metadata word is codified using a technique we call _bit interleaving_: this layout allows us to emulate SIMD with reasonably good performance using only standard arithmetic and logical operations. +在不支持 SIMD 的体系架构中, 逻辑布局不变,但采用__位交织__技术编码元数据字: 仅用标准算术和逻辑运算即可模拟接近SIMD的性能. [#img-foa-metadata-interleaving] -.Bit-interleaved metadata word. +.位交织元数据字结构. image::foa-metadata-interleaving.png[align=center] -A more detailed description of Boost.Unordered's open-addressing implementation is given in an https://bannalia.blogspot.com/2022/11/inside-boostunorderedflatmap.html[external article]. For more information on implementation rationale, read the xref:rationale.adoc#rationale_open_addresing_containers[corresponding section]. +关于 Boost.Unordered 开放寻址实现的更详细说明请参阅 https://bannalia.blogspot.com/2022/11/inside-boostunorderedflatmap.html[外部文章] 。 若需了解实现原理的更多信息,请参阅 xref:rationale.adoc#rationale_open_addresing_containers[相关说明章节] 。 -== Concurrent Containers +== 并发容器 -`boost::concurrent_flat_set`/`boost::concurrent_node_set` and `boost::concurrent_flat_map`/`boost::concurrent_node_map` use the basic xref:structures.adoc#structures_open_addressing_containers[open-addressing layout] described above augmented with synchronization mechanisms. +`boost::concurrent++_++flat++_++set` / `boost::concurrent++_++node++_++set` 和 `boost::concurrent++_++flat++_++map` / `boost::concurrent++_++node++_++map` 采用前述 xref:structures.adoc#structures_open_addressing_containers[开放寻址布局] , 并在此基础上增加了同步机制。 [#img-cfoa-layout] -.Concurrent open-addressing layout used by Boost.Unordered. +.Boost.Unordered采用的并发开放寻址布局结构. image::cfoa.png[align=center] -Two levels of synchronization are used: +采用两级同步机制: -* Container level: A read-write mutex is used to control access from any operation -to the container. Typically, such access is in read mode (that is, concurrent) even for modifying operations, so for most practical purposes there is no thread contention at this level. Access is only in write mode (blocking) when rehashing or performing container-wide operations such as swapping or assignment. -* Group level: Each 15-slot group is equipped with an 8-byte word containing: -By using atomic operations to access the group metadata, lookup is (group-level) lock-free up to the point where an actual comparison needs to be done with an element that has been previously SIMD-matched: only then is the group's spinlock used. +* 容器级:读写互斥锁控制所有操作访问。 通常情况下,即使是修改操作也采用读模式访问(即可并发执行), 因此在大多数实际应用场景中,该层级不会出现线程争用。 仅当执行重哈希或容器级操作(如交换或赋值)时, 才会采用写模式访问(即阻塞式)。 +* 组级:每个包含15个槽位的组都配备一个8字节的字,其中包含: + ** 一个用于同步访问组内任意元素的读写自旋锁. + ** 用于乐观插入的原子__插入计数器__ + (如下所述). -Insertion uses the following _optimistic algorithm_: +通过原子操作访问组元数据, 查找在(组级别上)无锁状态下进行, 直至需对先前经SIMD匹配的元素进行实际比较时,才使用组自旋锁. -sequence is locally recorded (let's call this value `c0`). +插入操作采用如下__乐观算法__: -* A read-write spinlock for synchronized access to any element in the group. ** An atomic _insertion counter_ used for optimistic insertion as described below. -search for an available slot for insertion successively locks/unlocks each group in the probing sequence. -* The value of the insertion counter for the initial group in the probe -reduced hash value is set) and the insertion counter is atomically incremented: if no other thread has incremented the counter during the whole operation (which is checked by comparing with `c0`), then we're good to go and complete the insertion, otherwise we roll back and start over. -* Lookup is as described above. If lookup finds no equivalent element, -This algorithm has very low contention both at the lookup and actual insertion phases in exchange for the possibility that computations have to be started over if some other thread interferes in the process by performing a succesful insertion beginning at the same group. In practice, the start-over frequency is extremely small, measured in the range of parts per million for some of our benchmarks. +* 在探查序列的初始组中, 插入计数器的值会被本地记录(我们称此值为 `c0` )。 +* 查找操作按上述方式执行。 若查找未发现相等元素, 则会在探查序列中依次锁定/解锁各个分组来搜索可用插槽。 +* 当定位到可用插槽时, 会抢先占用该插槽(设置其缩减哈希值)并原子地递增插入计数器: 若在整个操作期间没有其他线程递增过该计数器 (通过与 `c0` 比对确认), 则操作成功并完成插入; 否则回滚并重新开始。 -For more information on implementation rationale, read the xref:rationale.adoc#rationale_concurrent_containers[corresponding section]. +该算法在查找和实际插入阶段都具有极低的争用, 其代价是:当其他线程从同一初始组开始执行插入操作并成功时, 当前线程的计算可能需要重新执行。 实际应用中, 重启频率极低( 部分基准测试中为百万分之一量级). -For more information on implementation rationale, read the xref:rationale.adoc#rationale_concurrent_containers[corresponding section]. +如需了解有关实现原理的更多信息,请阅读 xref:rationale.adoc#rationale_concurrent_containers[相关说明章节] 。