boostorg / unordered

Boost.org unordered module
http://boost.org/libs/unordered
Boost Software License 1.0
63 stars 55 forks source link

[FR] Add extract-like functionality to concurrent containers #273

Closed demozon closed 2 months ago

demozon commented 2 months ago

Hi,

Is it feasible to add a function for extracting elements (perhaps only by key) that takes a function as an additional argument? Or perhaps add an additional overload to erase?

E.g. something like

template void extract(const key_type& k, F f);

My usecase is that I have an issue where I have an object that tries to delete itself.

joaquintides commented 2 months ago

You can "extract" elements as follows:

#include <boost/unordered/concurrent_flat_map.hpp>
#include <cassert>
#include <optional>

int main()
{
  using map = boost::concurrent_flat_map<int, int>;
  using value_type = map::value_type;

  map m = {{1, 2}};
  std::optional<value_type> o;
  m.erase_if(1, [&](value_type& x) {
    o.emplace(std::move(x)); 
    return true;
  });
  assert(o->first == 1);
  assert(o->second == 2);
}

Extraction proper (without incurring any move construction) is not possible as boost::concurrent_flat_(map|set) are not node-based. In Boost 1.87, boost::concurrent_node_(map|set) will be provided with actual extract capabilities, but bear in mind that these containers are generally slower than their flat counterparts.

demozon commented 2 months ago

That does do the trick, actually. Just need a const_cast in my case, since I'm using a set.

demozon commented 2 months ago

There exists a workaround