forked from boostorg/unordered
added insert_and_visit and similar operations to concurrent containers (#283)
This commit is contained in:
@@ -169,6 +169,27 @@ namespace boost {
|
||||
template<class F> size_type xref:#concurrent_flat_map_insert_initializer_list_or_visit[insert_or_visit](std::initializer_list<value_type> il, F f);
|
||||
template<class F> size_type xref:#concurrent_flat_map_insert_initializer_list_or_visit[insert_or_cvisit](std::initializer_list<value_type> il, F f);
|
||||
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_visit](Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_emplace_and_cvisit[emplace_and_cvisit](Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_visit](const value_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_cvisit](const value_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_visit](const init_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_copy_insert_and_cvisit[insert_and_cvisit](const init_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_visit](value_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_cvisit](value_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_visit](init_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool xref:#concurrent_flat_map_move_insert_and_cvisit[insert_and_cvisit](init_type&& obj, F1 f1, F2 f2);
|
||||
template<class InputIterator,class F1, class F2>
|
||||
size_type xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_visit](InputIterator first, InputIterator last, F1 f1, F2 f2);
|
||||
template<class InputIterator,class F1, class F2>
|
||||
size_type xref:#concurrent_flat_map_insert_iterator_range_and_visit[insert_and_cvisit](InputIterator first, InputIterator last, F1 f1, F2 f2);
|
||||
template<class F1, class F2>
|
||||
size_type xref:#concurrent_flat_map_insert_initializer_list_and_visit[insert_and_visit](std::initializer_list<value_type> il, F1 f1, F2 f2);
|
||||
template<class F1, class F2>
|
||||
size_type xref:#concurrent_flat_map_insert_initializer_list_and_visit[insert_and_cvisit](std::initializer_list<value_type> il, F1 f1, F2 f2);
|
||||
|
||||
template<class... Args> bool xref:#concurrent_flat_map_try_emplace[try_emplace](const key_type& k, Args&&... args);
|
||||
template<class... Args> bool xref:#concurrent_flat_map_try_emplace[try_emplace](key_type&& k, Args&&... args);
|
||||
template<class K, class... Args> bool xref:#concurrent_flat_map_try_emplace[try_emplace](K&& k, Args&&... args);
|
||||
@@ -186,6 +207,19 @@ namespace boost {
|
||||
template<class K, class... Args, class F>
|
||||
bool xref:#concurrent_flat_map_try_emplace_or_cvisit[try_emplace_or_cvisit](K&& k, Args&&... args, F&& f);
|
||||
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](const key_type& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](const key_type& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](key_type&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](key_type&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class K, class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_visit](K&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class K, class... Args, class F1, class F2>
|
||||
bool xref:#concurrent_flat_map_try_emplace_and_cvisit[try_emplace_and_cvisit](K&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
|
||||
template<class M> bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](const key_type& k, M&& obj);
|
||||
template<class M> bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](key_type&& k, M&& obj);
|
||||
template<class K, class M> bool xref:#concurrent_flat_map_insert_or_assign[insert_or_assign](K&& k, M&& obj);
|
||||
@@ -394,8 +428,9 @@ user-provided visitation function on the element passed do not introduce data ra
|
||||
|
||||
* Read access to the element.
|
||||
* Non-mutable modification of the element.
|
||||
* Mutable modification of the element (if the container operation executing the visitation function is not const
|
||||
and its name does not contain `cvisit`.)
|
||||
* 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`.
|
||||
@@ -1113,7 +1148,113 @@ template<class F> size_type insert_or_cvisit(std::initializer_list<value_type> i
|
||||
Equivalent to
|
||||
[listing,subs="+macros,+quotes"]
|
||||
-----
|
||||
this->xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or[c\]visit](il.begin(), il.end(), f);
|
||||
this->xref:#concurrent_flat_map_insert_iterator_range_or_visit[insert_or_[c\]visit](il.begin(), il.end(), f);
|
||||
-----
|
||||
|
||||
[horizontal]
|
||||
Returns:;; The number of elements inserted.
|
||||
|
||||
---
|
||||
|
||||
==== emplace_and_[c]visit
|
||||
```c++
|
||||
template<class... Args, class F1, class F2>
|
||||
bool emplace_and_visit(Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
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<class F1, class F2> bool insert_and_visit(const value_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool insert_and_cvisit(const value_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool insert_and_visit(const init_type& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> 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<std::remove_reference<decltype(obj)>::type>::type` is `value_type`.
|
||||
|
||||
---
|
||||
|
||||
==== Move insert_and_[c]visit
|
||||
```c++
|
||||
template<class F1, class F2> bool insert_and_visit(value_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool insert_and_cvisit(value_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> bool insert_and_visit(init_type&& obj, F1 f1, F2 f2);
|
||||
template<class F1, class F2> 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<decltype(obj)>::type` is `value_type`.
|
||||
|
||||
---
|
||||
|
||||
==== Insert Iterator Range and Visit
|
||||
```c++
|
||||
template<class InputIterator, class F1, class F2>
|
||||
size_type insert_or_visit(InputIterator first, InputIterator last, F1 f1, F2 f2);
|
||||
template<class InputIterator, class F1, class F2>
|
||||
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<class F1, class F2>
|
||||
size_type insert_or_visit(std::initializer_list<value_type> il, F1 f1, F2 f2);
|
||||
template<class F1, class F2>
|
||||
size_type insert_or_cvisit(std::initializer_list<value_type> 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(), f1, f2);
|
||||
-----
|
||||
|
||||
[horizontal]
|
||||
@@ -1207,6 +1348,55 @@ The `template<class K, class\... Args, class F>` overloads only participate in o
|
||||
|
||||
---
|
||||
|
||||
==== try_emplace_and_[c]visit
|
||||
```c++
|
||||
template<class... Args, class F1, class F2>
|
||||
bool try_emplace_and_visit(const key_type& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool try_emplace_and_cvisit(const key_type& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool try_emplace_and_visit(key_type&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class... Args, class F1, class F2>
|
||||
bool try_emplace_and_cvisit(key_type&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class K, class... Args, class F1, class F2>
|
||||
bool try_emplace_and_visit(K&& k, Args&&... args, F1&& f1, F2&& f2);
|
||||
template<class K, class... Args, class F1, class F2>
|
||||
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<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// last two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(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<class K, class\... Args, class F1, class F2>` 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<class M> bool insert_or_assign(const key_type& k, M&& obj);
|
||||
|
||||
Reference in New Issue
Block a user