documented proxy erase(iterator)

This commit is contained in:
joaquintides
2023-06-15 14:42:56 +02:00
committed by Christian Mazakas
parent 2f7bba0c21
commit 2b6cfe4f3c
6 changed files with 51 additions and 33 deletions

View File

@@ -10,6 +10,10 @@
* Added `boost::concurrent_flat_map`, a fast, thread-safe hashmap based on open addressing. * Added `boost::concurrent_flat_map`, a fast, thread-safe hashmap based on open addressing.
* Sped up iteration of open-addressing containers. * 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 == Release 1.82.0 - Major update

View File

@@ -135,7 +135,9 @@ The main differences with C++ unordered associative containers are:
* In general: * In general:
** `begin()` is not constant-time. ** `begin()` is not constant-time.
** `erase(iterator)` returns `void` instead of an iterator to the following element. ** `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`). ** 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, ** 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. exposed through the public function `max_load`, may decrease on erasure under high-load conditions.

View File

@@ -17,7 +17,6 @@ a number of aspects from that of `boost::unordered_flat_map`/`std::unordered_fla
- `value_type` must be move-constructible. - `value_type` must be move-constructible.
- Pointer stability is not kept under rehashing. - Pointer stability is not kept under rehashing.
- `begin()` is not constant-time. - `begin()` is not constant-time.
- `erase(iterator)` returns `void`.
- There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - 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. - The maximum load factor of the container is managed internally and can't be set by the user.
@@ -155,9 +154,9 @@ namespace boost {
template<class K, class M> template<class K, class M>
iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj); iterator xref:#unordered_flat_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj);
void xref:#unordered_flat_map_erase_by_position[erase](iterator position); _implementation-defined_ xref:#unordered_flat_map_erase_by_position[erase](iterator position);
void xref:#unordered_flat_map_erase_by_position[erase](const_iterator position); _implementation-defined_ 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); size_type xref:#unordered_flat_map_erase_by_key[erase](const key_type& k);
template<class K> size_type xref:#unordered_flat_map_erase_by_key[erase](K&& k); template<class K> 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); 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) void xref:#unordered_flat_map_swap[swap](unordered_flat_map& other)
@@ -1035,15 +1034,19 @@ The `template<class K, class M>` only participates in overload resolution if `Ha
==== Erase by Position ==== Erase by Position
```c++ [source,c++,subs=+quotes]
void erase(iterator position); ----
void erase(const_iterator position); _implementation-defined_ erase(iterator position);
``` _implementation-defined_ erase(const_iterator position);
----
Erase the element pointed to by `position`. Erase the element pointed to by `position`.
[horizontal] [horizontal]
Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator`
immediately following `position` prior to the erasure.
Throws:;; Nothing. Throws:;; Nothing.
Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`.
--- ---

View File

