32 #define _NODE_HANDLE 1 34 #pragma GCC system_header 36 #if __cplusplus > 201402L 37 # define __cpp_lib_node_extract 201606 44 namespace std _GLIBCXX_VISIBILITY(default)
46 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 template<
typename _Val,
typename _NodeAlloc>
50 class _Node_handle_common
52 using _AllocTraits = allocator_traits<_NodeAlloc>;
55 using allocator_type = __alloc_rebind<_NodeAlloc, _Val>;
58 get_allocator() const noexcept
60 __glibcxx_assert(!this->empty());
61 return allocator_type(*_M_alloc);
64 explicit operator bool() const noexcept {
return _M_ptr !=
nullptr; }
66 bool empty() const noexcept {
return _M_ptr ==
nullptr; }
69 constexpr _Node_handle_common() noexcept : _M_ptr(), _M_alloc() {}
71 ~_Node_handle_common() { _M_destroy(); }
73 _Node_handle_common(_Node_handle_common&& __nh) noexcept
74 : _M_ptr(__nh._M_ptr), _M_alloc(
std::move(__nh._M_alloc))
76 __nh._M_ptr =
nullptr;
81 operator=(_Node_handle_common&& __nh) noexcept
85 if constexpr (is_move_assignable_v<_NodeAlloc>)
87 if (_AllocTraits::propagate_on_container_move_assignment::value
89 this->_M_alloc = std::move(__nh._M_alloc);
91 __glibcxx_assert(this->_M_alloc == __nh._M_alloc);
94 __glibcxx_assert(_M_alloc);
95 __nh._M_ptr =
nullptr;
100 _Node_handle_common(
typename _AllocTraits::pointer __ptr,
101 const _NodeAlloc& __alloc)
102 : _M_ptr(__ptr), _M_alloc(__alloc) { }
105 _M_swap(_Node_handle_common& __nh) noexcept
108 swap(_M_ptr, __nh._M_ptr);
109 if (_AllocTraits::propagate_on_container_swap
110 || !_M_alloc || !__nh._M_alloc)
111 _M_alloc.swap(__nh._M_alloc);
113 __glibcxx_assert(_M_alloc == __nh._M_alloc);
118 _M_destroy() noexcept
120 if (_M_ptr !=
nullptr)
122 allocator_type __alloc(*_M_alloc);
124 _M_ptr->_M_valptr());
125 _AllocTraits::deallocate(*_M_alloc, _M_ptr, 1);
130 typename _AllocTraits::pointer _M_ptr;
132 optional<_NodeAlloc> _M_alloc;
134 template<
typename _Key2,
typename _Value2,
typename _KeyOfValue,
135 typename _Compare,
typename _ValueAlloc>
136 friend class _Rb_tree;
140 template<
typename _Key,
typename _Value,
typename _NodeAlloc>
141 class _Node_handle :
public _Node_handle_common<_Value, _NodeAlloc>
144 constexpr _Node_handle() noexcept = default;
145 ~_Node_handle() = default;
146 _Node_handle(_Node_handle&&) noexcept = default;
149 operator=(_Node_handle&&) noexcept = default;
151 using key_type = _Key;
152 using mapped_type = typename _Value::second_type;
157 __glibcxx_assert(!this->empty());
162 mapped() const noexcept
164 __glibcxx_assert(!this->empty());
169 swap(_Node_handle& __nh) noexcept
173 swap(_M_pkey, __nh._M_pkey);
174 swap(_M_pmapped, __nh._M_pmapped);
178 swap(_Node_handle& __x, _Node_handle& __y)
179 noexcept(noexcept(__x.swap(__y)))
183 using _AllocTraits = allocator_traits<_NodeAlloc>;
185 _Node_handle(
typename _AllocTraits::pointer __ptr,
186 const _NodeAlloc& __alloc)
187 : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc)
191 auto& __key =
const_cast<_Key&
>(__ptr->_M_valptr()->first);
192 _M_pkey = _S_pointer_to(__key);
193 _M_pmapped = _S_pointer_to(__ptr->_M_valptr()->second);
198 _M_pmapped =
nullptr;
202 template<
typename _Tp>
203 using __pointer = __ptr_rebind<typename _AllocTraits::pointer, _Tp>;
205 __pointer<_Key> _M_pkey =
nullptr;
206 __pointer<typename _Value::second_type> _M_pmapped =
nullptr;
208 template<
typename _Tp>
210 _S_pointer_to(_Tp& __obj)
211 {
return pointer_traits<__pointer<_Tp>>::pointer_to(__obj); }
214 _M_key() const noexcept {
return key(); }
216 template<
typename _Key2,
typename _Value2,
typename _KeyOfValue,
217 typename _Compare,
typename _ValueAlloc>
218 friend class _Rb_tree;
220 template<
typename _Key2,
typename _Value2,
typename _ValueAlloc,
221 typename _ExtractKey,
typename _Equal,
222 typename _H1,
typename _H2,
typename _Hash,
223 typename _RehashPolicy,
typename _Traits>
224 friend class _Hashtable;
228 template<
typename _Value,
typename _NodeAlloc>
229 class _Node_handle<_Value, _Value, _NodeAlloc>
230 :
public _Node_handle_common<_Value, _NodeAlloc>
233 constexpr _Node_handle() noexcept = default;
234 ~_Node_handle() = default;
235 _Node_handle(_Node_handle&&) noexcept = default;
238 operator=(_Node_handle&&) noexcept = default;
240 using value_type = _Value;
243 value() const noexcept
245 __glibcxx_assert(!this->empty());
246 return *this->_M_ptr->_M_valptr();
250 swap(_Node_handle& __nh) noexcept
251 { this->_M_swap(__nh); }
254 swap(_Node_handle& __x, _Node_handle& __y)
255 noexcept(noexcept(__x.swap(__y)))
259 using _AllocTraits = allocator_traits<_NodeAlloc>;
261 _Node_handle(
typename _AllocTraits::pointer __ptr,
262 const _NodeAlloc& __alloc)
263 : _Node_handle_common<_Value, _NodeAlloc>(__ptr, __alloc) { }
266 _M_key() const noexcept {
return value(); }
268 template<
typename _Key,
typename _Val,
typename _KeyOfValue,
269 typename _Compare,
typename _Alloc>
270 friend class _Rb_tree;
272 template<
typename _Key2,
typename _Value2,
typename _ValueAlloc,
273 typename _ExtractKey,
typename _Equal,
274 typename _H1,
typename _H2,
typename _Hash,
275 typename _RehashPolicy,
typename _Traits>
276 friend class _Hashtable;
280 template<
typename _Iterator,
typename _NodeHandle>
281 struct _Node_insert_return
283 bool inserted =
false;
284 _Iterator position = _Iterator();
287 template<
size_t _Idx>
288 decltype(
auto) get() &
289 {
return std::get<_Idx>(
std::tie(inserted, position, node)); }
291 template<
size_t _Idx>
292 decltype(
auto) get() const &
293 {
return std::get<_Idx>(
std::tie(inserted, position, node)); }
295 template<
size_t _Idx>
296 decltype(
auto) get() &&
298 return std::move(std::get<_Idx>(
std::tie(inserted, position, node)));
301 template<
size_t _Idx>
302 decltype(
auto) get() const &&
304 return std::move(std::get<_Idx>(
std::tie(inserted, position, node)));
308 template<
typename _Iterator,
typename _NodeHandle>
309 struct tuple_size<_Node_insert_return<_Iterator, _NodeHandle>>
310 : integral_constant<size_t, 3> { };
312 template<
typename _Iterator,
typename _NodeHandle>
313 struct tuple_element<0, _Node_insert_return<_Iterator, _NodeHandle>>
314 {
using type = bool; };
316 template<
typename _Iterator,
typename _NodeHandle>
317 struct tuple_element<1, _Node_insert_return<_Iterator, _NodeHandle>>
318 {
using type = _Iterator; };
320 template<
typename _Iterator,
typename _NodeHandle>
321 struct tuple_element<2, _Node_insert_return<_Iterator, _NodeHandle>>
322 {
using type = _NodeHandle; };
324 _GLIBCXX_END_NAMESPACE_VERSION
constexpr nullopt_t nullopt
Tag to disengage optional objects.
ISO C++ entities toplevel namespace is std.
static void destroy(_Alloc &__a, _Tp *__p)
Destroy an object of type _Tp.
constexpr tuple< _Elements &... > tie(_Elements &...__args) noexcept
tie