First half of C++17's splicing maps and sets

This commit adds a node handle type, (located in __node_handle), and adds
extract() and insert() members to all map and set types, as well as their
implementations in __tree and __hash_table.

The second half of this feature is adding merge() members, which splice nodes
in bulk from one container into another. This will be committed in a follow-up.

Differential revision: https://reviews.llvm.org/D46845

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@338472 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Erik Pilkington
2018-08-01 01:33:38 +00:00
parent ea96e3a707
commit 36fc737189
43 changed files with 3215 additions and 10 deletions

View File

@@ -859,6 +859,17 @@ public:
template <class> friend class __hash_map_node_destructor;
};
#if _LIBCPP_STD_VER > 14
template <class _NodeType, class _Alloc>
struct __generic_container_node_destructor;
template <class _Tp, class _VoidPtr, class _Alloc>
struct __generic_container_node_destructor<__hash_node<_Tp, _VoidPtr>, _Alloc>
: __hash_node_destructor<_Alloc>
{
using __hash_node_destructor<_Alloc>::__hash_node_destructor;
};
#endif
#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash, class _Equal, class _Alloc>
@@ -1151,6 +1162,30 @@ public:
return __emplace_unique_key_args(_NodeTypes::__get_key(__x), __x);
}
#if _LIBCPP_STD_VER > 14
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType __node_handle_insert_unique(_NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_unique(const_iterator __hint,
_NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(_NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
iterator __node_handle_insert_multi(const_iterator __hint, _NodeHandle&& __nh);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(key_type const& __key);
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle __node_handle_extract(const_iterator __it);
#endif
void clear() _NOEXCEPT;
void rehash(size_type __n);
_LIBCPP_INLINE_VISIBILITY void reserve(size_type __n)
@@ -2126,6 +2161,91 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__insert_multi(const_iterator __p,
#endif // _LIBCPP_CXX03_LANG
#if _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle, class _InsertReturnType>
_LIBCPP_INLINE_VISIBILITY
_InsertReturnType
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
_NodeHandle&& __nh)
{
if (__nh.empty())
return _InsertReturnType{end(), false, _NodeHandle()};
pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
if (__result.second)
__nh.__release();
return _InsertReturnType{__result.first, __result.second, _VSTD::move(__nh)};
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_unique(
const_iterator, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
pair<iterator, bool> __result = __node_insert_unique(__nh.__ptr_);
if (__result.second)
__nh.__release();
return __result.first;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
key_type const& __key)
{
iterator __i = find(__key);
if (__i == end())
return _NodeHandle();
return __node_handle_extract<_NodeHandle>(__i);
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
_NodeHandle
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_extract(
const_iterator __p)
{
allocator_type __alloc(__node_alloc());
return _NodeHandle(remove(__p).release(), __alloc);
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
_NodeHandle&& __nh)
{
if (__nh.empty())
return end();
iterator __result = __node_insert_multi(__nh.__ptr_);
__nh.__release();
return __result;
}
template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _NodeHandle>
_LIBCPP_INLINE_VISIBILITY
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_handle_insert_multi(
const_iterator __hint, _NodeHandle&& __nh)
{
if (__nh.empty())
return end();
iterator __result = __node_insert_multi(__hint, __nh.__ptr_);
__nh.__release();
return __result;
}
#endif // _LIBCPP_STD_VER > 14
template <class _Tp, class _Hash, class _Equal, class _Alloc>
void
__hash_table<_Tp, _Hash, _Equal, _Alloc>::rehash(size_type __n)