@@ -17,7 +17,6 @@ a number of aspects from that of `boost::unordered_flat_set`/`std::unordered_fla
- `value_type` must be move-constructible. - `value_type` must be move-constructible.
- Pointer stability is not kept under rehashing. - Pointer stability is not kept under rehashing.
- `begin()` is not constant-time. - `begin()` is not constant-time.
- `erase(iterator)` returns `void`.
- There is no API for bucket handling (except `bucket_count`) or node extraction/insertion. - 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. - The maximum load factor of the container is managed internally and can't be set by the user.
@@ -123,9 +122,9 @@ namespace boost {
template<class InputIterator> void xref:#unordered_flat_set_insert_iterator_range[insert](InputIterator first, InputIterator last); template<class InputIterator> 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<value_type>); void xref:#unordered_flat_set_insert_initializer_list[insert](std::initializer_list<value_type>);
void xref:#unordered_flat_set_erase_by_position[erase](iterator position); _implementation-defined_ xref:#unordered_flat_set_erase_by_position[erase](iterator position);
void xref:#unordered_flat_set_erase_by_position[erase](const_iterator position); _implementation-defined_ 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); size_type xref:#unordered_flat_set_erase_by_key[erase](const key_type& k);
template<class K> size_type xref:#unordered_flat_set_erase_by_key[erase](K&& k); template<class K> 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); 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) void xref:#unordered_flat_set_swap[swap](unordered_flat_set& other)
@@ -846,15 +845,19 @@ Notes:;; Can invalidate iterators, pointers and references, but only if the inse
==== Erase by Position ==== Erase by Position
```c++ [source,c++,subs=+quotes]
void erase(iterator position); ----
void erase(const_iterator position); _implementation-defined_ erase(iterator position);
``` _implementation-defined_ erase(const_iterator position);
----
Erase the element pointed to by `position`. Erase the element pointed to by `position`.
[horizontal] [horizontal]
Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator`
immediately following `position` prior to the erasure.
Throws:;; Nothing. Throws:;; Nothing.
Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`.
--- ---

View File

@@ -13,7 +13,6 @@ As a result of its using open addressing, the interface of `boost::unordered_nod
a number of aspects from that of `boost::unordered_map`/`std::unordered_map`: a number of aspects from that of `boost::unordered_map`/`std::unordered_map`:
- `begin()` is not constant-time. - `begin()` is not constant-time.
- `erase(iterator)` returns `void`.
- There is no API for bucket handling (except `bucket_count`). - 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 factor of the container is managed internally and can't be set by the user.
@@ -156,9 +155,9 @@ namespace boost {
template<class K, class M> template<class K, class M>
iterator xref:#unordered_node_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj); iterator xref:#unordered_node_map_insert_or_assign_with_hint[insert_or_assign](const_iterator hint, K&& k, M&& obj);
void xref:#unordered_node_map_erase_by_position[erase](iterator position); _implementation-defined_ xref:#unordered_node_map_erase_by_position[erase](iterator position);
void xref:#unordered_node_map_erase_by_position[erase](const_iterator position); _implementation-defined_ 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); size_type xref:#unordered_node_map_erase_by_key[erase](const key_type& k);
template<class K> size_type xref:#unordered_node_map_erase_by_key[erase](K&& k); template<class K> 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); 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) void xref:#unordered_node_map_swap[swap](unordered_node_map& other)
@@ -1105,15 +1104,19 @@ The `template<class K, class M>` only participates in overload resolution if `Ha
==== Erase by Position ==== Erase by Position
```c++ [source,c++,subs=+quotes]
void erase(iterator position); ----
void erase(const_iterator position); _implementation-defined_ erase(iterator position);
``` _implementation-defined_ erase(const_iterator position);
----
Erase the element pointed to by `position`. Erase the element pointed to by `position`.
[horizontal] [horizontal]
Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator`
immediately following `position` prior to the erasure.
Throws:;; Nothing. Throws:;; Nothing.
Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`.
--- ---

View File

@@ -13,7 +13,6 @@ As a result of its using open addressing, the interface of `boost::unordered_nod
a number of aspects from that of `boost::unordered_set`/`std::unordered_set`: a number of aspects from that of `boost::unordered_set`/`std::unordered_set`:
- `begin()` is not constant-time. - `begin()` is not constant-time.
- `erase(iterator)` returns `void`.
- There is no API for bucket handling (except `bucket_count`). - 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 factor of the container is managed internally and can't be set by the user.
@@ -124,9 +123,9 @@ namespace boost {
insert_return_type xref:#unordered_node_set_insert_node[insert](node_type&& nh); 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); iterator xref:#unordered_node_set_insert_node_with_hint[insert](const_iterator hint, node_type&& nh);
void xref:#unordered_node_set_erase_by_position[erase](iterator position); _implementation-defined_ xref:#unordered_node_set_erase_by_position[erase](iterator position);
void xref:#unordered_node_set_erase_by_position[erase](const_iterator position); _implementation-defined_ 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); size_type xref:#unordered_node_set_erase_by_key[erase](const key_type& k);
template<class K> size_type xref:#unordered_node_set_erase_by_key[erase](K&& k); template<class K> 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); 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) void xref:#unordered_node_set_swap[swap](unordered_node_set& other)
@@ -919,15 +918,19 @@ Notes:;; Behavior is undefined if `nh` is not empty and the allocators of `nh` a
==== Erase by Position ==== Erase by Position
```c++ [source,c++,subs=+quotes]
void erase(iterator position); ----
void erase(const_iterator position); _implementation-defined_ erase(iterator position);
``` _implementation-defined_ erase(const_iterator position);
----
Erase the element pointed to by `position`. Erase the element pointed to by `position`.
[horizontal] [horizontal]
Returns:;; An opaque object implicitly convertible to the `iterator` or `const_iterator`
immediately following `position` prior to the erasure.
Throws:;; Nothing. Throws:;; Nothing.
Notes:;; The opaque object returned must only be discarded or immediately converted to `iterator` or `const_iterator`.
--- ---