[PATCH] D46845: [libcxx][c++17] P0083R5: Splicing Maps and Sets

Erik Pilkington via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon May 14 13:21:55 PDT 2018


erik.pilkington created this revision.
erik.pilkington added reviewers: EricWF, mclow.lists, Quuxplusone.
Herald added a subscriber: christof.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0083r3.pdf

This patch adds support for p0083, splicing maps and sets. This feature allows users to `extract` a container node from a unordered or associative container, then `insert` it into another container without having to copy the node. The `container_type::node_type` member is a smart pointer that holds an extracted node. This proposal also includes a `merge` member function that can extract and insert nodes from a source container without losing nodes if an exception is thrown (from, i.e., a comparator).

This implementation for this is pretty straightforward, most of the operations necessary to write this API are already part of __tree and __hash_table. In __hash_table, I split up the functions __node_insert_unqiue and __node_insert_multi into 2 parts in order to implement merge. The first part, `__node_insert_{multi,unique}_prepare` checks to see if a node already is present in the container (as needed), and rehashes the container. This function can forward exceptions, but doesn't mutate the node it's preparing to insert. the `__node_insert_{multi,unique}_perform` is noexcept, but mutates the pointers in the node to actually insert it into the container. This allows `merge` to call a `_prepare` function on a node while it is in the source container, without invalidating anything or losing nodes if an exception is thrown. Another quirk is the __generic_container_node_destructor templated struct, this is forward-declared (and used, in a dependent context) in <__node_handle> and specialized in <__tree> and <__hash_table>. This allows <__node_handle> to call into __hash_node_destructor and __tree_node_destructor without including those headers.

As far as testing goes, I added some tests and ran them with msan, ubsan, and asan. I also ran the libstdc++ tests for this with the same sanitizers on linux and macos.

I'm still pretty new to libc++, so take this patch with a grain of salt!
Thanks for taking a look,
Erik


Repository:
  rCXX libc++

https://reviews.llvm.org/D46845

Files:
  libcxx/include/__hash_table
  libcxx/include/__node_handle
  libcxx/include/__tree
  libcxx/include/map
  libcxx/include/set
  libcxx/include/unordered_map
  libcxx/include/unordered_set
  libcxx/test/std/containers/associative/map/map.modifiers/insert_extract.pass.cpp
  libcxx/test/std/containers/associative/map/map.modifiers/merge.pass.cpp
  libcxx/test/std/containers/associative/multimap/multimap.modifiers/insert_extract.pass.cpp
  libcxx/test/std/containers/associative/multimap/multimap.modifiers/merge.pass.cpp
  libcxx/test/std/containers/associative/multiset/insert_extract.pass.cpp
  libcxx/test/std/containers/associative/multiset/merge.pass.cpp
  libcxx/test/std/containers/associative/set/insert_extract.pass.cpp
  libcxx/test/std/containers/associative/set/merge.pass.cpp
  libcxx/test/std/containers/container.node/node_handle.pass.cpp
  libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/insert_extract.pass.cpp
  libcxx/test/std/containers/unord/unord.map/unord.map.modifiers/merge.pass.cpp
  libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/insert_extract.pass.cpp
  libcxx/test/std/containers/unord/unord.multimap/unord.multimap.modifiers/merge.pass.cpp
  libcxx/test/std/containers/unord/unord.multiset/insert_extract.pass.cpp
  libcxx/test/std/containers/unord/unord.multiset/merge.pass.cpp
  libcxx/test/std/containers/unord/unord.set/insert_extract.pass.cpp
  libcxx/test/std/containers/unord/unord.set/merge.pass.cpp
  libcxx/test/support/Counter.h

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46845.146659.patch
Type: text/x-patch
Size: 133628 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180514/4045087d/attachment-0001.bin>


More information about the cfe-commits mailing list