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

@@ -43,6 +43,9 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
typedef unspecified node_type unspecified; // C++17
typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17
unordered_set()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -113,6 +116,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
insert_return_type insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -191,6 +199,8 @@ public:
typedef /unspecified/ local_iterator;
typedef /unspecified/ const_local_iterator;
typedef unspecified node_type unspecified; // C++17
unordered_multiset()
noexcept(
is_nothrow_default_constructible<hasher>::value &&
@@ -261,6 +271,11 @@ public:
void insert(InputIterator first, InputIterator last);
void insert(initializer_list<value_type>);
node_type extract(const_iterator position); // C++17
node_type extract(const key_type& x); // C++17
iterator insert(node_type&& nh); // C++17
iterator insert(const_iterator hint, node_type&& nh); // C++17
iterator erase(const_iterator position);
iterator erase(iterator position); // C++14
size_type erase(const key_type& k);
@@ -321,6 +336,7 @@ template <class Value, class Hash, class Pred, class Alloc>
#include <__config>
#include <__hash_table>
#include <__node_handle>
#include <functional>
#include <__debug>
@@ -363,6 +379,11 @@ public:
typedef typename __table::const_local_iterator local_iterator;
typedef typename __table::const_local_iterator const_local_iterator;
#if _LIBCPP_STD_VER > 14
typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
typedef __insert_return_type<iterator, node_type> insert_return_type;
#endif
_LIBCPP_INLINE_VISIBILITY
unordered_set()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -541,6 +562,35 @@ public:
_LIBCPP_INLINE_VISIBILITY
void clear() _NOEXCEPT {__table_.clear();}
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
insert_return_type insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to unordered_set::insert()");
return __table_.template __node_handle_insert_unique<
node_type, insert_return_type>(_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __h, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to unordered_set::insert()");
return __table_.template __node_handle_insert_unique<node_type>(
__h, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __table_.template __node_handle_extract<node_type>(__key);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __it)
{
return __table_.template __node_handle_extract<node_type>(__it);
}
#endif
_LIBCPP_INLINE_VISIBILITY
void swap(unordered_set& __u)
_NOEXCEPT_(__is_nothrow_swappable<__table>::value)
@@ -883,6 +933,10 @@ public:
typedef typename __table::const_local_iterator local_iterator;
typedef typename __table::const_local_iterator const_local_iterator;
#if _LIBCPP_STD_VER > 14
typedef __set_node_handle<typename __table::__node, allocator_type> node_type;
#endif
_LIBCPP_INLINE_VISIBILITY
unordered_multiset()
_NOEXCEPT_(is_nothrow_default_constructible<__table>::value)
@@ -1019,6 +1073,36 @@ public:
_LIBCPP_INLINE_VISIBILITY
void insert(_InputIterator __first, _InputIterator __last);
#if _LIBCPP_STD_VER > 14
_LIBCPP_INLINE_VISIBILITY
iterator insert(node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to unordered_multiset::insert()");
return __table_.template __node_handle_insert_multi<node_type>(
_VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
iterator insert(const_iterator __hint, node_type&& __nh)
{
_LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(),
"node_type with incompatible allocator passed to unordered_multiset::insert()");
return __table_.template __node_handle_insert_multi<node_type>(
__hint, _VSTD::move(__nh));
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(const_iterator __position)
{
return __table_.template __node_handle_extract<node_type>(
__position);
}
_LIBCPP_INLINE_VISIBILITY
node_type extract(key_type const& __key)
{
return __table_.template __node_handle_extract<node_type>(__key);
}
#endif
_LIBCPP_INLINE_VISIBILITY
iterator erase(const_iterator __p) {return __table_.erase(__p);}
_LIBCPP_INLINE_VISIBILITY