diff --git a/doc/unordered/changes.adoc b/doc/unordered/changes.adoc index 6cf4c767..757a7000 100644 --- a/doc/unordered/changes.adoc +++ b/doc/unordered/changes.adoc @@ -8,7 +8,7 @@ == Release 1.84.0 -* Added `[c]visit_until` and `[c]visit_while` operations to `boost::concurrent_map`, +* Added `[c]visit_while` operations to `boost::concurrent_map`, with serial and parallel variants. == Release 1.83.0 - Major update diff --git a/doc/unordered/concurrent.adoc b/doc/unordered/concurrent.adoc index 1d66a53c..aed9c466 100644 --- a/doc/unordered/concurrent.adoc +++ b/doc/unordered/concurrent.adoc @@ -162,23 +162,17 @@ Traversal can be interrupted midway: int key = 0; int value = ...; -bool found = m.visit_until([&](const auto& x) { +bool found = !m.visit_while([&](const auto& x) { if(x.second == value) { key = x.first; - return true; // finish + return false; // finish } else { - return false; // keep on visiting + return true; // keep on visiting } }); if(found) { ... } - -// check if all values are != 0 - -bool all_ok = m.visit_while([&](const auto& x) { - return x.second != 0; -}); ---- There is one last whole-table visitation operation, `erase_if`: @@ -190,7 +184,7 @@ m.erase_if([](auto& x) { }); ---- -`visit_until`, `visit_while` and `erase_if` can also be parallelized. Note that, in order to increase efficiency, +`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 `boost::concurrent_flat_map` diff --git a/doc/unordered/concurrent_flat_map.adoc b/doc/unordered/concurrent_flat_map.adoc index dd9199b7..8038f210 100644 --- a/doc/unordered/concurrent_flat_map.adoc +++ b/doc/unordered/concurrent_flat_map.adoc @@ -114,16 +114,6 @@ namespace boost { template void xref:#concurrent_flat_map_parallel_cvisit_all[cvisit_all](ExecutionPolicy&& policy, F f) const; - template bool xref:#concurrent_flat_map_cvisit_until[visit_until](F f); - template bool xref:#concurrent_flat_map_cvisit_until[visit_until](F f) const; - template bool xref:#concurrent_flat_map_cvisit_until[cvisit_until](F f) const; - template - bool xref:#concurrent_flat_map_parallel_cvisit_until[visit_until](ExecutionPolicy&& policy, F f); - template - bool xref:#concurrent_flat_map_parallel_cvisit_until[visit_until](ExecutionPolicy&& policy, F f) const; - template - bool xref:#concurrent_flat_map_parallel_cvisit_until[cvisit_until](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; @@ -740,50 +730,6 @@ Unsequenced execution policies are not allowed. --- -==== [c]visit_until - -```c++ -template bool visit_until(F f); -template bool visit_until(F f) const; -template bool cvisit_until(F f) const; -``` - -Successively invokes `f` with references to each of the elements in the table until `f` returns `true` -or all the elements are visited. -Such references to the elements are const iff `*this` is const. - -[horizontal] -Returns:;; `true` iff `f` ever returns `true`. - ---- - -==== Parallel [c]visit_until - -```c++ -template bool visit_until(ExecutionPolicy&& policy, F f); -template bool visit_until(ExecutionPolicy&& policy, F f) const; -template bool cvisit_until(ExecutionPolicy&& policy, F f) const; -``` - -Invokes `f` with references to each of the elements in the table until `f` returns `true` -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:;; `true` iff `f` ever returns `true`. -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 `true`, and as a result -`f` may be invoked with further elements for which the return value is also `true`. - ---- - ==== [c]visit_while ```c++ diff --git a/include/boost/unordered/concurrent_flat_map.hpp b/include/boost/unordered/concurrent_flat_map.hpp index 10712c9e..9364d349 100644 --- a/include/boost/unordered/concurrent_flat_map.hpp +++ b/include/boost/unordered/concurrent_flat_map.hpp @@ -355,56 +355,6 @@ namespace boost { } #endif - template bool visit_until(F f) - { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) - return table_.visit_until(f); - } - - template bool visit_until(F f) const - { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - return table_.visit_until(f); - } - - template bool cvisit_until(F f) const - { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - return table_.cvisit_until(f); - } - -#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) - template - typename std::enable_if::value, - bool>::type - visit_until(ExecPolicy&& p, F f) - { - BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) - BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) - return table_.visit_until(p, f); - } - - template - typename std::enable_if::value, - bool>::type - visit_until(ExecPolicy&& p, F f) const - { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) - return table_.visit_until(p, f); - } - - template - typename std::enable_if::value, - bool>::type - cvisit_until(ExecPolicy&& p, F f) const - { - BOOST_UNORDERED_STATIC_ASSERT_CONST_INVOCABLE(F) - BOOST_UNORDERED_STATIC_ASSERT_EXEC_POLICY(ExecPolicy) - return table_.cvisit_until(p, f); - } -#endif - template bool visit_while(F f) { BOOST_UNORDERED_STATIC_ASSERT_INVOCABLE(F) diff --git a/include/boost/unordered/detail/foa/concurrent_table.hpp b/include/boost/unordered/detail/foa/concurrent_table.hpp index 5a28f782..51615446 100644 --- a/include/boost/unordered/detail/foa/concurrent_table.hpp +++ b/include/boost/unordered/detail/foa/concurrent_table.hpp @@ -539,46 +539,6 @@ public: } #endif - template bool visit_until(F&& f) - { - return !visit_while([&](value_type& x){return !f(x);}); - } - - template bool visit_until(F&& f)const - { - return !visit_while([&](const value_type& x){return !f(x);}); - } - - template bool cvisit_until(F&& f)const - { - return visit_while(std::forward(f)); - } - -#if defined(BOOST_UNORDERED_PARALLEL_ALGORITHMS) - template - bool visit_until(ExecutionPolicy&& policy,F&& f) - { - return !visit_while( - std::forward(policy), - [&](value_type& x){return !f(x);}); - } - - template - bool visit_until(ExecutionPolicy&& policy,F&& f)const - { - return !visit_while( - std::forward(policy), - [&](const value_type& x){return !f(x);}); - } - - template - bool cvisit_until(ExecutionPolicy&& policy,F&& f)const - { - return visit_until( - std::forward(policy),std::forward(f)); - } -#endif - template bool visit_while(F&& f) { return visit_while_impl(group_exclusive{},std::forward(f));