From ca9d068cbec8586a3c2c3ca29d1a164c4e84087b Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:36 +0000 Subject: [PATCH 001/111] 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 ecbfbc6d1d480e56f3a56039a8226aab3840fcc0 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:37 +0000 Subject: [PATCH 002/111] 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 92cd9accb54189515645ccadc2f54f5f79b8af9d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:38 +0000 Subject: [PATCH 003/111] 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 f4de75eb04faffeb1ae925924752b27c6844488f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:38 +0000 Subject: [PATCH 004/111] 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 a0b92ee8e39caf501857c51b315ba5ce5133a2a8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:39 +0000 Subject: [PATCH 005/111] 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 cc08e1e5656af2d9686de9ce8c333bbfe98e3f09 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:41 +0000 Subject: [PATCH 006/111] 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 65dde68207ebcfbb969399b94093106cf856f529 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:42 +0000 Subject: [PATCH 007/111] 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 4ac4ecfe3e7aba314023a742f2cec4526f4a1b97 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:42 +0000 Subject: [PATCH 008/111] 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 e5363cfb9964d796399c95fee10794d6bfff2a73 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:43 +0000 Subject: [PATCH 009/111] 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 eba22b0df4cb88ff6015c16db914f68dc74b9d89 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:43 +0000 Subject: [PATCH 010/111] 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 3f14be126e49180e3fa9d1b890ef2d2850df0108 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:44 +0000 Subject: [PATCH 011/111] 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 b16fb13f03a6d4fc209b68bae31bff170a444d46 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:45 +0000 Subject: [PATCH 012/111] 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 b4d472972608b93f986b6e73019c0f6ee2cd6e3c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:45 +0000 Subject: [PATCH 013/111] 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 44df37b84d16199648779a605ee47156d32fb564 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:46 +0000 Subject: [PATCH 014/111] 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 58479045b4c474607fe397b2db824a9882c63f3e Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:46 +0000 Subject: [PATCH 015/111] 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 8966957ba8a3361e36bf622de5d67848950fddf4 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:49 +0000 Subject: [PATCH 016/111] 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 53844164fb497bc2dfe2deb8a76f3094e53daa1d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:50 +0000 Subject: [PATCH 017/111] 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 c9a52a60f03382601a13f9f4c6bcc09c829f9c05 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:50 +0000 Subject: [PATCH 018/111] 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 2d8af9a2e6021638628b8e527c3f502f8dbb3c55 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:51 +0000 Subject: [PATCH 019/111] 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 2bfdf50187468fef02ebad53839870f750729865 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:56 +0000 Subject: [PATCH 020/111] 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 afc4e60067dc1da93d115ff1abe77ec9f4c66a8c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:56 +0000 Subject: [PATCH 021/111] 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 2caa97df27015306681de3dadc40ea1f78850669 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:40:57 +0000 Subject: [PATCH 022/111] 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 cd0adb3b4488372a7ec0c87f0cd29bb8d1ce66b1 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:01 +0000 Subject: [PATCH 023/111] 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 50da1bb3df3ecbfae21367b719460e8be48395ba Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:05 +0000 Subject: [PATCH 024/111] 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 9aa514e17a3633774dbcf3bc6e999c1129a88db5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:05 +0000 Subject: [PATCH 025/111] 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 1e5ea5921fc7292bb106f506bd431eb090ad0169 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:06 +0000 Subject: [PATCH 026/111] 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 8eaac56f702f3ca8fd93217e14406f31f140e941 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:06 +0000 Subject: [PATCH 027/111] 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 aff5c3f09807f8c7f55a078f88c64d2cfd3bf658 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:06 +0000 Subject: [PATCH 028/111] 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 11f6ec7986e13178ef0c6a2286b9dc45cf1e831f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:07 +0000 Subject: [PATCH 029/111] 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 5a31f354f5426d056988b331695f8125703b9a6c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:12 +0000 Subject: [PATCH 030/111] 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 b44dd4359392d577556ec9f0bf81486a35907e87 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:12 +0000 Subject: [PATCH 031/111] 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 8007a75b04b20417a8ca7b0416e1b63106eaa7df Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:17 +0000 Subject: [PATCH 032/111] 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 b444d01d066c291848388209df3714e69edea0d1 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:17 +0000 Subject: [PATCH 033/111] 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 14905147d0da0da5062f48afc82cf4a67c74b375 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:21 +0000 Subject: [PATCH 034/111] 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 1f84ae0c9f4494863d7d6f4a2922693acd112805 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:22 +0000 Subject: [PATCH 035/111] 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 dfde4d3784de9ecd61565b4961f289065c9f5260 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:26 +0000 Subject: [PATCH 036/111] 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 5df388495e2091ecd53ff04713207be3b117468a Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:26 +0000 Subject: [PATCH 037/111] 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 7069aff1117721b622fe751561f25c31475f480f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:27 +0000 Subject: [PATCH 038/111] 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 f4596e09dd303dbd55a98b6d8bb1e5f6497007d5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:27 +0000 Subject: [PATCH 039/111] 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 c19e5b71919b30e0c3b59f10c2031fdadb3b706f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:28 +0000 Subject: [PATCH 040/111] 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 fbe23fb231645236de21d4fdea7203f55f0b5a97 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:28 +0000 Subject: [PATCH 041/111] 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 e381bf0b62748bd0a33064aa2c9275a796dc65f8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:33 +0000 Subject: [PATCH 042/111] 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 a9ca49b95a2a977d85227cae86bab2f40e0b3e0f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:39 +0000 Subject: [PATCH 043/111] 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 396bab19d383387368faf3bda9e1bbbc5b5634d5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:39 +0000 Subject: [PATCH 044/111] 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 f09907c0b7397a0c7c3bf5bb2e4ba4fa5ee5e88f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:43 +0000 Subject: [PATCH 045/111] 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 110ff67318ecfd1f35ecf3799025f2ec424cc388 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:47 +0000 Subject: [PATCH 046/111] 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 08f85d4daf4f58e5d34814f3f10b95b6d39036bd Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:48 +0000 Subject: [PATCH 047/111] 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 5492450ae0c50cad53b2e375da7e9261a7bd402f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:52 +0000 Subject: [PATCH 048/111] 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 4b4b33e926541308ecf889906086756345256102 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:52 +0000 Subject: [PATCH 049/111] 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 c91a40a2e1118a74c36901ea93d1f7237a536d86 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:52 +0000 Subject: [PATCH 050/111] 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 9a155f083f7f38b4a7d70cbcd40d4c896cd7ea2d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:53 +0000 Subject: [PATCH 051/111] 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 d3b8b620ac050e2a2e0a832dd3c9310bda3fb1f5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:41:53 +0000 Subject: [PATCH 052/111] 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 fe4be9d87cffa61452dbf7f903974e547bef441a Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:44:12 +0000 Subject: [PATCH 053/111] 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://insights.cppalliance.org/weblate/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 6bb418c19f250fb8fcd1b49337f1ce27eb6b1ea3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:44:16 +0000 Subject: [PATCH 054/111] 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://insights.cppalliance.org/weblate/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 2d69ecf44fba8a6e56d4b92d424ddad2a4c0509e Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:44:32 +0000 Subject: [PATCH 055/111] 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://insights.cppalliance.org/weblate/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 a8c360afcb3d5877f022baea1e249ed5f0f64cd8 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:45:03 +0000 Subject: [PATCH 056/111] 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://insights.cppalliance.org/weblate/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 6b8948fa9016de59a742f3406fef7a55c652680f Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:45:12 +0000 Subject: [PATCH 057/111] 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://insights.cppalliance.org/weblate/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 1a70e97ac60d17e871953217eeb0791e2ec183e6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:45:22 +0000 Subject: [PATCH 058/111] 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://insights.cppalliance.org/weblate/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 b408603886274831ec69c3f48cd925e1ce2b563f Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 5 Jun 2026 18:45:37 +0000 Subject: [PATCH 059/111] 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://insights.cppalliance.org/weblate/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 01f47a38accc12253fb2f434335025d2afa61eb9 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:51:22 +0000 Subject: [PATCH 060/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (372 of 372 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Flat Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-flat-set-adoc/zh_Hans/ --- .../reference/unordered_flat_set_zh_Hans.adoc | 549 ++++++++++-------- 1 file changed, 300 insertions(+), 249 deletions(-) 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..90e4ced 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,19 +1,23 @@ [#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()` 不是常数时间操作。 +- 没有用于桶操作的 API(除了 `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"] ----- @@ -224,16 +228,16 @@ namespace unordered { --- -=== 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. +并且可以从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[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`. @@ -243,38 +247,38 @@ and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the con |_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[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_avalanching[hash_is_avalanching]::value` 为 `true`,则哈希函数将按原样使用;否则,将添加一个比特混合后处理阶段,以增加哈希质量,但会增加额外的计算成本。 --- -=== 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. +全局定义此宏以启用容器的 xref:reference/stats.adoc#stats[统计信息计算]。请注意,此选项会降低许多操作的整体性能。 --- -=== Typedefs +=== 类型定义 [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`。 --- @@ -283,33 +287,35 @@ Convertible to `const_iterator`. 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(); ``` -Constructs an empty container 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[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[DefaultConstructible^]。 --- -==== Iterator Range Constructor +==== 迭代器范围构造函数 [source,c++,subs="+quotes"] ---- template @@ -320,75 +326,76 @@ 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[DefaultConstructible^]。 --- -==== Copy Constructor -```c++ unordered_flat_set(unordered_flat_set const& other); ``` +==== 复制构造函数 +```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. +如果 `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[enabled]),则从 `other` 转移内部统计信息,并调用 `other.reset_stats()`。 --- -==== Iterator Range Constructor with Allocator -```c++ template unordered_flat_set(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器区间构造函数 +```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. +构造一个以 `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[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[enabled]),则仅当 `a == other.get_allocator()` 时才从 `other` 转移内部统计信息,并且总是调用 `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`] 进行移动构造。`other` 的内部桶数组将直接转移给新容器。哈希函数、谓词和分配器从 `other` 进行移动构造。如果启用了统计信息(xref:unordered_flat_set_boost_unordered_enable_stats[enabled]),则从 `other` 转移内部统计信息,并调用 `other.reset_stats()`。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度:;; 常数时间。 +并发性:;; 在 `other` 上阻塞。 --- -==== Initializer List Constructor +==== 初始化列表构造函数 [source,c++,subs="+quotes"] ---- unordered_flat_set(std::initializer_list il, @@ -398,48 +405,50 @@ 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[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[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[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. +构造一个至少包含 `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[DefaultConstructible^]。 --- -==== Iterator Range Constructor with Bucket Count and Hasher +==== 带桶数和哈希函数的迭代器范围构造函数 [source,c++,subs="+quotes"] ---- template @@ -447,88 +456,92 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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[DefaultConstructible^]。 --- -==== initializer_list Constructor with Allocator +==== 带分配器的初始化列表构造函数 -```c++ unordered_flat_set(std::initializer_list il, const allocator_type& a); ``` +```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. +使用 `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[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[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); ``` +```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. +构造一个至少包含 `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[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); ``` +```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`. +赋值运算符。销毁先前存在的元素,从 `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[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` 元素的移动构造副本。如果启用了统计信息(xref:unordered_flat_set_boost_unordered_enable_stats[enabled]),则仅当最终的分配器等于 `other.get_allocator()` 时才从 `other` 转移内部统计信息,并且总是调用 `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[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()`) +返回:;; 指向容器第一个元素的迭代器,若容器为空,则返回容器的尾后迭代器。 +复杂度:;; O(`bucket_count()`) --- @@ -536,7 +549,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:;; 指向容器尾后值的迭代器。 --- @@ -544,7 +557,8 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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()`) +返回:;; 指向容器第一个元素的常量迭代器,若容器为空,则返回容器的尾后常量迭代器。 +复杂度:;; O(`bucket_count()`) --- @@ -552,27 +566,27 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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() == 0` --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回:;; `std::distance(begin(), end())` --- @@ -581,119 +595,156 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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. + +要求:;; `value_type` 可以从 `args` 构造。 +返回:;; 如果进行了插入,则返回类型的 `bool` 分量为 `true`。 +如果进行了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:;; 如果除调用 `hasher` 之外的操作抛出异常,则该函数无效。 +备注:;; 可能会使迭代器、指针和引用失效,但仅当插入导致负载因子大于最大负载因子时才会发生。 --- ==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +```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++ 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, 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[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[MoveInsertable^]。 +返回:;; 如果进行了插入,则返回类型的 `bool` 分量为 `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)` 构造的元素。 [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[EmplaceConstructible^]。 +返回:;; 如果进行了插入,则返回类型的 bool 分量为 true。 +如果进行了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:;; 如果除调用 `hasher` 之外的操作抛出异常,则该函数无效。 +备注:;; 可能会使迭代器、指针和引用失效,但仅当插入导致负载大于最大负载时才会发生。 +此外,仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,并且 `K` 不能隐式转换为 `iterator` 或 `const_iterator` 时,此重载才会参与重载决议。库假定 `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[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, 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[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)` 构造的元素。 -`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[EmplaceConstructible^]。 +返回:;; 如果进行了插入,则返回类型的 bool 分量为 true。 +如果进行了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:;; 如果除调用 `hasher` 之外的操作抛出异常,则该函数无效。 +备注:;; 可能会使迭代器、指针和引用失效,但仅当插入导致负载大于最大负载时才会发生。 +此外,仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,并且 `K` 不能隐式转换为 `iterator` 或 `const_iterator` 时,此重载才会参与重载决议。库假定 `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 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[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[CopyInsertable^] 到容器中。抛出:;; 当插入单个元素时,如果除调用 `hasher` 之外的操作抛出异常,则该函数无效。备注:;; 可能会使迭代器、指针和引用失效,但仅当插入导致负载大于最大负载时才会发生。 --- -==== Erase by Position +==== 通过位置擦除 [source,c++,subs=+quotes] ---- @@ -701,85 +752,85 @@ _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` 抛出异常时才会抛出异常。备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,并且 `K` 不能隐式转换为 `iterator` 或 `const_iterator` 时,才会参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 类型调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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++ 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. +如果 `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); ``` -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; ``` -Erases all elements in the container. +清除容器中的所有元素。 [horizontal] -Postconditions:;; `size() == 0`, `max_load() >= max_load_factor() * bucket_count()` +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); ``` +==== 合并 +```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; ``` [horizontal] -Returns:;; The container's allocator. +返回:;; 容器的分配器。 --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:;; 容器的哈希函数。 --- @@ -787,128 +838,128 @@ Returns:;; The container's hash function. ``` 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()`。备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时才会参与重载决议。库假定 `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` 等价的元素个数。备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时才会参与重载决议。库假定 `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` 的元素。备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时才会参与重载决议。库假定 `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; ``` +```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())`。备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时才会参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 类型调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型的开销。 --- -=== 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`. +返回:;; `static_cast(size())/static_cast(bucket_count())`,如果 `bucket_count() == 0` 则返回 `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`. +效果:;; 不执行任何操作,因为用户不允许更改此参数。为与 `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. +返回:;; 假设不再删除更多元素,容器在不进行重哈希的情况下所能容纳的最大元素数量。注意:;; 在构造、重哈希或清空之后,容器的最大负载至少为 `max_load_factor() * bucket_count()`。在高负载条件下,该值可能因删除操作而减小。 --- -==== 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. +必要时改变桶数组的大小,使得至少包含 `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)` 将释放底层桶数组的内存。如果所提供的分配器使用 fancy pointers,随后将执行一次默认分配。 -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()))`. +等价于 `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, 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]. +返回:;; 对容器迄今为止所执行的插入和查找操作的统计描述。备注:;; 仅在 xref:reference/stats.adoc#stats[统计信息计算] 已 xref:unordered_flat_set_boost_unordered_enable_stats[启用] 时可用。 --- @@ -916,18 +967,18 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -935,80 +986,80 @@ template 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); ``` +```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); ``` +```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). +如果 `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); ``` +```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`. +遍历容器 `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[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` 中插入由 `ar` 所读取存储中保存的原始 `unordered_flat_set` `other` 元素的恢复副本。 [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` 指向保存到由归档(XML 归档)`ar` 读取的存储中的原始 `iterator`(`const_iterator`)的被恢复位置。 [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` 执行任何修改操作。 From f71b6740a6e5e6f24dda068c17ef5f8ff0eaa49d Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:00 +0000 Subject: [PATCH 061/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Flat Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-flat-set-adoc/zh_Hans/ --- .../pages/reference/header_unordered_flat_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..30d0f91 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,9 +1,9 @@ [#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"] ----- From 0e3c4d67e595299f685e6fd091b3da817ff3e098 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:20 +0000 Subject: [PATCH 062/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (36 of 36 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Concurrent (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-concurrent-adoc/zh_Hans/ --- .../ROOT/pages/concurrent_zh_Hans.adoc | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc index 4e2a132..e77b0bb 100644 --- a/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/concurrent_zh_Hans.adoc @@ -1,8 +1,8 @@ -[#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. +Boost.Unordered 提供 `boost::concurrent_node_set` 、 `boost::concurrent_node_map` 、 `boost::concurrent_flat_set` 和 `boost::concurrent_flat_map` ,这些哈希表允许不同线程进行并发读写访问,无需用户实现任何同步机制。 [source,c++] ---- @@ -29,11 +29,11 @@ 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++] ---- @@ -43,7 +43,7 @@ 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++] ---- @@ -52,9 +52,9 @@ m.visit(k, [](const auto& x) { // x is the element with key k (if it exists) }); ---- -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++] ---- @@ -63,7 +63,7 @@ m.visit(k, [&](const auto& x) { }); ---- -Access to a different container is allowed, though: +但允许访问其他容器: [source,c++] ---- @@ -74,7 +74,7 @@ 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++] ---- @@ -87,7 +87,7 @@ if (found) { } ---- -Visitation is prominent in the API provided by concurrent containers, and many classical operations have visitation-enabled variations: +访问机制在并发容器 API 中占据核心地位,许多经典操作都提供了支持访问机制的变体: [source,c++] ---- @@ -98,9 +98,9 @@ m.insert_or_visit(x, [](auto& y) { }); ---- -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++] ---- @@ -113,11 +113,11 @@ 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++] ---- @@ -126,7 +126,7 @@ m.visit_all([](auto& x) { }); ---- -In C++17 compilers implementing standard parallel algorithms, whole-table visitation can be parallelized: +在支持标准并行算法的 C{plus}{plus}17 编译器中,全表遍历访问可进行并行化处理: [source,c++] ---- @@ -135,7 +135,7 @@ m.visit_all(std::execution::par, [](auto& x) { // run in parallel }); ---- -Traversal can be interrupted midway: +遍历过程可中途中断: [source,c++] ---- @@ -156,7 +156,7 @@ bool found = !m.visit_while([&](const auto& x) { if(found) { ... } ---- -There is one last whole-table visitation operation, `erase_if`: +最后一项全表访问操作是 `erase++_++if` : [source,c++] ---- @@ -165,11 +165,11 @@ m.erase_if([](auto& x) { }); ---- -`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++] ---- @@ -180,14 +180,14 @@ for(const auto& key: keys) { } ---- -_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: +提供此功能并非仅出于语法便利性考量:通过一次性处理所有键,可应用内部优化提升性能(详见 xref:benchmarks.adoc#benchmarks_boostconcurrent_flatnode_map[基准测试])。实际上,用户可通过缓冲输入键值以实现分块批量访问,从而进一步提升效率: [source,c++] ---- @@ -207,17 +207,17 @@ while(...) { // processing loop 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] @@ -228,11 +228,11 @@ As open-addressing and concurrent containers are based on the same internal data ^|`boost::concurrent_flat_set` ^|`boost::unordered_flat_set` -^|`boost::concurrent_flat_map` ^|`boost::unordered_flat_map` +^|`boost::concurrent_flat_set` ^|`boost::unordered_flat_set` |=== -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++] ---- From 321e92ef4e23ef07100a90efdbddd86a6384a7b2 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:23 +0000 Subject: [PATCH 063/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (32 of 32 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Debuggability (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-debuggability-adoc/zh_Hans/ --- .../ROOT/pages/debuggability_zh_Hans.adoc | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc index e02366a..4ab6146 100644 --- a/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/debuggability_zh_Hans.adoc @@ -1,64 +1,64 @@ [#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::unordered++_++map` 、示例 `boost::unordered++_++set` 及其迭代器. -```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 } ``` +```plaintext -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. +(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 } -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. +其余容器的显示逻辑完全一致,仅在显示容器本身时将其模板名称替换为对应的 "boost::unordered++_{++map++|++set}"。需要注意的事,每个子元素(即键、映射值或值)的显示均取决于其自身的打印设置,这可能包含其专属的美化打印器。 -```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}}} ``` +无论采用 SIMD 还是非 SIMD 实现,均可通过 GDB 美化打印器查看。 -=== 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]. +当用户在分配器中使用花式指针(例如 `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] 的末尾注释。 From f9755ac024f2ade0bb3f9f31cf773ba90d241dd1 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:15 +0000 Subject: [PATCH 064/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (17 of 17 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Stats (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-stats-adoc/zh_Hans/ --- .../ROOT/pages/reference/stats_zh_Hans.adoc | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc index 5079ace..15d9ba4 100644 --- a/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/stats_zh_Hans.adoc @@ -1,11 +1,11 @@ [#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"] ----- @@ -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[_雪崩效应_] 。 --- From 28896525c8c5a815cbe7c17d65f57abb96c5caa0 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:45 +0000 Subject: [PATCH 065/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (471 of 471 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Node Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-node-set-adoc/zh_Hans/ --- .../concurrent_node_set_zh_Hans.adoc | 758 ++++++++++-------- 1 file changed, 418 insertions(+), 340 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 a58cb07..c4c6f61 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,15 +1,15 @@ -[#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"] ----- @@ -286,16 +286,16 @@ namespace unordered { --- -=== 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. +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`. @@ -305,71 +305,71 @@ and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the con |_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::pointer` 与 `std::allocator_traits::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]::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] ---- 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] 。 --- @@ -378,7 +378,7 @@ A class for holding extracted table elements, modelling https://en.cppreference. typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -390,39 +390,41 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `NodeType` = `node_type`. +其中 `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. +xref:concurrent_node_set_bulk_visit[批量遍历]操作内部使用的块大小。 -=== 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. +构造一个空表,使用 `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[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++ 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. +构造一个包含至少 `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[DefaultConstructible^]。 --- -==== Iterator Range Constructor +==== 迭代器范围构造函数 [source,c++,subs="+quotes"] ---- template @@ -433,84 +435,87 @@ 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` 移动构造而来。若启用了统计功能,会从 `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[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` 复制构造。 +若启用了统计功能:仅当 `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++ 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()`. +从xref:#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"] ---- concurrent_node_set(std::initializer_list il, @@ -520,48 +525,50 @@ 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[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[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. +构造一个至少包含 `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[DefaultConstructible^]。 --- -==== Iterator Range Constructor with Bucket Count and Hasher +==== 带桶数和哈希函数的迭代器范围构造函数 [source,c++,subs="+quotes"] ---- template @@ -569,176 +576,188 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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[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. +构造一个至少包含 `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[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++ 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. +构造一个至少包含 `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_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); ``` +```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`. +赋值运算符。销毁先前存在的元素,从`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[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转移内部统计信息,且始终调用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[CopyInsertable^] +并发:;; 阻塞于 `*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; ``` +```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` 重载版本才会参与重载决议。库假定 `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. +尽管功能上等同于对每个键单独调用 `[c]visit`,但批量访问因内部优化通常性能更高。建议 `std::distance(first,last)` 至少达到 `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` 是传统前向迭代器(C++11 至 C++17),或满足 `std::forward_iterator` 概念(C++20 及更高版本)。对于 `K = std::iterator_traits::value_type`,要么 `K` 是 `key_type`,要么 `Hash::is_transparent` 和 `Pred::is_transparent` 是合法的成员别名。在后一种情况下,库假定 `Hash` 可同时接收 `K` 与 `Key` 类型调用,且 `Pred` 是透明的。这支持异构查找,避免了实例化 `Key` 类型对象的开销。返回值:;; 被访问的元素数量。 --- ==== [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++ 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++17 并行算法的编译器中可用。 +仅当`std::is_execution_policy_v>` 为 `true` 时,这些重载版本才参与重载决议。 +不允许使用无顺序执行策略。 --- ==== [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 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++17 并行算法的编译器中可用。 +仅当 `std::is_execution_policy_v>` 为 `true` 时,这些重载版本才参与重载决议。 +不允许使用无顺序执行策略。 +并行化意味着执行流程不会在 `f` 返回 `false` 时立即终止,因此 `f` 可能会继续被后续元素调用,且这些调用的返回值同样可能为 `false`。 --- -=== Size and Capacity +=== 大小与容量 -==== empty +==== 空 ```c++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回值:;; `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. +注意:;; 当存在并发插入操作时,返回的值可能无法精确反映函数执行后哈希表的真实大小。 --- @@ -747,359 +766,407 @@ Notes:;; In the presence of concurrent insertion operations, the value returned ```c++ size_type max_size() const noexcept; ``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回值:;; 哈希表支持的最大元素数量。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template bool emplace(Args&&... args); ``` +==== 原地构造 +```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`. +要求:;; `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` 支持拷贝插入。 +返回值:;; 若成功插入元素则返回 `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` 支持移动插入。 +返回值:;; 若成功插入元素则返回 `true`。 +并发特性:;; 会阻塞当前对象 `*this` 的扩容重哈希操作。 --- -==== Transparent Insert -```c++ template bool insert(K&& k); ``` +==== 透明插入 +```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. +当且仅当容器中不存在键等价的元素时,才使用 `std::forward(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` 原位构造。 +返回值:;; 若成功插入元素则返回 `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` 的原值。 +若 `nh` 非空,则当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素。函数返回时 `nh` 为空。 --- ==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +```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++ 不允许在可变参数包之后声明参数 `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`. +要求:;; `value_type` 支持拷贝插入。 +返回值:;; 若成功插入元素则返回 `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` 支持移动插入。 +返回值:;; 若成功插入元素则返回 `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)` 构造元素并插入容器;否则,以该等价元素的常量引用为参数调用函数 `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` 原位构造。 +返回值:;; 若成功插入元素则返回 `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` 的原值。 +若 `nh` 为空,则不执行任何操作;否则,当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素;否则,使用指向等效元素的常量引用调用 `f` 。 --- ==== 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); ``` +```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`。 +并发特性:;; 会阻塞当前对象的重哈希操作。 +注意:;; 该接口仅为说明性用法,因为 C++ 不允许在可变参数包之后声明 `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++ 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. +当且仅当哈希表中不存在键等价的元素时,将 `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` 支持拷贝插入。 +返回值:;; 若成功插入元素则返回 `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`。 +要求:`value_type` 支持拷贝插入。 +返回值:若成功插入元素则返回 `true`。 +并发特性:会阻塞当前对象的重哈希操作。 [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` 支持移动插入。 +返回值:;; 若成功插入元素则返回 `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)`构造元素并插入容器,随后使用新建元素的常量引用调用`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` 原位构造。 +返回值:;; 若成功插入元素则返回 `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++ 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. +若 `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` 的原值。 +若 `nh` 为空,则不执行任何操作;否则,当且仅当容器中不存在与 `nh.value()` 等效的键时,插入其关联的元素,并使用指向新插入元素的常量引用调用 `f1` ;否则,使用指向等效元素的常量引用调用 `f2` 。 --- -==== 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` 重载才参与重载决议。标准库假定 `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>` 为 `false` 时,`template` 重载才参与重载决议。 +注意:;; 仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为合法成员类型别名时,`template` 重载才参与重载决议。标准库假定 `Hash` 可同时接收 `K` 与 `Key` 类型参数调用,且 `Pred` 是透明的。该机制支持异构查找,避免了实例化 `Key` 类型对象的开销。 --- ==== erase_if -```c++ template size_type erase_if(F f); ``` +```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++17 并行算法的编译器中可用。 +注意:;; 仅当 `std::is_execution_policy_v>` 为 `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++ 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. +若 `Allocator::propagate_on_container_swap` 已声明且 `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` 重载才参与重载决议。标准库假定 `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` 重载才参与重载决议。标准库假定 `Hash` 可同时接收 `K` 与 `Key` 类型参数调用,且 `Pred` 是透明的。该机制支持异构查找,避免了实例化 `Key` 类型对象的开销。 --- -==== 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`. +后置条件:;; `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; ``` [horizontal] -Returns:;; The table's allocator. +返回值:;; 表的分配器。 --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The table's hash function. +返回值:;; 表的哈希函数。 --- @@ -1107,44 +1174,48 @@ Returns:;; The table's hash function. ``` 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` 重载才参与重载决议。标准库假定 `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` 重载才参与重载决议。标准库假定 `Hash` 可同时接收 `K` 与 `Key` 类型参数调用,且 `Pred` 是透明的。该机制支持异构查找,避免了实例化 `Key` 类型对象的开销。 +注意:;; 若存在并发插入操作,返回值可能无法精确反映执行后表的真实状态。 --- -=== 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`. +返回值:;; `static_cast(size())/static_cast(bucket_count())`,若 `bucket_count() == 0` 则返回 `0`。 --- @@ -1153,57 +1224,61 @@ Returns:;; `static_cast(size())/static_cast(bucket_count())`, or ` ```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`. +效果:;; 不执行任何操作,因为不允许用户修改此参数。保留该函数是为了与 `boost::unordered_set` 保持兼容。 --- -==== max_load +==== 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. +返回值:;; 表在不进行重哈希的情况下可容纳的最大元素数量(假定不会再删除任何元素)。 +注意:;; 构造、重哈希或清空后,表的最大负载量至少为 `max_load_factor() * bucket_count()`。在高负载条件下执行删除操作时,该数值可能会降低。 +注意:;; 若存在并发插入操作,返回值可能无法精确反映执行后表的真实状态。 --- -==== 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. +效果:;; 必要时调整桶数组大小,确保桶数量至少为 `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`. --- +如有必要,将改变桶数组的大小,使其至少包含 `n` 个桶,并确保负载因子小于或等于最大负载因子。此操作将根据情况增加或减少容器的 `bucket++_++count()` 。 -==== 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; ``` [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]. +返回值:;; 截至目前,由该表执行的插入与查找操作的统计信息描述。 +注意:;; 仅当**统计计算功能启用**时可用。 --- @@ -1211,18 +1286,19 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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[statistics calculation](统计计算功能)被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. +- 该推导指引包含 `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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1230,32 +1306,34 @@ template 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); ``` +```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); ``` +```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++ template void swap(concurrent_node_set& x, concurrent_node_set& y) noexcept(noexcept(x.swap(y))); ``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 [listing,subs="+macros,+quotes"] ----- x.xref:#concurrent_node_set_swap[swap](y); ----- @@ -1263,29 +1341,29 @@ 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); ``` +```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` 。 From 5cf1e44de126913f56737fd3b8a1cff5009095f5 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:51 +0000 Subject: [PATCH 066/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Flat Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-flat-set-adoc/zh_Hans/ --- .../pages/reference/header_concurrent_flat_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..18a5ced 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,9 +1,9 @@ [#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"] ----- From c7d57f78795144c03458d50d8d52080c37f98b37 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:48 +0000 Subject: [PATCH 067/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Flat Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-flat-map-adoc/zh_Hans/ --- .../pages/reference/header_concurrent_flat_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..0a02a99 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,9 +1,9 @@ [#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"] ----- From 3639d33c612f0c032eb5c2f1ddf7971d844ddc88 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:05 +0000 Subject: [PATCH 068/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (2 of 2 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Map Top (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-map-top-adoc/zh_Hans/ --- .../ROOT/pages/reference/header_unordered_map_top_zh_Hans.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..0f87ad6 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,5 +1,5 @@ [#header_unordered_map_fwd_top] -== `` Synopsis +== `++<++boost/unordered++_++map.hpp++>++` 概要 :idprefix: header_unordered_map_top_ From 32696b35e83ba9142232ca4fc3ad9b48f2c39110 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:47:38 +0000 Subject: [PATCH 069/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (430 of 430 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Flat Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-flat-set-adoc/zh_Hans/ --- .../concurrent_flat_set_zh_Hans.adoc | 702 ++++++++++-------- 1 file changed, 395 insertions(+), 307 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 8f58914..d7f4983 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,15 +1,15 @@ -[#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"] ----- @@ -269,16 +269,16 @@ namespace unordered { --- -=== 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. +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`. @@ -288,92 +288,92 @@ and https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] from the con |_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::pointer` 与 `std::allocator_traits::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]::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` +* 通过从`Alloc`重新绑定的分配器以`al`进行拷贝构造 +* `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. +通常而言,若 `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` -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; ``` -Chunk size internally used in xref:concurrent_flat_set_bulk_visit[bulk visit] operations. +xref:concurrent_flat_set_bulk_visit[批量访问]操作内部使用的块大小。 -=== 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. +构造一个空容器,使用`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++ 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. +构造一个拥有至少`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"] ---- template @@ -384,84 +384,84 @@ 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[enabled],仅当`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`] 移动构造。`other` 的内部桶数组直接转移至新容器。哈希函数、谓词及分配器均从 `other` 移动构造。若统计功能已通过 xref:concurrent_flat_set_boost_unordered_enable_stats[enabled],则从 `other` 转移内部统计信息并调用 `other.reset_stats()`。 [horizontal] Complexity:;; O(`bucket_count()`) --- -==== Initializer List Constructor +==== 初始化列表构造函数 [source,c++,subs="+quotes"] ---- concurrent_flat_set(std::initializer_list il, @@ -471,48 +471,48 @@ 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++ 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. +构造一个至少包含 `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"] ---- 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"] ---- template @@ -520,176 +520,190 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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++ 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. +构造一个至少包含 `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++ concurrent_flat_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```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. +构造一个至少包含 `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_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); ``` +```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`. +赋值运算符。销毁先前已存在的元素,从 `other` 拷贝赋值哈希函数和谓词;若 `Alloc::propagate_on_container_copy_assignment` 存在且其值为 `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 存在且其值为 true,则从 other 移动赋值分配器。若此时分配器与 other.get_allocator() 相等,other 的内部桶数组将直接转移给 *this;否则,插入由 other 元素移动构造的副本。若统计功能已通过 xref:concurrent_flat_set_boost_unordered_enable_stats [enabled],仅当最终分配器与 other.get_allocator() 相等时,从 other 转移内部统计信息,且始终调用 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[CopyInsertable^] +并发特性:;; 阻塞 `*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; ``` +```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` 重载版本才会参与重载决议。库假定 `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_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. +尽管功能上等同于对每个键单独调用 `[c]visit`,但得益于内部的流式优化,批量访问通常性能更高。建议当 `std::distance(first,last)` 至少达到 `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` 是一个传统前向迭代器(C++11 至 C++17),或满足 `std::forward_iterator` 要求(C++20 及更高版本)。 +对于 `K = std::iterator_traits::value_type`,要么 `K` 是 `key_type`,要么 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员别名。 +在后一种情况下,库假定 `Hash` 可同时接收 `K` 与 `Key` 类型调用,且 `Pred` 是透明的。这支持异构查找,避免了实例化 `Key` 类型对象的开销。 +返回值:;; 访问到的元素数量。 --- ==== [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++ 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++17 并行算法的编译器中可用。 +仅当 `std::is_execution_policy_v>` 为 `true` 时,这些重载版本才会参与重载决议。 +不允许使用无序执行策略。 --- ==== [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 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++17 并行算法的编译器中可用。 +仅当 `std::is_execution_policy_v>` 为 `true` 时,这些重载版本才会参与重载决议。 +不允许使用无序执行策略。 +并行化意味着执行流程不会在 `f` 返回 `false` 时立即终止,因此 `f` 可能还会被后续元素调用并同样返回 `false`。 --- -=== Size and Capacity +=== 大小与容量 -==== empty +==== 空 ```c++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回值:;; `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. +注意:;; 在存在并发插入操作时,返回的值可能无法准确反映函数执行后哈希表的真实大小。 --- @@ -698,297 +712,356 @@ Notes:;; In the presence of concurrent insertion operations, the value returned ```c++ size_type max_size() const noexcept; ``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回值:;; 哈希表能容纳的最大元素数量(最大容量)。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template bool emplace(Args&&... args); ``` +==== 原地构造 +```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++ 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`. Notes:;; Invalidates pointers and references to elements if a rehashing is issued. +前置要求:;; `value_type` 满足可复制插入要求。 +返回值:;; 成功插入元素时返回 `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` 满足可移动插入要求。 +返回值:;; 成功插入元素时返回 `true`。 +并发特性:;; 若触发重哈希,则会阻塞当前对象 `*this`。 +注意:;; 若执行重哈希,将使指向元素的指针和引用失效。 --- -==== Transparent Insert -```c++ template bool insert(K&& k); ``` +==== 透明插入 +```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. +当且仅当容器中不存在等价键的元素时,才会使用 `std::forward(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` 原位构造。 +返回值:;; 成功插入元素时返回 `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); ``` +```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++ 不允许在可变参数包之后声明参数 `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` 满足可复制插入要求。 +返回值:;; 成功插入元素时返回 `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` 满足可移动插入要求。 +返回值:;; 成功插入元素时返回 `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)` 构造元素并插入容器;否则,以等价元素的常量引用为参数调用函数 `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` 原位构造。 +返回值:;; 成功插入元素时返回 `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_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); ``` +```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. +若哈希表中不存在等价键的元素,则使用参数 `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++ 不允许在可变参数包之后声明参数 `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` 满足可复制插入要求。 +返回值:;; 成功插入元素时返回 `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` 满足可移动插入要求。 +返回值:;; 成功插入元素时返回 `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)`构造的元素插入容器,随后使用新建元素的常量引用调用`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` 原位构造。 +返回值:;; 成功插入元素时返回 `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` 抛出异常时才会抛出异常。 +备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为合法成员类型别名时才参与重载决议。标准库假定 `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`等价的元素存在且`f(x)`为`true`,则删除该元素`x`。 [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>` 为 `false` 时,`template` 重载才参与重载决议。 + +仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为合法成员类型别名时,`template` 重载才参与重载决议。标准库假定 `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++17并行算法的编译器中可用。 + +该重载仅当`std::is_execution_policy_v>`为`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`已声明且`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; ``` -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 ``` 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. +返回值:;; 表的哈希函数。 --- @@ -996,44 +1069,49 @@ Returns:;; The table's hash function. ``` 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)。 +备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为合法成员类型别名时才参与重载决议。标准库假定 `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`相等的元素。 +备注:;; `template` 重载仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为合法成员类型别名时才参与重载决议。标准库假定 `Hash` 可同时接受 `K` 与 `Key` 类型调用,且 `Pred` 是透明的。这实现了异构查找,避免了实例化 `Key` 类型对象的开销。 +在存在并发插入操作时,返回的值可能无法准确反映执行后表的真实状态。 --- -=== 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`. +返回值:;; `static_cast(size()) / static_cast(bucket_count())`;若`bucket_count() == 0`,则返回`0`。 --- @@ -1042,61 +1120,68 @@ Returns:;; `static_cast(size())/static_cast(bucket_count())`, or ` ```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`. +效果:;; 不执行任何操作,因为不允许用户修改此参数。保留该函数是为了与 `boost::unordered_set` 保持兼容。 --- -==== max_load +==== 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. +返回值:;; 哈希表在不进行重哈希的前提下可容纳的最大元素数量(假设不会再删除任何元素)。 +备注:;; 构造完成、重哈希或清空后,哈希表的最大负载至少为 `max_load_factor() * bucket_count()`。在高负载条件下执行删除操作后,该数值可能会降低。 +在存在并发插入操作时,返回的值可能无法准确反映执行后哈希表的真实状态。 --- -==== 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. +效果:;; 必要时调整哈希桶数组的大小,使桶数量至少为 `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`。 +--- -==== 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` 功能类似,该函数可用于**增加或减少**哈希表中的桶数量。 -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`。 --- -=== 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]. +返回值:;; 该哈希表迄今为止执行的插入与查找操作的统计信息。 +备注:;; 仅当 xref:reference/stats.adoc#stats[统计计算] 被 xref:concurrent_flat_set_boost_unordered_enable_stats[启用] 时,本接口方可使用。 --- @@ -1104,18 +1189,19 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1123,62 +1209,64 @@ template 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); ``` +```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); ``` +```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++ template void swap(concurrent_flat_set& x, concurrent_flat_set& y) noexcept(noexcept(x.swap(y))); ``` -Equivalent to [listing,subs="+macros,+quotes"] +等效于 [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` 。 From 349b4ce7f5ae0fa59a4a82d2963ed46fc86552fe Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:37 +0000 Subject: [PATCH 070/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (460 of 460 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Flat Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-flat-map-adoc/zh_Hans/ --- .../concurrent_flat_map_zh_Hans.adoc | 727 ++++++++++-------- 1 file changed, 407 insertions(+), 320 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 55ed491..7679068 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,15 +1,15 @@ -[#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++ 的 https://en.cppreference.com/w/cpp/named_req/Container[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"] ----- @@ -319,16 +319,16 @@ namespace unordered { --- -=== 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. +`std::pair` 必须能够从任何可转换为其的 `std::pair` 对象出发,在表中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^] 构造,并且也必须可以从表中进行 https://en.cppreference.com/w/cpp/named_req/Erasable[Erasable^] 擦除。 |_T_ @@ -340,92 +340,94 @@ namespace unordered { |_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` +* 从Alloc重新绑定后的分配器的al进行拷贝构造 +* `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. +通常而言,若 `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 operation` 操作,都会与针对 `e` 的内部访问函数调用同步。 ---- +由 `boost::concurrent_flat_map` 容器 `x` 执行的访问函数不得调用 `x` 上的任何操作;仅当对另一 `boost::concurrent_flat_map` 实例 `y` 的并发的未完成操作不直接或间接访问 `x` 时,才允许调用实例 `y` 上的操作。 --- -=== 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. +在调试版本中(更准确地说,当未定义 link:../../../../../assert/doc/html/assert.html#boost_assert_is_void[`BOOST_ASSERT_IS_VOID`] 时),系统会检测__容器重入__行为(即在访问 `m` 元素的函数内部非法调用 `m` 上的操作),并通过 `BOOST_ASSERT_MSG` 发出信号。若需关注运行时速度,可通过全局定义此宏来禁用该功能。 --- ==== `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; ``` -Chunk size internally used in xref:concurrent_flat_map_bulk_visit[bulk visit] operations. +xref:concurrent_flat_map_bulk_visit [批量访问] 操作内部使用的块大小。 -=== 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. +使用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++ 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. +构造一个至少包含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"] ---- template @@ -436,84 +438,88 @@ 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转移内部统计信息 +始终调用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++ 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()`. +从 xref:#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"] ---- concurrent_flat_map(std::initializer_list il, @@ -523,48 +529,50 @@ 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"] ---- 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"] ---- template @@ -572,176 +580,204 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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. +构造一个至少包含 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++ concurrent_flat_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```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. +构造一个至少包含 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_flat_map(); ``` +```c++ [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); ``` +```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`. +赋值运算符。销毁原有的所有元素,从other复制赋值哈希函数与谓词;若Alloc::propagate_on_container_copy_assignment存在且其值为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存在且其值为true,则从other移动赋值分配器。 +若此时分配器与other.get_allocator()相等,则直接转移other的内部桶数组至当前容器;否则,插入other元素的移动构造副本。 +如果启用了统计功能: +当且仅当最终分配器与other.get_allocator()相等时,从other转移内部统计信息 +始终调用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. +并发:阻塞于 *this 和 other。 +从初始化列表赋值。销毁所有先前存在的元素。 [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++ 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 为常量(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. +返回值:访问过的元素数量(0 或 1)。 +注意:template 形式的重载仅在 Hash::is_transparent 与 Pred::is_transparent 为合法成员别名时才参与重载决议。 +库假定 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 reference to `x`. Such reference is const iff `*this` is const. +对范围 [first, last) 中的每个键 k: +如果容器中存在键与 k 等价的元素 x,则以 x 的引用调用函数 f。 +当且仅当当前容器 *this 为常量(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. +尽管功能上等价于对每个键单独调用 [c]visit,但批量访问因内部流线型优化,通常性能更高。 +建议 std::distance(first,last) 至少达到 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[遗留向前迭代器^] 要求({cpp}11 至 {cpp}17),或满足 https://en.cppreference.com/w/cpp/iterator/forward_iterator[`std::forward_iterator`^] 要求({cpp}20 及更高版本)。对于 `K = std::iterator_traits::value_type`,要么 `K` 是 `key_type`,要么 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef。在后一种情况下,库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。返回:被访问的元素数量。 --- ==== [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 references to each of the elements in the table. Such references are const iff `*this` is const. +依次以表中每个元素的引用调用函数 f。 +当且仅当当前容器 *this 为常量(const)时,该引用为常量引用。 [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 为常量(const)时,该引用为常量引用。 +执行过程将根据指定的执行策略语义进行并行化。 [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++17 并行算法的编译器中可用。 +仅当 std::is_execution_policy_v> 为 true 时,这些重载版本才参与重载决议。 +不允许使用无序执行策略。 --- ==== [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 为常量(const)时,该元素引用为常量引用。 [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 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 为常量(const)时,该元素引用为常量引用。 +执行过程将根据指定的执行策略语义进行并行化。 [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++17 并行算法的编译器中可用。 +仅当 std::is_execution_policy_v> 为 true 时,这些重载版本才参与重载决议。 +不允许使用无序执行策略。 +并行化意味着:即使 f 已返回 false,执行流程也不一定会立即终止;因此,f 可能还会被继续调用以处理后续元素,且这些调用同样可能返回 false。 --- -=== Size and Capacity +=== 大小与容量 -==== empty +==== 空 ```c++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回值: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. +注意:在存在并发插入操作时,返回的值可能无法准确反映函数执行后容器的真实大小。 --- @@ -750,355 +786,391 @@ Notes:;; In the presence of concurrent insertion operations, the value returned ```c++ size_type max_size() const noexcept; ``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回值:容器所能容纳的最大元素数量(最大容量)。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template bool emplace(Args&&... args); ``` +==== 原地构造 +```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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +若 `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:;; 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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +形式为 `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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +形式为 `insert(x)` 的调用(其中 `x` 可同等转换为 `value_type&&` 和 `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); ``` +```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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +该接口仅为展示说明,因为 C++ 不允许在变参参数包之后声明参数 `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); ``` +```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:;; 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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +在形式为 `insert_or_[c]visit(obj, f)` 的调用中,接受 `const value_type&` 参数的重载仅当 `std::remove_cv::type>::type` 为 `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); ``` +```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::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); ``` +```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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +该接口仅为展示说明,因为 C++ 不允许在变参参数包之后声明参数 `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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +在形式为 `insert_and_[c]visit(obj, f1, f2)` 的调用中,接受 `const value_type&` 参数的重载仅当 `std::remove_cv::type>::type` 为 `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` 的 rehash 操作上阻塞。注意:如果执行了 rehash,则指向元素的指针和引用会失效。+ +在形式为 `insert_and_[c]visit(obj, f1, f2)` 的调用中,接受 `value_type&&` 参数的重载仅当 `std::remove_reference::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++ 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"] +等效于 [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); ``` +```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;否则,构造形式为: // 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. +这与 xref:#concurrent_flat_map_emplace [emplace] 不同,后者仅将所有参数转发给value_type的构造函数。 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. +若`Hash::is_transparent`与`Pred::is_transparent`为合法的成员类型别名,则`template`重载版本才会参与重载决议。库假定`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); ``` +```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;否则,构造形式为: // 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. +该接口仅为说明性用途,因为C++不允许在可变参数包之后声明参数`f`。 -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. +若`Hash::is_transparent`和`Pred::is_transparent`是有效的成员类型别名,则`template`重载版本才会参与重载决议。库假定`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); ``` +```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;否则,构造形式为: // 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. +该接口仅为说明性用途,因为C++不允许在可变参数包之后声明`f1`和`f2`参数。 -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. +若`Hash::is_transparent`和`Pred::is_transparent`是有效的成员类型别名,则`template`重载版本才会参与重载决议。库假定`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); ``` +```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(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))) +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`。 +说明:若触发重哈希,将使指向元素的指针和引用失效。 +`template` 仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为有效成员类型别名时才参与重载决议。库假定`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`重载版本才参与重载决议。库假定`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>`为`false`时,`template`重载版本才参与重载决议。 + +仅当`Hash::is_transparent`和`Pred::is_transparent`为有效的成员类型别名时,`template`重载版本才参与重载决议。库假定`Hash`可同时接受`K`与`Key`类型的参数调用,且`Pred`是透明的。该设计支持异构查找,避免了实例化`Key`类型对象的开销。 --- ==== erase_if -```c++ template size_type erase_if(F f); ``` +```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++17并行算法的编译器中可用。 + +仅当`std::is_execution_policy_v>`为`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`已定义且其值为`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; ``` -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++ 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`. +将来源容器`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; ``` [horizontal] -Returns:;; The table's allocator. +返回值:容器的分配器。 --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The table's hash function. +返回值:容器的哈希函数。 --- @@ -1106,107 +1178,119 @@ Returns:;; The table's hash function. ``` 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` 重载版本才参与重载决议。库假定哈希函数可同时作用于 `K` 类型与键类型,且相等谓词是透明的,从而支持异构查找,避免实例化键类型带来的开销。 + +若存在并发插入操作,返回值可能无法精确反映容器执行后的真实状态。 --- -==== 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` 重载版本才参与重载决议。库假定哈希函数可同时作用于 `K` 类型与键类型,且相等谓词是透明的,从而支持异构查找,避免实例化键类型带来的开销。 + +若存在并发插入操作,返回值可能无法精确反映容器执行后的真实状态。 --- -=== 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`. +返回值:`static_cast(size())/static_cast(bucket_count())`;若 `bucket_count() == 0`,则返回 `0`。 --- -==== max_load_factor +==== 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`. +效果:无任何操作,用户不允许修改此参数。保留该函数是为了与 `boost::unordered_map` 保持兼容。 --- -==== max_load +==== 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. +返回值:容器在不进行重哈希的前提下可容纳的最大元素数量(假定不会再擦除任何元素)。 +说明:容器在构造、重哈希或清空后,其最大负载量至少为 `max_load_factor() * bucket_count()`。在高负载条件下执行擦除操作时,该数值可能会降低。 +若存在并发插入操作,返回值可能无法精确反映容器执行后的真实状态。 --- -==== 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. +效果:必要时调整桶数组的大小,使桶数量至少为 `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`。 -==== 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` 功能类似,该函数可用于**增大或缩小**容器的桶数量。 -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`。 --- -=== 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]. +返回值:容器截至目前执行的插入与查找操作的统计描述信息。 +说明:仅当**启用统计计算**时,该函数才可用。 --- @@ -1214,18 +1298,19 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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. +- 该推导指引包含 `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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1258,32 +1343,34 @@ 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); ``` +```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); ``` +```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++ template void swap(concurrent_flat_map& x, concurrent_flat_map& y) noexcept(noexcept(x.swap(y))); ``` -Equivalent to [listing,subs="+macros,+quotes"] +等效于 [listing,subs="+macros,+quotes"] ----- x.xref:#concurrent_flat_map_swap[swap](y); ----- @@ -1291,29 +1378,29 @@ 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); ``` +```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::type` 和 `std::remove_const::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` 。 From a0cc992fabec7062535017f25c4e76ef967d04c8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:53 +0000 Subject: [PATCH 071/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Node Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-node-map-adoc/zh_Hans/ --- .../pages/reference/header_concurrent_node_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..1def290 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,9 +1,9 @@ [#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"] ----- From 0981cf6f859c50d1c8849ce4405868c36092a316 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:54:50 +0000 Subject: [PATCH 072/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (47 of 47 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Structures (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-structures-adoc/zh_Hans/ --- .../ROOT/pages/structures_zh_Hans.adoc | 81 ++++++++++--------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/doc/modules/ROOT/pages/structures_zh_Hans.adoc b/doc/modules/ROOT/pages/structures_zh_Hans.adoc index dba552d..a00d49e 100644 --- a/doc/modules/ROOT/pages/structures_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/structures_zh_Hans.adoc @@ -1,8 +1,8 @@ -[#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 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]. +值得注意的是,这种方法仅被 pass:[libc++] 和 pass:[libstdc++] 所采用;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++ 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 // ... } ``` +使用简单的桶组布局,只需执行以下操作:```c++auto const idx = get_bucket_idx(hash_function(key));node* n = buckets[idx]; // 第一次加载if (n) { value_type const& v = *n; // 第二次加载 // ...}``` -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: +在实际使用中,额外的间接层会对 `insert`、`find` 和 `erase` 等常见操作的性能产生显著影响。但为了保持容器的迭代速度,Boost.Unordered 引入了一种新颖的数据结构——“桶组”。桶组是桶数组的一个固定宽度的子区间视图。它包含一个位掩码(类型为 `std::size_t`),用于跟踪桶的占用情况,并包含两个指针,以便与非空组形成双向链表。下面是一个示例图: [#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. +因此,容器范围内的迭代转变为遍历非空的桶组(这是一个具有常数时间复杂度的操作),从而将时间复杂度降回 `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. 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 指令即可快速检查完整的元数据字,并在全部 15 个桶中寻找 _h_ 的缩减值:不匹配的桶可以迅速丢弃,而那些缩减哈希值匹配的桶则需要通过与对应元素的完整比较来进行检查。如果未找到目标元素,则检查溢出字节。 -- 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. 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 [对应章节]。 From e5f87d4dc21b0a0e4731b00037624f5c4e4b21b9 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:59 +0000 Subject: [PATCH 073/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Flat Map Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-flat-map-fwd-adoc/zh_Hans/ --- .../reference/header_unordered_flat_map_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..07add57 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++>++`] 中定义的所有内容。 From 7a0a28386ca267d5f29b4dfcace103327b730736 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:58 +0000 Subject: [PATCH 074/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Flat Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-flat-map-adoc/zh_Hans/ --- .../pages/reference/header_unordered_flat_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..df41678 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,9 +1,9 @@ [#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"] ----- From bef0fbe2f083ab20c9ed2c0baf6ed0d1780f2d6b Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:28 +0000 Subject: [PATCH 075/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (17 of 17 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Intro (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-intro-adoc/zh_Hans/ --- doc/modules/ROOT/pages/intro_zh_Hans.adoc | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/modules/ROOT/pages/intro_zh_Hans.adoc b/doc/modules/ROOT/pages/intro_zh_Hans.adoc index 2eb3215..13be990 100644 --- a/doc/modules/ROOT/pages/intro_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/intro_zh_Hans.adoc @@ -1,35 +1,35 @@ [#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. +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] |=== -^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|*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 中的所有 set 和 map 分别与 `std::unordered_set` 和 `std::unordered_map` 类似的方式进行实例化: [source,c++] ---- @@ -54,4 +54,4 @@ namespace boost { } ---- -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[相等谓词与哈希函数] 一节。 From e63dc8308e4c5c2bd9d0e92216045d4cfafa975c Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:50 +0000 Subject: [PATCH 076/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Flat Map Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-flat-map-fwd-adoc/zh_Hans/ --- .../reference/header_concurrent_flat_map_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..4d40470 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++>++`] 中的所有定义。 From f54352eab39f84bb5cdf010447baa19de9cc8ab7 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:09 +0000 Subject: [PATCH 077/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Node Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-node-set-adoc/zh_Hans/ --- .../pages/reference/header_unordered_node_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..f738c95 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,9 +1,9 @@ [#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"] ----- From 983a59a4318ad8dd07c6e3102004479b26e90e27 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:52:30 +0000 Subject: [PATCH 078/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (434 of 434 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Multimap (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-multimap-adoc/zh_Hans/ --- .../reference/unordered_multimap_zh_Hans.adoc | 668 ++++++++++-------- 1 file changed, 380 insertions(+), 288 deletions(-) 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..b3ecfc5 100644 --- a/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_multimap_zh_Hans.adoc @@ -1,11 +1,11 @@ [#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"] ----- @@ -246,9 +246,9 @@ namespace unordered { --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== @@ -267,32 +267,32 @@ namespace unordered { |_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. +桶的数量可以通过调用 insert 自动增加,或者作为调用 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. +全局定义此宏以支持加载由 Boost 1.84 之前版本的 Boost 保存到 Boost.Serialization 归档中的 `unordered_multimap`。 -=== Typedefs +=== 类型定义 [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` 。 --- @@ -301,9 +301,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -312,9 +312,9 @@ The iterator category is at least a forward iterator. 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` 对象可用于遍历单个桶内的元素。 --- @@ -323,9 +323,9 @@ A `local_iterator` object can be used to iterate through a single bucket. 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` 对象可用于遍历单个桶。 --- @@ -334,33 +334,35 @@ A const_local_iterator object can be used to iterate through a single bucket. typedef _implementation-defined_ node_type; ---- -See node_handle_map for details. +详见 `node_handle_map`。 --- -=== 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`. +使用 `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++ 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`. +构造一个至少包含 `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"] ---- template @@ -371,70 +373,72 @@ 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++ unordered_multimap(unordered_multimap&& 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_multimap(InputIterator f, InputIterator l, const allocator_type& a); ``` +==== 带分配器的迭代器范围构造函数 +```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. +使用 `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++ explicit unordered_multimap(const Allocator& a); ``` -Constructs an empty container, using 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"] ---- unordered_multimap(std::initializer_list il, @@ -444,47 +448,49 @@ 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"] ---- 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"] ---- template @@ -492,103 +498,103 @@ template 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++ 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. +使用 `a` 作为分配器,最大负载因子为 `1.0`,构造一个至少包含 `n` 个桶的空容器,并将 `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++ 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. +构造一个至少包含 `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_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++ 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. +如果 `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); ``` 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. +如果 `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; ``` [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. +返回:指向容器尾后值的迭代器。 --- @@ -596,7 +602,7 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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`,如果容器为空则返回容器的尾后值。 --- @@ -604,27 +610,27 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回:`size() == 0`。 --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回:`std::distance(begin(), end())`。 --- @@ -633,275 +639,341 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +返回:指向已插入元素的迭代器。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 --- ==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +```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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +返回:指向已插入元素的迭代器。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `position` 的含义表述相当模糊。但唯一实际的使用方式,也是 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

