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
When a function is declared with a visibility macro (_LIBCPP_INLINE_VISIBILITY in this case), I think it is customary in libc++ to repeat the visibility macro on the definition as well. If that's correct, apply here and to other similar functions below, and also in __tree.