diff options
| author | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-01 01:33:38 +0000 |
|---|---|---|
| committer | Erik Pilkington <erik.pilkington@gmail.com> | 2018-08-01 01:33:38 +0000 |
| commit | b0386a515b60c2f43eaaef986bd5b1cdc4448244 (patch) | |
| tree | bf43e7a1f1c135df7a7873d08381e77c70c1416e /libcxx/include/__hash_table | |
| parent | 9057546c5bf2015414186c1a1f0660cd32344362 (diff) | |
| download | bcm5719-llvm-b0386a515b60c2f43eaaef986bd5b1cdc4448244.tar.gz bcm5719-llvm-b0386a515b60c2f43eaaef986bd5b1cdc4448244.zip | |
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
llvm-svn: 338472
Diffstat (limited to 'libcxx/include/__hash_table')
| -rw-r--r-- | libcxx/include/__hash_table | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 44ba268a0ec..c77de961be6 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -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) |