(value))` 向容器中插入一个元素。

-Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅在 `std::is_constructible::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++iterator insert(const_iterator hint, const value_type& obj);``` +将 `obj` 插入容器中。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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. +将 `obj` 插入容器中。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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))`. +通过执行 `emplace_hint(hint, std::forward

(value))` 向容器中插入一个元素。

-Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅在 `std::is_constructible::value` 为 `true` 时参与重载决议。 -`hint` is a suggestion to where the element should be inserted. +`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. +返回:指向已插入元素的迭代器。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +抛出:当插入单个元素时,如果除调用 `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); ``` -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_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` 中。 + +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `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. +如果 `nh` 为空,则无效果。 -Otherwise inserts the element owned by `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++ 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_map`. +要求:`nh` 为空,或者 `nh.get_allocator()` 等于容器的分配器。 +返回:如果 `nh` 为空,则返回 `end()`;否则,返回指向新插入元素的迭代器。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 Boost.Unordered 支持的唯一方式,是将其指向一个具有相同键的已存在元素。 +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 +此函数可用于插入从兼容的 `unordered_map` 中提取的节点。 --- -==== Erase by 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 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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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); ``` -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` 返回指向下一个元素的迭代器成本较高,但容器已经过重新设计,不再存在这种情况。因此,此方法现已弃用。 --- ==== 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` 抛出异常时才会抛出。 +在此实现中,此重载不会调用任何函数对象的方法,因此不会抛出异常,但这在其他实现中可能并不成立。 +注意:引入此方法是因为从 `erase` 返回指向下一个元素的迭代器成本较高,但容器已经过重新设计,不再存在这种情况。因此,此方法现已弃用。 --- -==== 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++ 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. +如果 `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++11 标准不完全相同,因为相等谓词和哈希函数是使用其拷贝构造函数进行交换的。 --- -==== clear +==== 清空 ```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++ 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`. +尝试“合并”两个容器:遍历 `source`,提取 `source` 中的所有节点,并将它们插入到 `*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` 可能具有不同的哈希函数和键相等谓词,因此 `source` 中每个节点的键都会使用 `this->hash_function()` 重新计算哈希值,然后在必要时使用 `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; ``` --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:容器的哈希函数。 --- @@ -909,53 +981,57 @@ Returns:;; The container's hash function. ``` 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` 成员函数模板。 `template` 重载仅在 `Hash::is_transparent` `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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; ``` +```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())`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -=== Bucket Interface +=== 桶接口 ==== bucket_count ```c++ size_type bucket_count() const noexcept; ``` [horizontal] -Returns:;; The number of buckets. +返回:桶的数量。 --- @@ -963,40 +1039,46 @@ Returns:;; The number of buckets. ```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`. +要求:`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()`。 + +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== 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`. +要求:`n` 必须在 `[0, bucket_count())` 范围内。 +返回:指向索引为 `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`. +要求:`n` 必须在 `[0, bucket_count())` 范围内。 +返回:指向索引为 `n` 的桶中“尾后”元素的局部迭代器。 --- @@ -1004,7 +1086,8 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中第一个元素的常量局部迭代器。 --- @@ -1012,17 +1095,18 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A consta ```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 +=== 哈希策略 -==== load_factor +==== 负载因子 ```c++ float load_factor() const noexcept; ``` [horizontal] -Returns:;; The average number of elements per bucket. +返回:每个桶的平均元素数量。 --- @@ -1031,55 +1115,58 @@ Returns:;; The average number of elements per bucket. ```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. +效果:使用 `z` 作为提示,更改容器的最大负载因子。 --- -==== 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. +更改桶的数量,使其至少包含 `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); ``` -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::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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1112,82 +1199,87 @@ 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); ``` +==== 运算符 +```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` 中均存在一个具有相同键的组,并且该组是 `x` 中对应组的置换(使用 `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); ``` +```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` 中均存在一个具有相同键的组,并且该组是 `x` 中对应组的置换(使用 `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++11 标准不完全相同,因为相等谓词和哈希函数是使用其拷贝构造函数进行交换的。 --- === erase_if -```c++ template typename unordered_multimap::size_type erase_if(unordered_multimap& c, Predicate pred); ``` +```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`. +遍历容器 `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::type` 和 `std::remove_const::type` 必须是可序列化的(对于 XML 归档需支持 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::type&&, std::remove_const::type&&)` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。`x.key_equal()` 在功能上必须等价于 `other.key_equal()`。 +注意:如果归档是使用 Boost 1.84 之前版本的 Boost 保存的,则必须全局定义配置宏 `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. +将迭代器(或常量迭代器)`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`. +使迭代器(或常量迭代器)`it` 指向原始迭代器(或常量迭代器)被保存到归档(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` 执行任何修改操作。 From e1032bd1401075eab6be2cf7999fd0de70a32530 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:57 +0000 Subject: [PATCH 079/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Node Set Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-node-set-fwd-adoc/zh_Hans/ --- .../reference/header_concurrent_node_set_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..2fcfe83 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++>++`] 中的所有定义。 From d6784be80f78056f270ac4e2a0bc6e97d524df78 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:04 +0000 Subject: [PATCH 080/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Map Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-map-fwd-adoc/zh_Hans/ --- .../pages/reference/header_unordered_map_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..b1cf8ea 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 +== `` 概要 :idprefix: header_unordered_map_fwd_ -Forward declares all the definitions in xref:reference/header_unordered_map.adoc[``]. +前向声明 xref:reference/header_unordered_map.adoc[``]中的所有定义。 From b27f2c2028a50850dff43f17d159d4faa90a992f Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:31 +0000 Subject: [PATCH 081/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (37 of 37 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Ref (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-ref-adoc/zh_Hans/ --- doc/modules/ROOT/pages/ref_zh_Hans.adoc | 72 ++++++++++++------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/doc/modules/ROOT/pages/ref_zh_Hans.adoc b/doc/modules/ROOT/pages/ref_zh_Hans.adoc index 36976a2..cbd50bb 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/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[哈希特征] +* xref:reference/stats.adoc[统计信息] +* 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[Class Template ++++++concurrent_node_set++++++] From 186f93faa592c80aedd240b57ca6eebbc8447fe7 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:54:39 +0000 Subject: [PATCH 082/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (403 of 403 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Node Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-node-set-adoc/zh_Hans/ --- .../reference/unordered_node_set_zh_Hans.adoc | 625 ++++++++++-------- 1 file changed, 354 insertions(+), 271 deletions(-) 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..e80a0e6 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,19 +1,21 @@ [#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"] ----- @@ -233,9 +235,9 @@ namespace unordered { --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== @@ -251,38 +253,38 @@ namespace unordered { |_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_avalanching[hash_is_avalanching]::value` 为 `true`,则哈希函数将按原样使用;否则,会增加一个位混合后处理阶段,以牺牲额外的计算成本为代价来提高哈希质量。 --- -=== 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. +全局定义此宏,以启用容器的 xref:reference/stats.adoc#stats[统计计算] 功能。请注意,此选项会降低许多操作的总体性能。 --- -=== Typedefs +=== 类型定义 [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` 。 --- @@ -291,9 +293,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -302,7 +304,7 @@ The iterator category is at least a forward iterator. 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] 。 --- @@ -311,7 +313,7 @@ A class for holding extracted container elements, modelling https://en.cpprefere typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -324,33 +326,35 @@ 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(); ``` -Constructs an empty container 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 unordered_node_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```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. +构造一个至少包含 `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"] ---- template @@ -361,75 +365,76 @@ 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++ 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. +如果 `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[`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++ 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. +使用 `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++ 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`. +构造一个容器,拷贝 `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[`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++ 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()`. +从 xref:#concurrent_node_set[`concurrent_node_set`] 进行移动构造。`other` 的内部桶数组直接转移给新容器。哈希函数、谓词和分配器通过移动构造从 `other` 获得。如果启用了统计信息(详见 xref:unordered_node_set_boost_unordered_enable_stats[`BOOST_UNORDERED_ENABLE_STATS`]),则从 `other` 转移内部的统计信息,并调用 `other.reset_stats()`。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度:常数时间。 +并发性:在 `other` 上阻塞。 --- -==== Initializer List Constructor +==== 初始化列表构造函数 [source,c++,subs="+quotes"] ---- unordered_node_set(std::initializer_list il, @@ -439,48 +444,48 @@ 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++ 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. +构造一个至少包含 `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++ 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. +构造一个至少包含 `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"] ---- 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"] ---- template @@ -488,88 +493,92 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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_set(std::initializer_list il, const allocator_type& a); ``` +```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. +使用 `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++ 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. +使用 `a` 以及默认的哈希函数和键相等谓词,构造一个至少包含 `n` 个桶的空容器,并将 `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_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```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. +构造一个至少包含 `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_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); ``` +```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`. +赋值运算符。销毁之前存在的元素,从 `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[`BOOST_UNORDERED_ENABLE_STATS`]),则当最终分配器与 `other.get_allocator()` 相等时,从 `other` 转移内部的统计信息,并且始终会调用 `other.reset_stats()`。 --- -==== Initializer List Assignment -```c++ unordered_node_set& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```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^] +要求:`value_type` 满足 https://en.cppreference.com/w/cpp/named_req/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()`) +返回:指向容器第一个元素的迭代器,如果容器为空则返回容器的尾后迭代器。 +复杂度:O(`bucket_count()`) --- @@ -577,7 +586,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:指向容器尾后值的迭代器。 --- @@ -593,13 +602,13 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` @@ -608,7 +617,7 @@ Returns:;; `size() == 0` --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` @@ -622,145 +631,187 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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); ``` +```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++ 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 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++ 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)` 构造的元素。 [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[可原位构造^]。 +返回:如果发生了插入,则返回类型的 bool 分量为 true。 +如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载大于最大负载时才会发生。 + +只有当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `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, 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)` 构造的元素。 -`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[可原位构造^]。 +返回:如果发生了插入,则返回类型的 bool 分量为 true。 +如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载大于最大负载时才会发生。 + +只有当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `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 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++ 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. +返回:一个 `insert_return_type` 对象,由 `position`、`inserted` 和 `node` 构造而成: +* 若 `nh` 为空,则 `inserted` 为 `false` , `position` 为 `end()` ,且 `node` 为空。 +* 否则,若插入操作发生,则 `inserted` 为 `true` , `position` 指向被插入的元素,且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 `false` , `node` 保留 `nh` 的原始值,且 `position` 指向一个键等价于 `nh.value()` 的元素。 +如果 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.value()` 的元素时,插入其关联的元素。函数返回时, `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` 变为空;否则 `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] ---- @@ -768,108 +819,117 @@ _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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时,才参与重载决议。库假定 `Hash` 可同时用 `K` 和 `Key` 调用,并且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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); ``` -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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时才参与重载决议。库假定 `Hash` 可同时用 `K` 和 `Key` 调用,并且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- ==== 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`. +从 `position` 指向的元素移动构造一个 `init_value` 对象 `x`,擦除该元素并返回 `x`。 --- -==== clear +==== 清空 ```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++ 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`. +从 `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; ``` [horizontal] -Returns:;; The container's allocator. +返回:容器的分配器。 --- -==== hash_function -``` hasher hash_function() const; ``` +==== 哈希函数 +```cpp +hasher hash_function() const; +``` [horizontal] -Returns:;; The container's hash function. +返回:容器的哈希函数对象。 --- @@ -877,63 +937,67 @@ Returns:;; The container's hash function. ``` 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()`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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; ``` +```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())`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -=== 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`. +返回:`static_cast(size())/static_cast(bucket_count())`,如果 `bucket_count() == 0` 则返回 `0`。 --- @@ -942,15 +1006,15 @@ Returns:;; `static_cast(size())/static_cast(bucket_count())`, or ` ```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`. +效果:不执行任何操作,因为用户不允许更改此参数。保留此函数是为了与 `boost::unordered_set` 保持兼容。 --- @@ -960,45 +1024,47 @@ Effects:;; Does nothing, as the user is not allowed to change this parameter. Ke ```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); ``` -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); ``` -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; ``` [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[`BOOST_UNORDERED_ENABLE_STATS`] 启用时才可用。 --- @@ -1006,18 +1072,22 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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[`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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1025,80 +1095,93 @@ template 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); ``` +```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); ``` +```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). +若 `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); ``` - -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(); ``` +```c++ template typename unordered_node_set::size_type erase_if(unordered_node_set& c, Predicate pred); ``` + +遍历容器 `c`,并移除所有使给定谓词返回 `true` 的元素。 + +[horizontal] +返回:被擦除的元素数量。 +注意:等价于: +```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 归档需支持 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. +将迭代器(或常量迭代器)`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`. +使迭代器(或常量迭代器)`it` 指向原始迭代器(或常量迭代器)被保存到归档(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` 执行任何修改操作。 From e65b1c4e72af50169ff6d765ff6ee4fa6b088c00 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:56 +0000 Subject: [PATCH 083/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Node Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-node-set-adoc/zh_Hans/ --- .../pages/reference/header_concurrent_node_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..dd66486 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,9 +1,9 @@ [#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"] ----- From c05de4b0bf21966c3c30ab7ba0d9f4c76f865e4e Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:11 +0000 Subject: [PATCH 084/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-set-adoc/zh_Hans/ --- .../ROOT/pages/reference/header_unordered_set_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..048d4f6 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,9 +1,9 @@ [#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"] ----- From b0260181dd7f3acfff63a2e7ace49a191d29c7e9 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:47 +0000 Subject: [PATCH 085/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (6 of 6 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Hash Traits (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-hash-traits-adoc/zh_Hans/ --- doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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..a441129 100644 --- a/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/hash_traits_zh_Hans.adoc @@ -1,9 +1,9 @@ [#hash_traits] -== Hash Traits +== 哈希特征 :idprefix: hash_traits_ -=== `` Synopsis +=== `++<++boost/unordered/hash++_++traits.hpp++>++` 概要 [listing,subs="+macros,+quotes"] ----- @@ -19,8 +19,8 @@ using boost::hash_is_avalanching; ----- [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` ;否则它们将实施位混合后处理阶段,以牺牲额外计算成本为代价来提升哈希质量。 --- From 8617172906b017fa47cb58f91362497bb4da21e7 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:52:36 +0000 Subject: [PATCH 086/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (417 of 417 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Multiset (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-multiset-adoc/zh_Hans/ --- .../reference/unordered_multiset_zh_Hans.adoc | 642 ++++++++++-------- 1 file changed, 363 insertions(+), 279 deletions(-) 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..4fb88c5 100644 --- a/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_multiset_zh_Hans.adoc @@ -1,11 +1,11 @@ [#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"] ----- @@ -237,9 +237,9 @@ namespace unordered { --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== @@ -255,32 +255,32 @@ namespace unordered { |_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. +桶的数量可以通过调用 insert 自动增加,或者作为调用 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. +全局定义此宏以支持加载由 Boost 1.84 之前版本的 Boost 保存到 Boost.Serialization 归档中的 `unordered_multiset`。 -=== Typedefs +=== 类型定义 [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` 。 --- @@ -289,9 +289,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -300,9 +300,9 @@ The iterator category is at least a forward iterator. 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` 对象可用于遍历单个桶内的元素。 --- @@ -311,9 +311,9 @@ A `local_iterator` object can be used to iterate through a single bucket. 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` 对象可用于遍历单个桶。 --- @@ -322,33 +322,35 @@ A const_local_iterator object can be used to iterate through a single bucket. typedef _implementation-defined_ node_type; ---- -See node_handle_set for details. +详见 `node_handle_set`。 --- -=== 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`. +使用 `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"] ---- template @@ -359,70 +361,72 @@ 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"] ---- unordered_multiset(std::initializer_list il, @@ -432,48 +436,49 @@ 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"] ---- 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"] ---- template @@ -481,105 +486,105 @@ template 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++ 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. +构造一个至少包含 `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(); ``` [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); ``` +```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++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);```移动赋值运算符。 -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_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; ``` [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. +返回:指向容器尾后值的迭代器。 --- @@ -587,7 +592,7 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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`,如果容器为空则返回容器的尾后值。 --- @@ -595,27 +600,27 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回:`size() == 0`。 --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回:`std::distance(begin(), end())`。 --- @@ -624,251 +629,312 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +返回:指向已插入元素的迭代器。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 --- ==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +```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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +返回:指向已插入元素的迭代器。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 --- -==== 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. +将 `obj` 插入容器中。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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. +将 `obj` 插入容器中。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 +抛出:当插入单个元素时,如果除调用 `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); ``` -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` 中。 + +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `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. +如果 `nh` 为空,则无效果。 -Otherwise inserts the element owned by `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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 Boost.Unordered 支持的唯一方式,是将其指向一个具有相同键的已存在元素。 +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 +此函数可用于插入从兼容的 `unordered_set` 中提取的节点。 --- -==== Erase by 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++ size_type erase(const key_type& k); template size_type erase(K&& x); ``` -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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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); ``` -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` 返回指向下一个元素的迭代器成本较高,但容器已经过重新设计,不再存在这种情况。因此,此方法现已弃用。 --- ==== 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` 抛出异常时才会抛出。 +在此实现中,此重载不会调用任何函数对象的方法,因此不会抛出异常,但这在其他实现中可能并不成立。 +注意:引入此方法是因为从 `erase` 返回指向下一个元素的迭代器成本较高,但容器已经过重新设计,不再存在这种情况。因此,此方法现已弃用。 --- -==== 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++11 标准不完全相同,因为相等谓词和哈希函数是使用其拷贝构造函数进行交换的。 --- -==== clear +==== 清空 ```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`. +尝试“合并”两个容器:遍历 `source`,提取 `source` 中的所有节点,并将它们插入到 `*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` 可能具有不同的哈希函数和键相等谓词,因此 `source` 中每个节点的键都会使用 `this->hash_function()` 重新计算哈希值,然后在必要时使用 `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 noexcept; ``` --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:容器的哈希函数对象。 --- @@ -877,51 +943,57 @@ Returns:;; The container's hash function. ``` 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` 成员函数模板。 + +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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; ``` +```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())`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -=== Bucket Interface +=== 桶接口 ==== bucket_count ```c++ size_type bucket_count() const noexcept; ``` [horizontal] -Returns:;; The number of buckets. +返回:桶的数量。 --- @@ -929,40 +1001,44 @@ Returns:;; The number of buckets. ```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`. +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; ``` +==== 桶 +```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()`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== 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`. +要求:`n` 必须在 `[0, bucket_count())` 范围内。 +返回:指向索引为 `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`. +要求:`n` 必须在 `[0, bucket_count())` 范围内。 +返回:指向索引为 `n` 的桶中“尾后”元素的局部迭代器。 --- @@ -970,7 +1046,8 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中第一个元素的常量局部迭代器。 --- @@ -978,74 +1055,78 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A consta ```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 +=== 哈希策略 -==== 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. +效果:使用 `z` 作为提示,更改容器的最大负载因子。 --- -==== 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. +更改桶的数量,使其至少包含 `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. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 --- -==== 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()`. +等价于 `a.rehash(ceil(n / a.max_load_factor()))`;如果 `n > 0` 且 `a.max_load_factor() == std::numeric_limits::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. +当 `size() == 0` 时, `rehash(0)` 将释放底层桶数组。 --- -=== 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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1053,82 +1134,85 @@ template typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 -==== operator -```c++ template bool operator==(const unordered_multiset& x, const unordered_multiset& y); ``` +==== 运算符 +```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); ``` +```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). +若 `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++11 标准不完全相同,因为相等谓词和哈希函数是使用其拷贝构造函数进行交换的。 --- === erase_if -```c++ template typename unordered_multiset::size_type erase_if(unordered_multiset& c, Predicate pred); ``` +```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`. +遍历容器 `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 归档需支持 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 保存的,则必须全局定义配置宏 `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. +将迭代器(或常量迭代器)`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`. +使迭代器(或常量迭代器)`it` 指向原始迭代器(或常量迭代器)被保存到归档(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` 执行任何修改操作。 From fc5732cd569d2ed5ac9d159a0ea28ab49944d7ac Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:54:46 +0000 Subject: [PATCH 087/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (430 of 430 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Set (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-set-adoc/zh_Hans/ --- .../reference/unordered_set_zh_Hans.adoc | 579 +++++++++--------- 1 file changed, 292 insertions(+), 287 deletions(-) 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..84e6f7f 100644 --- a/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_set_zh_Hans.adoc @@ -1,11 +1,11 @@ [#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"] ----- @@ -238,9 +238,9 @@ namespace unordered { --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== @@ -256,32 +256,32 @@ namespace unordered { |_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. +桶的数量可以通过调用 insert 自动增加,或者作为调用 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. +全局定义此宏以支持加载由 Boost 1.84 之前版本的 Boost 保存到 Boost.Serialization 归档中的 `unordered_set`。 -=== Typedefs +=== 类型定义 [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` 。 --- @@ -290,9 +290,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -301,9 +301,9 @@ The iterator category is at least a forward iterator. 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` 对象可用于遍历单个桶内的元素。 --- @@ -312,9 +312,9 @@ A `local_iterator` object can be used to iterate through a single bucket. 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` 对象可用于遍历单个桶。 --- @@ -323,7 +323,7 @@ A const_local_iterator object can be used to iterate through a single bucket. 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] 模型。 --- @@ -332,7 +332,7 @@ A class for holding extracted container elements, modelling https://en.cpprefere typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -345,33 +345,33 @@ 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(); ``` -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`. +使用 `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`. +explicit unordered_set(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = 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[可默认构造^]要求。 --- -==== Iterator Range Constructor +==== 迭代器范围构造函数 [source,c++,subs="+quotes"] ---- template @@ -382,70 +382,70 @@ 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++ 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`. +构造一个容器,移动 `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"] ---- unordered_set(std::initializer_list il, @@ -455,48 +455,49 @@ 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++ 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`. +构造一个至少包含 `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"] ---- 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"] ---- template @@ -504,97 +505,97 @@ template 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_set(std::initializer_list il, const allocator_type& a); ``` +```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. +使用 `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_set(std::initializer_list il, size_type n, const allocator_type& a); ``` +```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. +构造一个至少包含 `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_set(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```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. +构造一个至少包含 `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_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); ``` +```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++ 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^]. +要求:`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; ``` [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. +返回:指向容器第一个元素的迭代器,若容器为空则返回容器尾后迭代器。 --- @@ -602,7 +603,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:指向容器尾后位置的迭代器。 --- @@ -610,7 +611,7 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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`,若容器为空,则返回容器尾后迭代器。 --- @@ -618,27 +619,27 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回:`size() == 0` --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回:`std::distance(begin(), end())` --- @@ -647,326 +648,330 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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` 处满足对 `X` 的 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^] 要求。返回:若执行了插入,则返回类型中的布尔分量为 `true`。+ + 若执行了插入,则迭代器指向新插入的元素;否则指向等价的元素。 抛出:若调用 `hasher` 以外的操作抛出异常,则函数无效果。 说明:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。+ + 指向元素的指针和引用永远不会失效。 --- ==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +```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. +当且仅当容器中没有等价值的元素时,插入一个使用参数 `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. +要求:`value_type` 需从 `args` 处满足对 `X` 的 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^] 要求。返回:若执行了插入,则迭代器指向新插入的元素;否则指向等价的元素。抛出:若调用 `hasher` 以外的操作抛出异常,则函数无效果。说明:标准对提示的含义表述相当模糊。但使用它的唯一实际方式,也是 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++ 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` 以外的操作抛出异常,则函数无效果。说明:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。+ +指向元素的指针和引用永远不会失效。 --- -==== 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` 是有效的成员 typedef,且 `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); ``` 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. +`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` 以外的操作抛出异常,则函数无效果。说明:标准对提示的含义表述相当模糊。但使用它的唯一实际方式,也是 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. +当且仅当容器中不存在等价键时,将 `obj` 对象插入到容器中。 -`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/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` 以外的操作抛出异常,则函数无效果。说明:标准对提示的含义表述相当模糊。但使用它的唯一实际方式,也是 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. +当且仅当容器中不存在等价键的元素时,插入一个由 `std::forward++<++K++>++(k)` 构造的元素。 -`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^] 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` 以外的操作抛出异常,则函数无效果。说明:标准对 hint 的含义表述相当模糊。但使用它的唯一实际方式,也是 Boost.Unordered 唯一支持的方式,是将其指向具有相同键的现有元素。+ +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。+ +指向元素的指针和引用永远不会失效。+ +此重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `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` 处满足对 `X` 的 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 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); ``` -Removes the element pointed to by `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++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++17 中,通过此方法提取的节点可以插入到兼容的 `unordered_multiset` 中,但该功能尚未支持。+ +`template` 重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 均不能从 `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. + + 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++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. +若 `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` 不产生任何影响.(即 `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()`. + + 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` 以外的操作抛出异常,则函数无效果。说明:标准对 hint 的含义表述相当模糊。但使用它的唯一实际方式,也是 Boost.Unordered 唯一支持的方式,是将其指向具有相同键的现有元素。+ +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。+ +指向元素的指针和引用永远不会失效。+ +该函数可用于插入从兼容的 `unordered_multiset` 中提取的节点。 --- -==== Erase by 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` 方法已被弃用。 --- -==== 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` 抛出异常时才会抛出异常。说明:`template` 重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 均不能从 `K` 隐式转换。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。这实现了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase Range +==== 范围擦除 ```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); ``` -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` 返回指向下一个元素的迭代器开销较大,但容器已经过重新设计,该问题已不复存在。因此,此方法现已弃用。 --- ==== 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` 抛出异常时才会抛出异常。 ++ + 在此实现中,此重载不会调用这两个函数对象的任何方法,因此不会抛出异常,但在其他实现中可能并非如此。 +说明:此方法最初实现的原因是,从 `erase` 返回指向下一个元素的迭代器开销较大,但容器已经过重新设计,该问题已不复存在。因此,此方法现已弃用。 --- -==== 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++ 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. +如果声明了 `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++11 标准并不完全相同。 --- -==== clear +==== 清空 ```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++ 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`. +通过遍历 `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 +==== get++_++allocator ``` allocator_type get_allocator() const; ``` --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:容器的哈希函数。 --- -==== key_eq +==== 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` 成员函数模板。+ +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。说明:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。说明:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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())`。说明:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。这实现了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -=== Bucket Interface +=== 桶接口 -==== bucket_count +==== bucket++_++count ```c++ size_type bucket_count() const noexcept; ``` [horizontal] -Returns:;; The number of buckets. +返回:桶的数量。 --- @@ -974,23 +979,23 @@ Returns:;; The number of buckets. ```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`. +要求:`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()`。说明:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。这实现了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- @@ -999,7 +1004,7 @@ Returns:;; The index of the bucket which would contain an element with key `k`. ```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` 的桶中第一个元素的局部迭代器。 --- @@ -1007,7 +1012,7 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中“尾后”元素的局部迭代器。 --- @@ -1015,7 +1020,7 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中第一个元素的常量局部迭代器。 --- @@ -1023,17 +1028,17 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A consta ```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 +=== 哈希策略 -==== load_factor +==== 负载因子 ```c++ float load_factor() const noexcept; ``` [horizontal] -Returns:;; The average number of elements per bucket. +返回:每个桶的平均元素数量。 --- @@ -1042,51 +1047,51 @@ Returns:;; The average number of elements per bucket. ```c++ float max_load_factor() const noexcept; ``` [horizontal] -Returns:;; Returns the current maximum load factor. +返回:当前最大负载因子。 --- -==== Set max_load_factor +==== 设置max_load_factor(最大负载因子) ```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); ``` -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); ``` -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::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"] @@ -1096,82 +1101,82 @@ template typename std::iterator_traits::value_type; // exposition only ----- -=== Equality Comparisons +=== 相等性比较 ==== operator -```c++ template bool operator==(const unordered_set& x, const unordered_set& y); ``` +```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). +如果 `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); ``` +```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++11 标准并不完全相同。 --- === erase_if -```c++ template typename unordered_set::size_type erase_if(unordered_set& c, Predicate pred); ``` +```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`. +遍历容器 `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(); ``` +返回:被擦除的元素数量。注意:等价于: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` 执行任何修改操作。 From 6290723ed19bd9defbceb0a92fa708634cd4ba70 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:05 +0000 Subject: [PATCH 088/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (51 of 51 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Nav (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-nav-adoc/zh_Hans/ --- doc/modules/ROOT/nav_zh_Hans.adoc | 66 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/doc/modules/ROOT/nav_zh_Hans.adoc b/doc/modules/ROOT/nav_zh_Hans.adoc index 7143f6a..2221eb9 100644 --- a/doc/modules/ROOT/nav_zh_Hans.adoc +++ b/doc/modules/ROOT/nav_zh_Hans.adoc @@ -4,48 +4,48 @@ * 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: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/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/hash_traits.adoc[哈希特征] +** xref:reference/stats.adoc[统计信息] +** 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/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/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/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/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/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/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/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[] +* xref:changes.adoc[变更记录] +* xref:bibliography.adoc[参考文献] +* xref:copyright.adoc[版权声明] From 20ad3e6d5154b598ebfc90f4002ae8d286aaf227 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:54:48 +0000 Subject: [PATCH 089/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (78 of 78 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Regular (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-regular-adoc/zh_Hans/ --- doc/modules/ROOT/pages/regular_zh_Hans.adoc | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/doc/modules/ROOT/pages/regular_zh_Hans.adoc b/doc/modules/ROOT/pages/regular_zh_Hans.adoc index f17b37a..09a185d 100644 --- a/doc/modules/ROOT/pages/regular_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/regular_zh_Hans.adoc @@ -1,11 +1,11 @@ -[#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] ---- @@ -19,7 +19,7 @@ assert(x.at("one") == 1); assert(x.find("missing") == x.end()); ---- -But since the elements aren't ordered, the output of: +但由于元素不按顺序存储,以下代码的输出结果: [source,c++] ---- @@ -28,7 +28,7 @@ for(const map::value_type& i: x) { } ---- -can be in any order. For example, it might be: +可能以任意顺序输出。例如,结果可能为: [source] ---- @@ -37,26 +37,28 @@ one,1 three,3 ---- -There are other differences, which are listed in the xref:regular.adoc#comparison[Comparison with Associative Containers] section. +其他差异列于 xref:regular.adoc#comparison[与关联容器的对比] 章节中。 -== Iterator Invalidation +== 迭代器失效 -It is not specified how member functions other than `rehash` and `reserve` affect the bucket count, although `insert` can only invalidate iterators when the insertion causes the container's load to be greater than the maximum allowed. For most implementations this means that `insert` will only change the number of buckets when this happens. Iterators can be invalidated by calls to `insert`, `rehash` and `reserve`. +标准未明确规定除 `rehash` 和 `reserve` 之外的成员函数如何影响桶数量,但 `insert` 操作仅当导致容器负载超过最大允许值时才会使迭代器失效。在大多数实现中,这意味着 `insert` 仅在此种情况下才会改变桶的数量。迭代器可能因调用 `insert` 、 `rehash` 或 `reserve` 而失效。 -As for pointers and references, they are never invalidated for node-based containers (`boost::unordered_[multi]set`, `boost::unordered_[multi]map`, `boost::unordered_node_set`, `boost::unordered_node_map`), but they will be when rehashing occurs for `boost::unordered_flat_set` and `boost::unordered_flat_map`: this is because these containers store elements directly into their holding buckets, so when allocating a new bucket array the elements must be transferred by means of move construction. +对于基于节点的容器( `boost::unordered++_[++multi++]++set` 、 `boost::unordered++_[++multi++]++map` 、 `boost::unordered++_++node++_++set` 、 `boost::unordered++_++node++_++map` ),其指针和引用永远不会失效。但对于 `boost::unordered++_++flat++_++set` 和 `boost::unordered++_++flat++_++map` ,在发生重哈希时指针和引用将会失效:这是因为这些容器将元素直接存储在桶中,当分配新的桶数组时,必须通过移动构造来转移元素。 -In a similar manner to using `reserve` for ``vector``s, it can be a good idea to call `reserve` before inserting a large number of elements. This will get the expensive rehashing out of the way and let you store iterators, safe in the knowledge that they won't be invalidated. If you are inserting `n` elements into container `x`, you could first call: +与为 `vector` 使用 `reserve` 类似,在插入大量元素之前调用 `reserve` 是一个好主意。这样可以避免代价高昂的重哈希操作,并且让你能够存储迭代器,确信它们不会被失效。如果你要向容器 `x` 插入 `n` 个元素,可以先调用: ``` x.reserve(n); ``` -Note:: `reserve(n)` reserves space for at least `n` elements, allocating enough buckets -so as to not exceed the maximum load factor. + Because the maximum load factor is defined as the number of elements divided by the total number of available buckets, this function is logically equivalent to: + ``` x.rehash(std::ceil(n / x.max_load_factor())) ``` + See the xref:reference/unordered_map.adoc#unordered_map_rehash[reference for more details] on the `rehash` function. +Note:: `reserve(n)` 为至少 `n` 个元素预留空间,分配足够数量的桶, +以确保不超过最大负载因子。由于最大负载因子定义为元素数量除以可用桶的总数,该函数在逻辑上等价于: +```cppx.rehash(std::ceil(n / x.max_load_factor()))``` +有关 `rehash` 函数的更多详细信息,请参阅 xref:reference/unordered_map.adoc#unordered_map_rehash[参考文档]。 [#comparison] :idprefix: comparison_ -== Comparison with Associative Containers +== 与关联容器的对比 [caption=, title='Table {counter:table-counter} Interface differences'] [cols="1,1", frame=all, grid=rows] @@ -80,14 +82,15 @@ so as to not exceed the maximum load factor. + Because the maximum load factor i |`equal_range(k)` returns an empty range at the position that `k` would be inserted if `k` isn't present in the container. |`equal_range(k)` returns a range at the end of the container if `k` isn't present in the container. It can't return a positioned range as `k` could be inserted into multiple place. + -**Closed-addressing containers:** To find out the bucket that `k` would be inserted into use `bucket(k)`. But remember that an insert can cause the container to rehash - meaning that the element can be inserted into a different bucket. +闭散列容器:使用 bucket (k) 可确定键 k 待插入的哈希桶。需注意,插入操作可能触发容器重新哈希,元素最终会被存入其他哈希桶。 |`iterator`, `const_iterator` are of the bidirectional category. |`iterator`, `const_iterator` are of at least the forward category. |Iterators, pointers and references to the container's elements are never invalidated. |xref:regular.adoc#regular_iterator_invalidation[Iterators can be invalidated by calls to insert or rehash]. + -**Node-based containers:** Pointers and references to the container's elements are never invalidated. + **Flat containers:** Pointers and references to the container's elements are invalidated when rehashing occurs. +基于节点的容器:指向容器元素的指针和引用永远不会失效。 +扁平容器:发生重新哈希时,指向容器元素的指针和引用将会失效。 |Iterators iterate through the container in the order defined by the comparison object. |Iterators iterate through the container in an arbitrary order, that can change as elements are inserted, although equivalent elements are always adjacent. From cfd8c2a85ad2c6ef4b1639ff2fa5453bae9e7ce4 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:53:38 +0000 Subject: [PATCH 090/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (447 of 447 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Node Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-node-map-adoc/zh_Hans/ --- .../reference/unordered_node_map_zh_Hans.adoc | 733 +++++++++++------- 1 file changed, 435 insertions(+), 298 deletions(-) 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..ec33e75 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,19 +1,19 @@ [#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"] ----- @@ -279,16 +279,16 @@ namespace unordered { --- -=== 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. +从任何可转换为 `std::pair` 的对象构造并插入容器,并且还必须可以从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除^]。 |_T_ @@ -300,38 +300,38 @@ into the container from any `std::pair` object convertible to it, and it also mu |_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_avalanching[hash_is_avalanching]::value` 为 `true`,则哈希函数将按原样使用;否则,会增加一个位混合后处理阶段,以牺牲额外的计算成本为代价来提高哈希质量。 --- -=== 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. +全局定义此宏可为容器启用 xref:reference/stats.adoc#stats[统计计算]。请注意,此选项会降低许多操作的整体性能。 --- -=== Typedefs +=== 类型定义 [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`。 --- @@ -340,9 +340,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -351,7 +351,7 @@ The iterator category is at least a forward iterator. 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] 模型。 --- @@ -360,7 +360,7 @@ A class for holding extracted container elements, modelling https://en.cpprefere typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -373,33 +373,35 @@ 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(); ``` -Constructs an empty container 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 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"] ---- template @@ -410,72 +412,73 @@ 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++ 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. +如果 `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[`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++ 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. +使用 `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++ 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()`. +如果 `a == other.get_allocator()`,则 `other` 的元素节点会直接转移给新容器;否则,元素将从 `other` 中的元素通过移动构造获得。哈希函数和谓词通过移动构造从 `other` 获得,而分配器则通过拷贝构造从 `a` 获得。如果启用了统计信息(详见 xref:unordered_node_map_boost_unordered_enable_stats[`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++ 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()`. +从 xref:#concurrent_node_map[`concurrent_node_map`] 进行移动构造。`other` 的内部桶数组直接转移给新容器。哈希函数、谓词和分配器通过移动构造从 `other` 获得。如果启用了统计信息(详见 xref:unordered_node_map_boost_unordered_enable_stats[`BOOST_UNORDERED_ENABLE_STATS`]),则从 `other` 转移内部的统计信息,并调用 `other.reset_stats()`。 [horizontal] -Complexity:;; Constant time. Concurrency:;; Blocking on `other`. +复杂度:常数时间。 +并发性:在 `other` 上阻塞。 --- -==== Initializer List Constructor +==== 初始化列表构造函数 [source,c++,subs="+quotes"] ---- unordered_node_map(std::initializer_list il, @@ -485,48 +488,49 @@ 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++ 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. +构造一个至少包含 `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++ 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. +构造一个至少包含 `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"] ---- 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"] ---- template @@ -534,88 +538,92 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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++ unordered_node_map(std::initializer_list il, size_type n, const allocator_type& a); ``` +```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. +使用 `a` 以及默认的哈希函数和键相等谓词,构造一个至少包含 `n` 个桶的空容器,并将 `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(); ``` [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++ 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`. +赋值运算符。销毁之前存在的元素,从 `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[`BOOST_UNORDERED_ENABLE_STATS`]),则当最终分配器与 `other.get_allocator()` 相等时,从 `other` 转移内部的统计信息,并且始终会调用 `other.reset_stats()`。 --- -==== Initializer List Assignment -```c++ unordered_node_map& operator=(std::initializer_list il); ``` +==== 初始化列表赋值 +```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^] +要求:`value_type` 满足 https://en.cppreference.com/w/cpp/named_req/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()`) +返回:指向容器第一个元素的迭代器,如果容器为空则返回容器的尾后迭代器。 +复杂度:O(`bucket_count()`) --- @@ -623,7 +631,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:指向容器尾后值的迭代器。 --- @@ -631,7 +639,8 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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()`) --- @@ -639,13 +648,13 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` @@ -654,7 +663,7 @@ Returns:;; `size() == 0` --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` @@ -668,216 +677,304 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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); ``` +```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++ 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, 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` 可以同等转换为 `value_type&&` 和 `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); +``` +当且仅当容器中没有具有等价键的元素时,才将 `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, 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++ 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. +如果 `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. +返回:一个 `insert_return_type` 对象,由 `position`、`inserted` 和 `node` 构造而成。 +* 若 `nh` 为空,则 `inserted` 为 `false` , `position` 为 `end()` ,且 `node` 为空。 +* 否则,若插入操作发生,则 `inserted` 为 `true` , `position` 指向被插入的元素,且 `node` 为空。 +* 若插入操作失败,则 `inserted` 为 `false` , `node` 保留 `nh` 的原始值,且 `position` 指向与 `nh.key()` 等效的元素。 +若 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入其关联元素。函数返回时 `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.key()`. `nh` becomes empty if insertion took place, otherwise it is not changed. +如果 `nh` 非空,则当且仅当容器中没有键与 `nh.key()` 等价的元素时,才将关联的元素插入容器。如果插入发生,则 `nh` 变为空;否则 `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` 与容器的分配器不相等,则行为未定义。 --- ==== 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); ``` +```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)...)) +```c++ +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. +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `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++ 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. +如果容器中不存在键为 `k` 的元素,则插入一个新元素。 -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. 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:;; 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)...)) +```c++ +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. +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `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); ``` +```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(obj)` 来更新它。 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式为: +```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` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载大于最大负载时才会发生。 + +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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(obj)` 来更新它。 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式为: +```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` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载大于最大负载时才会发生。 + +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase by Position +==== 按位置擦除 [source,c++,subs=+quotes] ---- @@ -885,108 +982,117 @@ _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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== 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). +返回:被擦除元素之后的迭代器——即 `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++ 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. +如果 `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); ``` -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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- ==== 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`. +从 `position` 指向的元素移动构造一个 `init_value` 对象 `x`,擦除该元素并返回 `x`。 --- -==== clear +==== 清空 ```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; ``` [horizontal] -Returns:;; The container's allocator. +返回:容器的分配器。 --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:容器的哈希函数。 --- @@ -994,79 +1100,90 @@ Returns:;; The container's hash function. ``` 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()`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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; ``` +```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())`。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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); ``` +```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(k, mapped_type())`。 +返回:对 `x.second` 的引用,其中 `x` 是容器中已存在的元素,或是新插入的键与 `k` 等价的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载大于最大负载时才会发生。 + +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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. +返回:对 `x.second` 的引用,其中 `x` 是键与 `k` 等价的(唯一)元素。 +抛出:如果不存在这样的元素,则抛出 `std::out_of_range` 类型的异常对象。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -=== 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`. +返回:`static_cast(size())/static_cast(bucket_count())`,如果 `bucket_count() == 0` 则返回 `0`。 --- @@ -1075,15 +1192,15 @@ Returns:;; `static_cast(size())/static_cast(bucket_count())`, or ` ```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`. +效果:不执行任何操作,因为用户不允许更改此参数。保留此函数是为了与 `boost::unordered_map` 保持兼容。 --- @@ -1093,45 +1210,47 @@ Effects:;; Does nothing, as the user is not allowed to change this parameter. Ke ```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); ``` -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); ``` -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; ``` [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[`BOOST_UNORDERED_ENABLE_STATS`] 启用时才可用。 --- @@ -1139,18 +1258,22 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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[`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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1183,80 +1306,94 @@ template 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); ``` +```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). +若 `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); ``` +```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). +若 `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_map& x, unordered_node_map& y) noexcept(noexcept(x.swap(y))); ``` +=== 交换 +```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); ``` +```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::type` 和 `std::remove_const::type` 必须是可序列化的(对于 XML 归档需支持 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::type&&` 和 `std::remove_const::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. +将迭代器(或常量迭代器)`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`. +使迭代器(或常量迭代器)`it` 指向原始迭代器(或常量迭代器)被保存到归档(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` 执行任何修改操作。 From bf4b263c2d00cce7af18c4d55fc4aa5574b1b12a Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:07 +0000 Subject: [PATCH 091/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Node Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-node-map-adoc/zh_Hans/ --- .../pages/reference/header_unordered_node_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..9bb5c40 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,9 +1,9 @@ [#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. +定义 xref:reference/unordered_node_map.adoc#unordered_node_map[boost::unordered_node_map] 及相关函数和别名模板。 [listing,subs="+macros,+quotes"] ----- From 7d4a343d34a5785b33c2e63911cefd8c54c8d7b8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:16 +0000 Subject: [PATCH 092/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (301 of 301 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Changes (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-changes-adoc/zh_Hans/ --- doc/modules/ROOT/pages/changes_zh_Hans.adoc | 724 ++++++++++---------- 1 file changed, 362 insertions(+), 362 deletions(-) diff --git a/doc/modules/ROOT/pages/changes_zh_Hans.adoc b/doc/modules/ROOT/pages/changes_zh_Hans.adoc index a6297f3..c5b4702 100644 --- a/doc/modules/ROOT/pages/changes_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/changes_zh_Hans.adoc @@ -1,392 +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: -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`. +== 版本 1.89.0 + +* 已弃用的 boost::unordered::hash_is_avalanching 现在是 +在 中对 boost::hash_is_avalanching 的使用声明。请直接使用该头文件代替。 将在未来被移除。 +* 为开放寻址容器新增 `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 + +* 当头文件 `` 可用时,新增容器 `pmr` 别名。 `boost::unordered::pmr::[container]` 别名指向使用 `std::pmr::polymorphic_allocator` 分配器类型的 `boost::unordered::[container]` 。 +* 为开放寻址容器与并发容器增设内部统计功能,可计算并提供受哈希函数质量影响的统计指标。通过全局宏 `BOOST_UNORDERED_ENABLE_STATS` 启用。 +* 雪崩哈希函数现在必须通过内嵌 `value` 常量设为 `true` 的 `is_avalanching` typedef 来标记(通常将 `is_avalanching` 定义为 `std::true_type`)。 `using is_avalanching = void` 已被弃用,但为了向后兼容性仍予保留。 +* 为容器和迭代器添加 Visual Studio Natvis 框架的自定义可视化功能。此功能适用于所有使用原始指针分配器的容器。在此版本中,若容器或迭代器的分配器使用花式指针,则暂不支持该功能,此问题可能在后续版本中解决。 + +== 版本 1.85.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 分配器在共享内存中构建容器等应用场景。 +这使得像使用 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` and `boost::unordered_flat_set`。 +(基于开放寻址的) +* 为所有容器添加 CTAD 推导指引。 +* 补充 https://cplusplus.github.io/LWG/issue2713[LWG 问题 2713] 中要求的缺失构造函数。 + +== 版本 1.80.0 - 重大更新 + +* 重构内部实现以显著提升性能 +* 允许 使用 `final` 修饰的 Hasher 和 KeyEqual 对象 +* 更新文档,新增性能基准对比图及关于新内部数据结构的说明 +(数据结构) + +== 版本 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。 + +== 版本 1.67.0 + +* 增强 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 中提供。 + +== 版本 1.63.0 + +* 检查 `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 个参数。 + +== 版本 1.62.0 + +* 停止使用已弃用的 `boost::iterator` 组件 。 +* 移除 `BOOST_NO_STD_DISTANCE` 的兼容性代码。 +* 移除 `BOOST_UNORDERED_DEPRECATED_EQUALITY` 警告。 +* 采用更简化的赋值操作实现,修复了 +`unordered_multiset` 与 `unordered_multimap` 的异常安全问题,但性能可能略有下降。 +* 停止使用返回值SFINAE技术,以避免部分旧版本编译器的 +兼容性问题。 + +== 版本 1.58.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])。 + +== 版本 1.57.0 + +* 修复迭代器中 `pointer` 类型定义的问题(https://svn.boost.org/trac/boost/ticket/10672[#10672])。 +* 修复 Coverity 警告 +(https://github.com/boostorg/unordered/pull/2[GitHub #2])。 + +== 版本 1.56.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 标准规定,仅使用分配器构造元素。 + +== 版本 1.55.0 + +* 避免部分警告(https://svn.boost.org/trac/boost/ticket/8851[#8851] 、 https://svn.boost.org/trac/boost/ticket/8874[#8874])。 +* 避免通过迭代器上的 ADL 暴露部分细节函数。 +* 遵循标准规范,仅使用分配器的 construct 和 destroy +方法来构造和析构存储的元素,不将其用于指针等内部数据的操作。 + +== 版本 1.54.0 + +* 为标准中指定的方法标注 `noexcept` 。更多方法将在下一 +版本中更新。 +* 若已知哈希函数与相等性谓词均具备无抛出 +移动赋值或移动构造特性,则使用它们。 + +== 版本 1.53.0 + +* 移除对旧式变参 pair 构造函数和 +相等性实现的支持,这两项功能自 Boost 1.48 起已被弃用。 +* 停止使用已弃用的配置宏。 +* 更多内部实现变更,包括采用更简化的 +`erase` 方法 实现。 -== Release 1.52.0 +== 版本 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. +* 加速赋值操作:尽可能复用现有节点进行赋值, +而非创建全新节点并执行复制构造。 +* 修复 `erase_range` 方法中的缺陷(https://svn.boost.org/trac/boost/ticket/7471[#7471])。 +* 回退部分关于节点创建机制的内部变更(尤其 +针对 C{plus}{plus}11 编译器),使 'construct' 和 'destroy' 对 C{plus}{plus}11 分配器更有效。 +* 简化实现,以提高健壮性。 + +== 版本 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` 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`. +* `emplace` 方法原先模拟了 +早期 C{plus}{plus}0x 草案中的变参 pair 构造函数。由于该特性已被移除,现不再提供此模拟实现。当前仅模拟新的 `piecewise_construct` pair 构造函数,但需使用 `boost::piecewise_construct` 作为参数。若需启用旧版变参构造函数的模拟行为,请定义宏 `BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT` 。 -== Release 1.45.0 +== 版本 1.45.0 -* Fix a bug when inserting into an `unordered_map` or `unordered_set` using -iterators which returns `value_type` by copy. +* 修复了在使用返回 `value_type` 副本的迭代器插入 `unordered_map` 或 `unordered_set` 时的一个错误。 +(使用返回 `value_type` 副本) -== Release 1.43.0 +== 版本 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. +* 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_*` 系列宏。 -== Release 1.42.0 +== 版本 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. +* 支持使用不完整值类型来实例化容器。 +* 减少编译警告数量(主要出现在测试中)。 +* 提升 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 字符。 -== Release 1.41.0 - Major update +== 版本 1.41.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. +* 初始版本曾大量使用 +宏来规避旧式编译器薄弱的模板支持能力。鉴于现已不再支持这些编译器,且宏的使用逐渐成为维护负担,现将实现类重构为使用模板替代宏。 -* 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. +* 通过 `boost::compressed_pair` 实现 EBO 及微调函数缓冲区 +(现使用 bool 替代成员指针),容器对象的内存占用得以减小。 + +* 桶采用延迟分配机制,这意味着构造空容器时 +不会分配任何内存。 -== Release 1.40.0 +== 版本 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. +* 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 特性提供优化方案,以应对头文件不可用的情况。 +* 默认创建更少的桶。 -== Release 1.39.0 +== 版本 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. +* https://svn.boost.org/trac/boost/ticket/2756[问题单 2756] :规避 +Visual C{plus}{plus} 2009 的编译警告。 +* 对实现、测试及文档进行其他少量内部调整。 +(文档) +* 避免 `operator[]` 中不必要的复制。 +* https://svn.boost.org/trac/boost/ticket/2975[问题单 2975] :修正 +质数列表长度。 -== Release 1.38.0 +== 版本 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). +* 使用 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 模式)。 -== Release 1.37.0 +== 版本 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. +* 将带提示的 `emplace` 重载更名为 `emplace++_++hint` 。 +(根据 http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2691.pdf[n2691^] 规范) +* 在 `` 与 +`` 路径下提供前向声明头文件。 +* 将所有实现移至 `boost/unordered` 内,以支持 +模块化并便于跟踪发布版本。 -== Release 1.36.0 +== 版本 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. +* 调整内部结构。 +* 移动语义:在支持右值引用的环境中提供完整支持,否则 +使用精简版 Adobe 移动库进行模拟实现。 +* 支持右值引用和变参模板时提供就地构造支持。 +* 节点分配效率更高(当右值引用和变参模板 +可用时)。 +* 新增相等性判断运算符。 -== Boost 1.35.0 Add-on - 31st March 2008 +== Boost 1.35.0 附加版本 - 2008年3月31日 -Unofficial release uploaded to vault, to be used with Boost 1.35.0. Incorporated many of the suggestions from the review. +非官方版本已上传至资源库,适用于 Boost 1.35.0。该版本已采纳评审阶段的多项改进建议。 -* 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. +* 通过 Boost 回归测试,代码可移植性得到显著提升。 +* 修正文档中的多处笔误,并优化文本表述以提升可读性。 +* 修复根据最大负载因子计算容器大小时,浮点数到 `std::size_t` 的转换问题, +并在计算过程中使用 `double` 类型来提高精度。 +* 修正示例中的部分错误。 + +== 评审版本 + +初始评审版本(评审时间:2007年12月7日至12月16日)。 From cfc0e88b4c723d1a6cf6c70128be44c0c6ed88dc Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:19 +0000 Subject: [PATCH 093/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (31 of 31 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Compliance (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-compliance-adoc/zh_Hans/ --- .../ROOT/pages/compliance_zh_Hans.adoc | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc index b895e29..5d1331b 100644 --- a/doc/modules/ROOT/pages/compliance_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/compliance_zh_Hans.adoc @@ -1,21 +1,21 @@ [#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` 为支持 {cpp}11 或更高版本的编译器提供了符合最新标准修订版中 {cpp} 无序关联容器规范的实现,仅有极少量的已知偏差。这些容器完全遵循 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++] ---- @@ -26,7 +26,7 @@ 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++] ---- @@ -35,36 +35,36 @@ x.emplace( 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++ 标准目前并未提供任何可供遵循的开放定址容器规范,因此 `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++ 标准中尚未针对此类或任何其他类型的并发数据结构提供规范。`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++] ---- @@ -72,7 +72,7 @@ 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++] ---- @@ -80,15 +80,15 @@ 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++] ---- 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`] 实现替代(该方式更为复杂)。 //- From b5b72588111c6b8b7a0d71fd4ba3756eea672705 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:25 +0000 Subject: [PATCH 094/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (34 of 34 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Hash Equality (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-hash-equality-adoc/zh_Hans/ --- .../ROOT/pages/hash_equality_zh_Hans.adoc | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc index 4835af9..c15a31c 100644 --- a/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/hash_equality_zh_Hans.adoc @@ -2,59 +2,59 @@ :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 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: +哈希函数放在首位,因为你可能只想更改哈希函数而不想更改相等谓词。例如,如果你想使用 https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a 哈希^],可以这样写: -```cpp boost::unordered_map dictionary; ``` +```cpp boost::unordered_map dictionary; ``` -There is an link:../../../examples/fnv1.hpp[implementation of FNV-1a^] in the examples directory. +examples 目录中有一个链接:../../../examples/fnv1.hpp[implementation of 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()); } }; +```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; +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; ``` +然后你可以在不区分大小写的字典中使用它:```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. +这是 link:../../../examples/case_insensitive.hpp[/libs/unordered/examples/case_insensitive.hpp^] 处示例的简化版本,该示例支持其他区域设置和字符串类型。 -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. +CAUTION: 在使用自定义相等谓词时,请谨慎使用相等(==)运算符 +在使用自定义相等谓词(特别是函数指针)时请务必小心。如果你用不同的相等谓词比较两个容器,结果是未定义的。对于大多数无状态函数对象而言,这种情况不可能发生——因为你只能使用相同的相等谓词来比较对象,所以两个相等谓词必然相等。但如果你使用的是函数指针或有状态的相等谓词(例如 boost::function),则可能会遇到问题。 -== 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; } +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; } }; +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; ``` +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:../../../../container_hash/index.html[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; } +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; } +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] From 457b78033f7744fd895d41260cb45064bae99a96 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:10 +0000 Subject: [PATCH 095/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Node Set Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-node-set-fwd-adoc/zh_Hans/ --- .../reference/header_unordered_node_set_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..5467c1b 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++>++`] 中的所有定义。 From c8ff3d39b048533fe50663986eb4c68664b792aa Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:52 +0000 Subject: [PATCH 096/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Flat Set Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-flat-set-fwd-adoc/zh_Hans/ --- .../reference/header_concurrent_flat_set_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..059036a 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++>++`] 中的所有定义。 From cf8689f703a7b640e5e265cd06a205622264b2e8 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:51:29 +0000 Subject: [PATCH 097/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (489 of 489 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-map-adoc/zh_Hans/ --- .../reference/unordered_map_zh_Hans.adoc | 777 ++++++++++-------- 1 file changed, 448 insertions(+), 329 deletions(-) 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..066cf79 100644 --- a/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/reference/unordered_map_zh_Hans.adoc @@ -1,11 +1,11 @@ [#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"] ----- @@ -279,9 +279,9 @@ namespace unordered { --- -=== Description +=== 描述 -*Template Parameters* +*模板参数* [cols="1,1"] |=== @@ -300,32 +300,32 @@ namespace unordered { |_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. +桶的数量可以通过调用 insert 自动增加,或者作为调用 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. +全局定义此宏以支持加载由 Boost 1.84 之前版本的 Boost 保存到 Boost.Serialization 归档中的 `unordered_map`。 -=== Typedefs +=== 类型定义 [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` 。 --- @@ -334,9 +334,9 @@ Convertible to `const_iterator`. 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. +迭代器类别至少为前向迭代器。 --- @@ -345,9 +345,9 @@ The iterator category is at least a forward iterator. 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` 对象可用于遍历单个桶内的元素。 --- @@ -356,9 +356,9 @@ A `local_iterator` object can be used to iterate through a single bucket. 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` 对象可用于遍历单个桶。 --- @@ -367,7 +367,7 @@ A const_local_iterator object can be used to iterate through a single bucket. 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] 模型。 --- @@ -376,7 +376,7 @@ A class for holding extracted container elements, modelling https://en.cpprefere typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +一个内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -389,33 +389,35 @@ 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(); ``` -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`. +使用 `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"] ---- template @@ -426,70 +428,71 @@ 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++ explicit unordered_map(Allocator const& a); ``` -Constructs an empty container, using allocator `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"] ---- unordered_map(std::initializer_list il, @@ -499,48 +502,49 @@ 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++ 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`. +构造一个至少包含 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"] ---- 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"] ---- template @@ -548,95 +552,95 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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++ 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. +使用 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++ unordered_map(std::initializer_list il, size_type n, const hasher& hf, const allocator_type& a); ``` +```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. +构造一个至少包含 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(); ``` [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); ``` +```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. +如果 `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++ 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. +如果 `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; ``` [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. +返回:指向容器第一个元素的迭代器,如果容器为空则返回容器的尾后迭代器。 --- @@ -644,7 +648,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:指向容器尾后值的迭代器。 --- @@ -652,7 +656,7 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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`,如果容器为空则返回容器的尾后值。 --- @@ -660,27 +664,27 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回:`size() == 0`。 --- -==== size +==== 大小 ```c++ size_type size() const noexcept; ``` [horizontal] -Returns:;; `std::distance(begin(), end())` +返回:`std::distance(begin(), end())`。 --- @@ -689,372 +693,463 @@ Returns:;; `std::distance(begin(), end())` ```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++ 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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 返回:如果发生了插入,则返回类型的 bool 分量为 true。 +如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 指向元素的指针和引用永远不会失效。 +如果 `args...` 的形式为 `k,v`,则该函数会延迟构造整个对象,直到确定应该插入元素为止,仅使用 `k` 参数进行检查。当映射的 `key_type` 可移动构造或 `k` 参数本身就是 `key_type` 类型时,此优化生效。 --- ==== emplace_hint -```c++ template iterator emplace_hint(const_iterator position, Args&&... args); ``` +```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` 出发在 `X` 中进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^]。 返回:如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 Boost.Unordered 支持的唯一方式,是将其指向一个具有相同键的已存在元素。 +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 +如果 `args...` 的形式为 `k,v`,则该函数会延迟构造整个对象,直到确定应该插入元素为止,仅使用 `k` 参数进行检查。当映射的 `key_type` 可移动构造或 `k` 参数本身就是 `key_type` 类型时,此优化生效。 --- -==== 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[可拷贝插入^]。 +返回:返回类型的 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 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[可移动插入^]。 +返回:返回类型的 bool 分量为 true 表示发生了插入。 +如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 --- -==== Emplace Insert -```c++ template std::pair insert(P&& obj); ``` +==== 原地插入 +```c++ template std::pair insert(P&& obj); ``` -Inserts an element into the container by performing `emplace(std::forward

(value))`. +通过执行 `emplace(std::forward

(value))` 向容器中插入一个元素。

-Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅当 std::is_constructible::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. +返回:返回类型的 bool 分量为 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);``` +当且仅当容器中没有具有等价键的元素时,才将 `obj` 插入容器。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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. +当且仅当容器中没有具有等价键的元素时,才将 `obj` 插入容器。 -`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/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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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))`. +通过执行 `emplace_hint(hint, std::forward

(value))` 向容器中插入一个元素。

-Only participates in overload resolution if `std::is_constructible::value` is `true`. +仅当 std::is_constructible::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. +返回:如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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` 出发在 `X` 中进行 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 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) ``` +```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_map_emplace[emplace] except the `value_type` is constructed using: + + -- ```c++ +返回:返回类型的 bool 分量为 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. -- +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `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++ 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. +如果容器中不存在键为 `k` 的元素,则插入一个新元素。 -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. +`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. +标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 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. -- +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `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); ``` +```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(obj)` 来更新它。 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式为: +```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. +返回:返回类型的 bool 分量为 true 表示发生了插入。 +如果发生了插入,则迭代器指向新插入的元素;否则,指向具有等价键的元素。 +抛出:如果除调用 `hasher` 之外的操作抛出异常,则该函数无效果。 +注意:可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 + +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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(obj)` 来更新它。 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式为: +```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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 Boost.Unordered 支持的唯一方式,是将其指向一个具有相同键的已存在元素。 +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 指向元素的指针和引用永远不会失效。 +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Extract by Iterator +==== 通过迭代器提取 ```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++ 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_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` 中。 +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `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++ iterator insert(const_iterator hint, 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` 所拥有的元素。 -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` 无影响(即 `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()`. + + 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` 之外的操作抛出异常,则该函数无效果。 +注意:标准关于 `hint` 的含义表述相当模糊。但唯一实际的使用方式,也是 Boost.Unordered 支持的唯一方式,是将其指向一个具有相同键的已存在元素。 +可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +指向元素的指针和引用永远不会失效。 +此函数可用于插入从兼容的 `unordered_multimap` 中提取的节点。 --- -==== Erase by 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 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` 抛出异常时才会抛出。 +注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 都不能从 `K` 隐式转换时参与重载决议。库假定 `Hash` 可同时使用 `K` 和 `Key` 调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型对象的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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); ``` -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` 返回下一个元素的迭代器开销较大,但容器已经过重新设计,情况不再如此。因此,此方法现已废弃。 --- ==== 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` 抛出异常时才会抛出异常。 + +在此实现中,此重载不会调用任一函数对象的方法,因此不会抛出异常,但在其他实现中可能并非如此。 + +备注:;; 之所以实现此方法,是因为从 `erase` 返回下一个元素的迭代器开销较大,但容器已经过重新设计,情况不再如此。因此,此方法现已废弃。 --- -==== 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++11 标准不完全相同,因为相等谓词和哈希函数是通过它们的复制构造函数进行交换的。 --- -==== clear +==== 清空 ```c++ void clear(); ``` -Erases all elements in the container. +清除容器中的所有元素。 [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` 并提取 `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` 可能具有不同的哈希函数和键相等谓词,因此 `source` 中每个节点的键都将使用 `this->hash_function()` 重新计算哈希值,然后根据需要再使用 `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; ``` --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The container's hash function. +返回:;; 容器的哈希函数。 --- @@ -1062,69 +1157,81 @@ Returns:;; The container's hash function. ``` 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` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `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` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `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` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `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; ``` +```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` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `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); ``` +```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(k, mapped_type())`。 +返回:;; 指向 `x.second` 的引用,其中 `x` 是容器中已存在的元素,或者是键与 `k` 等价的新插入元素。 +抛出:;; 如果除调用 `hasher` 之外的操作抛出异常,则该函数无效。 +备注:;; 可能使迭代器失效,但仅当插入导致负载因子大于或等于最大负载因子时才会发生。 +此外,指向元素的指针和引用永远不会失效。 +另外,仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `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. +返回:;; 指向 `x.second` 的引用,其中 `x` 是键与 `k` 等价的(唯一)元素。 +抛出:;; 如果不存在这样的元素,则抛出 `std::out_of_range` 类型的异常对象。 +备注:;; 仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 类型调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型的开销。 --- -=== Bucket Interface +=== 桶接口 ==== bucket_count ```c++ size_type bucket_count() const noexcept; ``` [horizontal] -Returns:;; The number of buckets. +返回:;; 桶的数量。 --- @@ -1132,23 +1239,25 @@ Returns:;; The number of buckets. ```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`. +要求:;; `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` 是有效的成员 typedef 时,`template` 重载才会参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 类型调用,且 `Pred` 是透明的。这支持了异构查找,从而避免了实例化 `Key` 类型的开销。 --- @@ -1157,7 +1266,8 @@ Returns:;; The index of the bucket which would contain an element with key `k`. ```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` 的桶中第一个元素的局部迭代器。 --- @@ -1165,7 +1275,8 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中“尾后”元素的局部迭代器。 --- @@ -1173,7 +1284,8 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A local ```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` 的桶中第一个元素的常量局部迭代器。 --- @@ -1181,17 +1293,18 @@ Requires:;; `n` shall be in the range `[0, bucket_count())`. Returns:;; A consta ```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 +=== 哈希策略 -==== load_factor +==== 负载因子 ```c++ float load_factor() const noexcept; ``` [horizontal] -Returns:;; The average number of elements per bucket. +返回:;; 每个桶的平均元素个数。 --- @@ -1200,53 +1313,56 @@ Returns:;; The average number of elements per bucket. ```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. +效果:;; 改变容器的最大负载因子,以 `z` 作为提示。 --- -==== 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. +改变桶的数量,使得至少包含 `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); ``` -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::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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1279,80 +1395,83 @@ template 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); ``` +```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). +如果 `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); ``` +```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++ template void swap(unordered_map& x, unordered_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:;; 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++11 标准不完全相同,因为相等谓词和哈希函数是通过它们的复制构造函数进行交换的。 --- === erase_if -```c++ template typename unordered_map::size_type erase_if(unordered_map& c, Predicate pred); ``` +```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::type` 和 `std::remove_const::type` 必须是可序列化的(支持 XML 序列化),并且它们支持 Boost.Serialization 的 `save_construct_data`/`load_construct_data` 协议(该协议由 https://en.cppreference.com/w/cpp/named_req/DefaultConstructible[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` 中插入由 `ar` 所读取存储中保存的原始 `unordered_map` `other` 元素的恢复副本。 [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::type&&, std::remove_const::type&&)` 进行 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[EmplaceConstructible^]。`x.key_equal()` 在功能上等价于 `other.key_equal()`。 +注意:;; 如果归档是使用 Boost 1.84 之前的 Boost 版本保存的,则必须全局定义配置宏 `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` 指向保存到由归档(XML 归档)`ar` 读取的存储中的原始 `iterator`(`const_iterator`)的被恢复位置。 [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` 执行任何修改操作。 From 69caad8cc0a1dd018d838409929b47484cf87dc3 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:08 +0000 Subject: [PATCH 098/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (217 of 217 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Benchmarks (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-benchmarks-adoc/zh_Hans/ --- .../ROOT/pages/benchmarks_zh_Hans.adoc | 150 +++++++++--------- 1 file changed, 75 insertions(+), 75 deletions(-) diff --git a/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc index c3d2c6e..a6cca2f 100644 --- a/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/benchmarks_zh_Hans.adoc @@ -1,23 +1,23 @@ [#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^]. +所有基准测试均使用 `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 -==== Insertion +==== 插入 [caption=] [cols="3*^.^a", frame=all, grid=all] @@ -27,7 +27,7 @@ The unsuccessful lookup benchmarks use `n` randomly generated integers but using |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] @@ -37,11 +37,11 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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] @@ -51,18 +51,18 @@ h|non-duplicate elements, + prior `reserve` h|duplicate elements, + prior `reser |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] @@ -72,11 +72,11 @@ h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 |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] @@ -86,13 +86,13 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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 -==== Insertion +==== 插入 [caption=] [cols="3*^.^a", frame=all, grid=all] @@ -102,7 +102,7 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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 |=== @@ -114,11 +114,11 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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] @@ -128,18 +128,18 @@ h|non-duplicate elements, + prior `reserve` h|duplicate elements, + prior `reser |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] @@ -149,11 +149,11 @@ h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 |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] @@ -163,13 +163,13 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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 -==== Insertion +==== 插入 [caption=] [cols="3*^.^a", frame=all, grid=all] @@ -179,7 +179,7 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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 |=== @@ -191,11 +191,11 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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] @@ -205,18 +205,18 @@ h|non-duplicate elements, + prior `reserve` h|duplicate elements, + prior `reser |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] @@ -226,11 +226,11 @@ h|by key, duplicate elements h|by key, duplicate elements, + max load factor 5 |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] @@ -240,28 +240,28 @@ h|non-duplicate elements h|duplicate elements h|duplicate elements, + max load f |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 -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` +* `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^]. +源代码可 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 @@ -276,7 +276,7 @@ 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|未命中查找 |=== @@ -292,7 +292,7 @@ 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|未命中查找 |=== @@ -308,7 +308,7 @@ 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|未命中查找 |=== @@ -324,7 +324,7 @@ 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|未命中查找 |=== @@ -340,7 +340,7 @@ 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|未命中查找 |=== @@ -356,7 +356,7 @@ 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|未命中查找 |=== @@ -372,24 +372,24 @@ 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 -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^]` +* `https://github.com/greg7mdp/gtl/blob/main/docs/phmap.md[gtl::parallel_flat_hash_map^]` (含64个子映射) +* `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^]. +源代码可 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 @@ -402,7 +402,7 @@ The benchmarks exercise a number of threads _T_ (between 1 and 16) concurrently |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] @@ -412,7 +412,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -425,7 +425,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -435,7 +435,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -448,7 +448,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -458,7 +458,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -471,7 +471,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -481,7 +481,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -494,7 +494,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -504,7 +504,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -517,7 +517,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -527,7 +527,7 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 @@ -540,7 +540,7 @@ h|5M updates, 45M lookups + skew=0.01 h|5M updates, 45M lookups + skew=0.5 h|5M |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] @@ -550,4 +550,4 @@ h|500k updates, 4.5M lookups + skew=0.01 h|500k updates, 4.5M lookups + skew=0.5 |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 |=== From b059a41b80848f66821910abb855428caea19150 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:26 +0000 Subject: [PATCH 099/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (17 of 17 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Hash Quality (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-hash-quality-adoc/zh_Hans/ --- .../ROOT/pages/hash_quality_zh_Hans.adoc | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc index 3e6efee..bc0648d 100644 --- a/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/hash_quality_zh_Hans.adoc @@ -1,16 +1,16 @@ -[#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++] ---- @@ -25,11 +25,11 @@ 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++] ---- @@ -48,7 +48,7 @@ int main() } ---- -The `stats` object provides the following information: +`stats` 对象提供以下统计信息: [source,subs=+quotes] ---- @@ -81,14 +81,14 @@ 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: +提供了一个链接:../../../benchmark/string_stats.cpp[示例^],用于展示 `boost::hash`、https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash[FNV-1a 哈希^] 以及两种行为不当但被错误标记为具有雪崩效应的自定义哈希函数的容器统计信息。 [listing] ---- From 66153a4f7510649f800c5e188633ed671d7bb6a9 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:46 +0000 Subject: [PATCH 100/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (499 of 499 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Concurrent Node Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-concurrent-node-map-adoc/zh_Hans/ --- .../concurrent_node_map_zh_Hans.adoc | 789 ++++++++++-------- 1 file changed, 436 insertions(+), 353 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 6a7fcdc..004cfde 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,15 +1,15 @@ -[#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"] ----- @@ -337,16 +337,16 @@ namespace unordered { --- -=== 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. +`std::pair` 对象 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[原地构造] 到容器中,并且必须支持从容器中 https://en.cppreference.com/w/cpp/named_req/Erasable[擦除] 。 |_T_ @@ -358,71 +358,71 @@ into the table from any `std::pair` object convertible to it, and it also must b |_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]::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::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. +通常而言,若 `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` -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` -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] ---- 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] 。 --- @@ -431,7 +431,7 @@ A class for holding extracted table elements, modelling https://en.cppreference. typedef _implementation-defined_ insert_return_type; ---- -A specialization of an internal class template: +内部类模板的特化: [source,c++,subs=+quotes] ---- @@ -443,41 +443,43 @@ struct _insert_return_type_ // name is exposition only }; ---- -with `NodeType` = `node_type`. +其中 `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. +内部用于 xref:concurrent_node_map_bulk_visit[批量访问] 操作的块大小。 --- -=== 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. +构造一个空哈希表,使用 `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"] ---- template @@ -488,84 +490,86 @@ 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++ 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. +构造一个以 `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++ 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`. +构造一个哈希表,复制 `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++ concurrent_node_map(unordered_node_map&& other); ``` +```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()`. +通过 xref:#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"] ---- concurrent_node_map(std::initializer_list il, @@ -575,48 +579,50 @@ 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++ 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. +构造一个至少包含 `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"] ---- 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"] ---- template @@ -624,176 +630,191 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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_map(std::initializer_list il, const allocator_type& a); ``` +```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. +构造一个使用分配器 `a`、默认哈希函数和默认键相等谓词的空哈希表,并将 `il` 中的元素插入其中。 [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); ``` +```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. +构造一个至少包含 `n` 个桶的空哈希表,使用分配器 `a`、默认哈希函数和默认键相等谓词,并将 `il` 中的元素插入其中。 [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); ``` +```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(); ``` [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); ``` +```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`. +赋值运算符。销毁已存在的所有元素,从 `other` 复制赋值哈希函数和谓词;若 `Alloc::propagate_on_container_copy_assignment` 存在且其值为 `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` 存在且其值为 `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++ 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` 重载版本才会参与重载决议。库假定 `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 reference to `x`. Such reference is const iff `*this` is const. +对范围 [`first`, `last`) 中的每个元素 `k`,若容器内存在键与 `k` 等价的元素 `x`,则以 `x` 的引用调用函数 `f`。当且仅当 `*this` 为常量时,该引用为常量引用。 -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. +尽管功能上等同于对每个键单独调用 `[c]visit`,但得益于内部的流式优化,批量访问通常性能更高。建议当 `std::distance(first,last)` 至少达到 `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` 是前向迭代器(C++11 至 C++17),或满足 C++20 及之后标准的 `std::forward_iterator` 概念。 +对于 `K = std::iterator_traits::value_type`,要么 `K` 是 `key_type`,要么 `Hash::is_transparent` 和 `Pred::is_transparent` 是合法的成员别名。 +在后一种情况下,库假定 `Hash` 可同时接收 `K` 与 `Key` 类型调用,且 `Pred` 是透明的。这支持异构查找,避免了实例化 `Key` 类型对象的开销。 +返回值:;; 被访问的元素总数。 --- ==== [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 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++17 并行算法的编译器中可用。 +仅当 `std::is_execution_policy_v>` 为 `true` 时,这些重载版本才参与重载决议。 +不允许使用无序执行策略。 --- ==== [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++ 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++17 并行算法的编译器中可用。 +仅当 `std::is_execution_policy_v>` 为 `true` 时,这些重载版本才参与重载决议。 +不允许使用无序执行策略。 +并行化意味着:一旦 `f` 返回 `false`,执行流程**不一定会立即终止**,因此 `f` 可能还会被继续用于后续元素,且这些调用的返回值同样为 `false`。 --- -=== Size and Capacity +=== 大小与容量 -==== empty +==== 空 ```c++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回值:;; `size() == 0`(容器为空时返回 true,否则返回 false) --- -==== 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. +注意:;; 在存在并发插入操作时,返回的值可能无法精确反映函数执行完成后哈希表的真实大小。 --- @@ -802,411 +823,461 @@ Notes:;; In the presence of concurrent insertion operations, the value returned ```c++ size_type max_size() const noexcept; ``` [horizontal] -Returns:;; `size()` of the largest possible table. +返回值:;; 哈希表能容纳的最大元素数量(最大容量)。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template bool emplace(Args&&... args); ``` +==== 原地构造 +```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:;; 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`。 +并发特性:;; 当对当前对象执行重哈希操作时会阻塞。 +注意:;; 若 `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[CopyInsertable^] 要求。返回值:;; 成功执行插入操作则返回 `true`。并发特性:;; 对当前对象执行重哈希操作时会发生阻塞。注意:;; 若调用形式为 `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[MoveInsertable^] 要求。 +返回值:;; 成功执行插入操作则返回 `true`。 +并发特性:;; 对当前对象执行重哈希操作时会发生阻塞。 +注意:;; 若调用形式为 `insert(x)`,且 `x` 可同时转换为 `value_type&&` 与 `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++ size_type insert(std::initializer_list il); ``` -Equivalent to [listing,subs="+macros,+quotes"] +等价于 [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` 的原值。 +若 `nh` 非空,则当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入关联元素。函数返回时 `nh` 为空。 --- ==== emplace_or_[c]visit -```c++ template bool emplace_or_visit(Args&&... args, F&& f); template bool emplace_or_cvisit(Args&&... args, F&& f); ``` +```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`。 +并发特性:;; 对当前对象执行重哈希操作时会发生阻塞。 +注意:;; 该接口仅为说明性接口,因为C++不允许在可变参数包之后声明参数 `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[CopyInsertable^] 要求。 +返回值:;; 成功执行插入操作则返回 `true`。 +并发特性:;; 对当前对象执行重哈希操作时会发生阻塞。 +注意:;; 在形式为 `insert_or_[c]visit(obj, f)` 的调用中,仅当 `std::remove_cv::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:;; 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[MoveInsertable^] 要求。 +返回值:;; 成功执行插入操作则返回 `true`。 +并发特性:;; 对当前对象执行重哈希操作时会发生阻塞。 +注意:;; 在形式为 `insert_or_[c]visit(obj, f)` 的调用中,仅当 `std::remove_reference::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` 的原值。 +若 `nh` 为空,则不执行任何操作。否则,当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入其关联的元素;否则,以等价元素的引用为参数调用 `f` ;当且仅当使用 `insert++_++or++_++cvisit` 时该引用为常量引用。 --- ==== 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); ``` +```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++ 不允许在可变参数包之后声明参数 `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:;; 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[CopyInsertable^] 要求。 +返回值:;; 若执行插入操作则返回 `true`。 +并发特性:;; 阻塞对 `*this` 的重哈希操作。 +注意:;; 在形式为 `insert_and_[c]visit(obj, f1, f2)` 的调用中,仅当 `std::remove_cv::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[MoveInsertable^] 要求。 +返回值:;; 若执行插入操作则返回 `true`。 +并发特性:;; 阻塞对 `*this` 的重哈希操作。 +注意:;; 在形式为 `insert_and_[c]visit(obj, f1, f2)` 的调用中,仅当 `std::remove_reference::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++ 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_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`时,该引用为常量引用。 [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` 的原值。 +若 `nh` 为空,则不执行任何操作。否则,当且仅当容器中不存在键等价于 `nh.key()` 的元素时,插入关联元素,并以新插入元素的非常量引用为参数调用 `f1` ;否则,以等价元素的引用为参数调用 `f2` ;当且仅当使用 `insert++_++or++_++cvisit` (此处应为 `insert++_++and++_++cvisit` ,可能是英文出了点错误)时该引用为常量引用。 --- ==== 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); ``` +```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;否则,构造方式如下: // 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. +与 xref:#concurrent_node_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 这个重载版本才会参与重载决议。 +库实现假定 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); ``` +```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;否则,构造方式如下: // 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. +该接口仅为说明性用法,因为 C++ 不允许在可变参数包之后声明参数 `f`。 -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. +仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员类型别名时,`template` 这些重载版本才会参与重载决议。库假定 `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); ``` +```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;否则,构造方式如下: // 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. +该接口仅为说明性用法,因为 C++ 不允许在可变参数包之后声明 `f1` 和 `f2` 参数。 -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. +仅当 `Hash::is_transparent` 和 `Pred::is_transparent` 为有效成员类型别名时,`template` 这些重载版本才会参与重载决议。 +库假定 `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); ``` +```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(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))) +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` 才参与重载决议。库假定 `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` 重载版本才参与重载决议。库假定 `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` 的非常量引用。 +`template` 重载版本仅在 `std::is_execution_policy_v>` 为 `false` 时参与重载决议。 +`template` 重载版本仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 为有效成员类型别名时参与重载决议。库假定 `Hash` 可同时接受 `K` 类型与 `Key` 类型作为参数,且 `Pred` 是透明的。这支持异构查找,从而避免实例化 `Key` 类型对象带来的性能开销。 --- ==== erase_if -```c++ template size_type erase_if(F f); ``` +```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++17 并行算法的编译器中可用。该重载版本仅在`std::is_execution_policy_v>` 为 `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++ 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. +若声明了 `Allocator::propagate_on_container_swap` 且其值为 `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` 重载版本才参与重载决议。库假定 `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` 重载版本才参与重载决议。库假定 `Hash` 可同时接受 `K` 类型与 `Key` 类型作为参数,且 `Pred` 是透明的。这支持异构查找,从而避免实例化 `Key` 类型对象带来的性能开销。 --- -==== 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`. +后置条件:;; `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++ 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`. +将源容器 `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; ``` [horizontal] -Returns:;; The table's allocator. +返回值:;; 表的分配器。 --- -==== hash_function +==== 哈希函数 ``` hasher hash_function() const; ``` [horizontal] -Returns:;; The table's hash function. +返回值:;; 表的哈希函数。 --- @@ -1214,103 +1285,112 @@ Returns:;; The table's hash function. ``` 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` 重载版本才参与重载决议。库假定 `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` 重载版本才参与重载决议。库假定 `Hash` 可同时接受 `K` 类型与 `Key` 类型作为参数,且 `Pred` 是透明的。这支持异构查找,从而避免实例化 `Key` 类型对象带来的性能开销。 +在存在并发插入操作的情况下,返回的值可能无法精确反映执行后容器的真实状态。 --- -=== 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`. +返回值:;; `static_cast(size()) / static_cast(bucket_count())`;若 `bucket_count() == 0`,则返回 `0`。 --- -==== max_load_factor +==== 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`. +效果:;; 不执行任何操作,因为不允许用户修改此参数。保留该函数是为了与 `boost::unordered_map` 保持兼容。 --- -==== max_load +==== 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. +返回值:;; 表在不进行重哈希的情况下可容纳的最大元素数量(假设不会再删除任何元素)。 +注意:;; 构造、重哈希或清空后,表的最大装载量至少为 `max_load_factor() * bucket_count()`。在高负载条件下执行删除操作时,该数值可能会降低。 +在存在并发插入操作的情况下,返回的值可能无法精确反映执行后容器的真实状态。 --- -==== 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. +效果:;; 必要时调整桶数组的大小,使桶数量至少为 `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`。 -==== 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; ``` [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]. +返回值:;; 表截至目前执行的插入和查找操作的统计信息描述。 +注意:;; 仅当启用了**统计信息计算**功能时可用。 --- @@ -1318,18 +1398,19 @@ Returns:;; A statistical description of the insertion and lookup operations perf ```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[statistics calculation] 被 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. +- 该推导指引包含 `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__ +==== _iter-value-type_ [listings,subs="+macros,+quotes"] ----- template @@ -1362,32 +1443,34 @@ template 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); ``` +```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). +若 `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); ``` +```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); ----- @@ -1395,29 +1478,29 @@ 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); ``` +```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` 。 From 6efda377ee868d15087f9cabf1924c0b46b285ef Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:02 +0000 Subject: [PATCH 101/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Flat Set Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-flat-set-fwd-adoc/zh_Hans/ --- .../reference/header_unordered_flat_set_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..711be2d 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++>++`] 中的所有定义。 From 313544b66d7c0c0e419308652471e5a7be141198 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:08 +0000 Subject: [PATCH 102/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Node Map Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-node-map-fwd-adoc/zh_Hans/ --- .../reference/header_unordered_node_map_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..64a8c15 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++>++`] 中的所有定义。 From e44355fe5b475f66233b1e25a027c18d21b82b75 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:21 +0000 Subject: [PATCH 103/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (416 of 416 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Unordered Flat Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-unordered-flat-map-adoc/zh_Hans/ --- .../reference/unordered_flat_map_zh_Hans.adoc | 582 +++++++++--------- 1 file changed, 291 insertions(+), 291 deletions(-) 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..54a74d4 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,19 +1,19 @@ [#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"] ----- @@ -271,16 +271,16 @@ namespace unordered { --- -=== 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. +`std::pair` 必须能从任何可转换为它的 `std::pair` 对象满足对容器的 https://en.cppreference.com/w/cpp/named_req/EmplaceConstructible[可原位构造^] 要求,并且还必须满足对容器的 https://en.cppreference.com/w/cpp/named_req/Erasable[可擦除^] 要求。 |_T_ @@ -292,38 +292,38 @@ namespace unordered { |_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] ---- 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` 。 --- @@ -332,33 +332,33 @@ Convertible to `const_iterator`. 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(); ``` -Constructs an empty container 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 unordered_flat_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ``` +==== 桶数构造函数 +```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. +构造一个至少包含 `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"] ---- template @@ -369,75 +369,75 @@ 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++ 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()`. +移动构造函数。`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++ 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. +使用 `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++ explicit unordered_flat_map(Allocator const& a); ``` -Constructs an empty container, using allocator `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"] ---- unordered_flat_map(std::initializer_list il, @@ -447,48 +447,48 @@ 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. +unordered_flat_map(size_type n, hasher const& hf, allocator_type const& 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"] ---- 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"] ---- template @@ -496,88 +496,88 @@ Requires:;; `hasher`, `key_equal` need to be https://en.cppreference.com/w/cpp/n 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++ 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. +构造一个空容器,使用 `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++ 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. +构造一个至少包含 `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++ 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. +构造一个至少包含 `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(); ``` [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); ``` +```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`. +赋值操作符。该操作会销毁容器中原有的元素,并从 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; ``` [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()`) --- @@ -585,7 +585,7 @@ Returns:;; An iterator referring to the first element of the container, or if th ```c++ iterator end() noexcept; const_iterator end() const noexcept; ``` [horizontal] -Returns:;; An iterator which refers to the past-the-end value for the container. +返回:指向容器尾后位置的迭代器。 --- @@ -593,7 +593,7 @@ Returns:;; An iterator which refers to the past-the-end value for the container. ```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()`) --- @@ -601,219 +601,219 @@ Returns:;; A `const_iterator` referring to the first element of the container, o ```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++ [[nodiscard]] bool empty() const noexcept; ``` [horizontal] -Returns:;; `size() == 0` +返回: `size() == 0` --- -==== size +==== 大小 ```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; ``` [horizontal] -Returns:;; `size()` of the largest possible container. +返回:可能的最大容器的 `size()`。 --- -=== Modifiers +=== 修改器 -==== emplace -```c++ template std::pair emplace(Args&&... args); ``` +==== 原地构造 +```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. +当且仅当容器中没有等价的键时,插入一个使用参数 `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. + + 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` 可同等转换为 `value_type&&` 和 `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. +==== 带提示的复制插入 +`iterator insert(const_iterator hint, const value_type& obj); iterator insert(const_iterator hint, const init_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. + + 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++ 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` 以外的操作抛出异常,则函数无效果。注意:可能使迭代器、指针和引用失效,但仅当插入导致负载大于最大负载时才会发生。 --- -==== 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_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. +`template` 重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 均不能从 `K` 隐式转换。库假定 `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++ 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. +如果容器中不存在键为 `k` 的元素,则向容器中插入一个新元素。 -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. 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:;; 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. +`template` 重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 均不能从 `K` 隐式转换。库假定 `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(obj) 来更新该元素 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式如下:```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` 以外的操作抛出异常,则函数无效果。注意:可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。+ +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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(obj) 来更新该元素 -If there is no such element, it is added to the container as: ```c++ +如果不存在这样的元素,则将其添加到容器中,形式如下:```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` 以外的操作抛出异常,则函数无效果。注意:可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。+ +`template` 仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。这提供了异构查找能力,从而避免构造 `Key` 类型实例的开销。 --- -==== Erase by Position +==== 通过位置擦除 [source,c++,subs=+quotes] ---- @@ -821,247 +821,247 @@ _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` 抛出异常时才会抛出异常。注意:`template` 重载仅在以下条件下参与重载决议:`Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef,且 `iterator` 和 `const_iterator` 均不能从 `K` 隐式转换。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。这提供了异构查找能力,从而避免构造 `Key` 类型实例的开销。 --- -==== Erase Range +==== 范围擦除 ```c++ iterator erase(const_iterator first, const_iterator last); ``` -Erases the elements in the range from `first` to `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); ``` -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; ``` -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_flat_map& source); template void merge(unordered_flat_map&& source); ``` +==== 合并 +```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`. +尝试将 `source` 中所有键尚未出现在 `*this` 内的元素移动插入到 `*this` 中,同时将这些元素从 `source` 移除。 --- -=== Observers +=== 观察器 -==== get_allocator +==== 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++_++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()`。注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 等价的元素数量。注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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` 的元素。注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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. +返回:一个布尔值,指示容器中是否存在键等于 `key` 的元素。注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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(k, mapped_type())`。返回:对 `x.second` 的引用,其中 `x` 是容器中已存在的元素,或键与 `k` 等价的新插入元素。抛出:如果调用 `hasher` 以外的操作抛出异常,则该函数无效果。注意:可能会导致迭代器、指针和引用失效,但仅当插入操作导致负载因子超过最大负载因子时才会发生。+ +`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `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. +返回:对 `x.second` 的引用,其中 `x` 是键与 `k` 等价的(唯一)元素。抛出:如果不存在这样的元素,则抛出 `std::out_of_range` 类型的异常对象。注意:`template` 重载仅在 `Hash::is_transparent` 和 `Pred::is_transparent` 是有效的成员 typedef 时参与重载决议。库假定 `Hash` 可同时以 `K` 和 `Key` 调用,且 `Pred` 是透明的。该机制支持异构查找,从而避免实例化 `Key` 类型的开销。 --- -=== 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`. +返回:`static_cast(size())/static_cast(bucket_count())`,若 `bucket_count() == 0` 则返回 `0`。 --- -==== max_load_factor +==== 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`. +效果:不执行任何操作,因为用户不允许更改此参数。为与 `boost::unordered_map` 保持兼容而保留。 --- -==== max_load +==== 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 的前提下,容器所能容纳的最大元素数量(假设不会有更多元素被擦除)。注意:在构造、rehash 或清空之后,容器的最大负载至少为 `max_load_factor() * bucket_count()`。在高负载条件下,该值可能因擦除操作而减小。 --- -==== 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. +如有必要,将改变桶数组的大小,使其至少包含 `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); ``` -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, 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 +==== 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]. +返回:对容器迄今为止执行的插入和查找操作的统计描述。注意:仅当 xref:reference/stats.adoc#stats[统计计算] 被 xref:unordered_flat_map_boost_unordered_enable_stats[启用] 时可用。 --- -==== reset_stats +==== 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"] @@ -1096,80 +1096,80 @@ 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); ``` +```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); ``` +```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++ 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`. +遍历容器 `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. +返回:被擦除的元素数量。注意:等价于:`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::type 和 std::remove_const::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` 执行任何修改操作。 From 8722ec655d01d53cc7a462b34d6be3296660d9a9 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:29 +0000 Subject: [PATCH 104/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (45 of 45 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Rationale (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-rationale-adoc/zh_Hans/ --- doc/modules/ROOT/pages/rationale_zh_Hans.adoc | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/doc/modules/ROOT/pages/rationale_zh_Hans.adoc b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc index db2db06..4f8f5d5 100644 --- a/doc/modules/ROOT/pages/rationale_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/rationale_zh_Hans.adoc @@ -2,78 +2,78 @@ :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++ 标准中对无序关联容器的规范对允许的实现方式施加了严格的限制,其中最重要的一点是隐式假定使用闭地址法。稍微放宽这一规范,则为提供能够充分利用开放寻址技术的容器变体开辟了可能性。 -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 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. +当使用直接适合开放定址的哈希函数时,可以通过专用的 `link:../../../../container_hash/doc/html/hash.html#ref_hash_is_avalanching[hash_is_avalanching]` 特征来退出后混合操作。针对字符串类型的 `boost::hash` 特化已被标记为雪崩式哈希。 -=== 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 开放寻址容器做出了相同的决策并提供了相同的保证。 From 8a95e41f917e0da02834823461bd8ab73ffb3810 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:49:54 +0000 Subject: [PATCH 105/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Concurrent Node Map Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-concurrent-node-map-fwd-adoc/zh_Hans/ --- .../reference/header_concurrent_node_map_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..a8b0129 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++>++`] 中的所有定义。 From 0aaf17c2c9960c31f12168651595a5ac04c676c2 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:10 +0000 Subject: [PATCH 106/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (7 of 7 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Bibliography (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-bibliography-adoc/zh_Hans/ --- doc/modules/ROOT/pages/bibliography_zh_Hans.adoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc b/doc/modules/ROOT/pages/bibliography_zh_Hans.adoc index 020d3c0..4c4b0b4 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++ Users Journal_. February, 2006. Pete Becker. http://www.ddj.com/cpp/184402066[STL and TR1: :第三部分 — 无序容器^] 。 + +关于标准无序容器的介绍性文章。 +* __维基百科__中的 https://en.wikipedia.org/wiki/Hash_table[哈希表^] 。 + +这是关于哈希表实现原理的概述,重点探讨了链地址法和开放地址法两种实现路径的差异。 +* Peter Dimov,2022年。 https://pdimov.github.io/articles/unordered_dev_plan.html[Boost.Unordered库开发计划^] 。 From 6623f0da5eb7b18ec6712788224a7d2a404c2f05 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:03 +0000 Subject: [PATCH 107/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Map (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-map-adoc/zh_Hans/ --- .../ROOT/pages/reference/header_unordered_map_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..318cf06 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,9 +1,9 @@ [#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"] ----- From 17b3923d59c0aed3a6f81d952e68bece4a8aaf05 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:22 +0000 Subject: [PATCH 108/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (10 of 10 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Copyright (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-copyright-adoc/zh_Hans/ --- doc/modules/ROOT/pages/copyright_zh_Hans.adoc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 。) From d3e0e7c075a6af796c9c2ccb01f888c0ce17b17a Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:46:12 +0000 Subject: [PATCH 109/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (53 of 53 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Buckets (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-buckets-adoc/zh_Hans/ --- doc/modules/ROOT/pages/buckets_zh_Hans.adoc | 44 ++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/doc/modules/ROOT/pages/buckets_zh_Hans.adoc b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc index 0b7c2a0..ceef73e 100644 --- a/doc/modules/ROOT/pages/buckets_zh_Hans.adoc +++ b/doc/modules/ROOT/pages/buckets_zh_Hans.adoc @@ -1,35 +1,35 @@ [#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] |=== -2+^h| *All containers* h|*Method* h|*Description* +2+^h| *所有容器* h|*方法* h|*描述* |`size_type bucket_count() const` |The number of buckets. -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. @@ -40,7 +40,7 @@ In open-addressing containers, buckets can hold at most one element; if a collis |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`. +1.6+|返回编号为 `n` 的桶的起始与末尾迭代器。 |`local_iterator end(size_type n)` @@ -54,23 +54,23 @@ In open-addressing containers, buckets can hold at most one element; if a collis |=== -== 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] |=== -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). @@ -86,16 +86,16 @@ You can't control the bucket count directly but there are two ways to influence |`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* +2+^h| *仅限开放寻址与并发容器* h|*方法* h|*描述* |`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. +关于开放寻址与并发容器的 `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为保持性能稳定而采取的内部机制,用户在规划无重组插入操作时需予以考虑。 From 7d24dd1c7437c235c4814c38c9394eb4a74e546b Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:13 +0000 Subject: [PATCH 110/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (3 of 3 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Set Fwd (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-set-fwd-adoc/zh_Hans/ --- .../pages/reference/header_unordered_set_fwd_zh_Hans.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..0be97ba 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++>++`] 中的所有定义。 From 27b3a7b29e1310f34e5c97d96356f43e33356074 Mon Sep 17 00:00:00 2001 From: Boost-Weblate Admin Date: Fri, 5 Jun 2026 18:50:14 +0000 Subject: [PATCH 111/111] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (2 of 2 strings) Translation: Boost Unordered Translation (zh_Hans)/Doc / Modules / Root / Pages / Reference / Header Unordered Set Top (adoc) Translate-URL: https://insights.cppalliance.org/weblate/projects/boost-unordered-documentation-zh_Hans/doc-modules-root-pages-reference-header-unordered-set-top-adoc/zh_Hans/ --- .../ROOT/pages/reference/header_unordered_set_top_zh_Hans.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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..f64dd68 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,5 +1,5 @@ [#header_unordered_set_fwd_top] -== `` Synopsis +== `++<++boost/unordered++_++set.hpp++>++` 概要 :idprefix: header_unordered_set_top_