forked from boostorg/unordered
@@ -9,6 +9,7 @@
|
||||
== Release 1.86.0
|
||||
|
||||
* Added container `pmr` aliases when header `<memory_resource>` 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`.
|
||||
|
||||
== Release 1.85.0
|
||||
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace boost {
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using stats = xref: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_;
|
||||
|
||||
@@ -228,6 +230,10 @@ namespace boost {
|
||||
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
|
||||
@@ -407,6 +413,15 @@ a function visiting elements of `m`) are detected and signalled through `BOOST_A
|
||||
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:#stats[statistics calculation] for the table. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Constants
|
||||
|
||||
```cpp
|
||||
@@ -488,6 +503,8 @@ 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`.
|
||||
@@ -536,6 +553,9 @@ 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`.
|
||||
@@ -551,6 +571,8 @@ concurrent_flat_map(unordered_flat_map<Key, T, Hash, Pred, Allocator>&& 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()`)
|
||||
@@ -709,6 +731,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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`.
|
||||
@@ -1480,6 +1505,30 @@ 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: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: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:
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ namespace boost {
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using stats = xref: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_;
|
||||
|
||||
@@ -188,6 +190,10 @@ namespace boost {
|
||||
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
|
||||
@@ -358,6 +364,15 @@ a function visiting elements of `m`) are detected and signalled through `BOOST_A
|
||||
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:#stats[statistics calculation] for the table. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Constants
|
||||
|
||||
```cpp
|
||||
@@ -439,6 +454,8 @@ 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`.
|
||||
@@ -487,6 +504,9 @@ 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`.
|
||||
@@ -502,6 +522,8 @@ concurrent_flat_set(unordered_flat_set<Key, Hash, Pred, Allocator>&& 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()`)
|
||||
@@ -659,6 +681,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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`.
|
||||
@@ -1316,6 +1341,30 @@ 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: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: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:
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
[#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 = void; // instruct Boost.Unordered to not use post-mixing
|
||||
|
||||
std::size_t operator()(const std::string& x) const
|
||||
{
|
||||
...
|
||||
}
|
||||
};
|
||||
----
|
||||
|
||||
By setting the
|
||||
xref:#hash_traits_hash_is_avalanching[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 <boost/unordered/unordered_map.hpp>
|
||||
|
||||
...
|
||||
|
||||
int main()
|
||||
{
|
||||
boost::unordered_flat_map<std::string, int, my_string_hash> 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_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.
|
||||
|
||||
A link:../../benchmark/string_stats.cpp[example^] is provided that displays container
|
||||
statistics for `boost::hash<std::string>`, 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
|
||||
----
|
||||
@@ -102,7 +102,7 @@ and *high* and *low* are the upper and lower halves of an extended word, respect
|
||||
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 by via a dedicated <<hash_traits_hash_is_avalanching,`hash_is_avalanching`>>trait.
|
||||
When using a hash function directly suitable for open addressing, post-mixing can be opted out of via a dedicated <<hash_traits_hash_is_avalanching,`hash_is_avalanching`>>trait.
|
||||
`boost::hash` specializations for string types are marked as avalanching.
|
||||
|
||||
=== Platform Interoperability
|
||||
|
||||
@@ -6,6 +6,7 @@ include::unordered_multimap.adoc[]
|
||||
include::unordered_set.adoc[]
|
||||
include::unordered_multiset.adoc[]
|
||||
include::hash_traits.adoc[]
|
||||
include::stats.adoc[]
|
||||
include::unordered_flat_map.adoc[]
|
||||
include::unordered_flat_set.adoc[]
|
||||
include::unordered_node_map.adoc[]
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
[#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: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_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_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 xref:hash_traits_hash_is_avalanching[__avalanching__].
|
||||
|
||||
---
|
||||
@@ -58,6 +58,8 @@ namespace boost {
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
|
||||
using stats = xref: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,
|
||||
@@ -214,6 +216,10 @@ namespace boost {
|
||||
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
|
||||
@@ -343,6 +349,15 @@ at the expense of extra computational cost.
|
||||
|
||||
---
|
||||
|
||||
=== Configuration Macros
|
||||
|
||||
==== `BOOST_UNORDERED_ENABLE_STATS`
|
||||
|
||||
Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
@@ -439,6 +454,8 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -481,6 +498,9 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -493,6 +513,8 @@ unordered_flat_map(concurrent_flat_map<Key, T, Hash, Pred, Allocator>&& 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.
|
||||
@@ -651,6 +673,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -1364,6 +1389,32 @@ Invalidates iterators, pointers and references, and changes the order of element
|
||||
[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: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: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:
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ namespace boost {
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
|
||||
using stats = xref: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,
|
||||
@@ -172,6 +174,10 @@ namespace boost {
|
||||
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
|
||||
@@ -291,6 +297,15 @@ at the expense of extra computational cost.
|
||||
|
||||
---
|
||||
|
||||
=== Configuration Macros
|
||||
|
||||
==== `BOOST_UNORDERED_ENABLE_STATS`
|
||||
|
||||
Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
@@ -387,6 +402,8 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -429,6 +446,9 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -441,6 +461,8 @@ unordered_flat_set(concurrent_flat_set<Key, Hash, Pred, Allocator>&& 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.
|
||||
@@ -599,6 +621,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -1137,6 +1162,32 @@ Invalidates iterators, pointers and references, and changes the order of element
|
||||
[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: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: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:
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ namespace boost {
|
||||
using node_type = _implementation-defined_;
|
||||
using insert_return_type = _implementation-defined_;
|
||||
|
||||
using stats = xref: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,
|
||||
@@ -217,6 +219,10 @@ namespace boost {
|
||||
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
|
||||
@@ -345,6 +351,15 @@ at the expense of extra computational cost.
|
||||
|
||||
---
|
||||
|
||||
=== Configuration Macros
|
||||
|
||||
==== `BOOST_UNORDERED_ENABLE_STATS`
|
||||
|
||||
Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
@@ -472,6 +487,8 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -514,6 +531,9 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -668,6 +688,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -1451,6 +1474,32 @@ 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: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: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:
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ namespace boost {
|
||||
using node_type = _implementation-defined_;
|
||||
using insert_return_type = _implementation-defined_;
|
||||
|
||||
using stats = xref: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,
|
||||
@@ -176,6 +178,10 @@ namespace boost {
|
||||
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
|
||||
@@ -294,6 +300,15 @@ at the expense of extra computational cost.
|
||||
|
||||
---
|
||||
|
||||
=== Configuration Macros
|
||||
|
||||
==== `BOOST_UNORDERED_ENABLE_STATS`
|
||||
|
||||
Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note
|
||||
that this option decreases the overall performance of many operations.
|
||||
|
||||
---
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
@@ -424,6 +439,8 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -466,6 +483,9 @@ 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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -620,6 +640,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h
|
||||
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()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -1228,6 +1251,32 @@ 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: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: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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user