Files
2025-10-25 03:02:53 +03:00

293 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[container.node]
# 23 Containers library [[containers]](./#containers)
## 23.2 Requirements [[container.requirements]](container.requirements#container.node)
### 23.2.5 Node handles [container.node]
#### [23.2.5.1](#overview) Overview [[container.node.overview]](container.node.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2318)
A [*node handle*](#def:node_handle "23.2.5.1Overview[container.node.overview]") is an object that accepts ownership of a single element
from an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")) or an unordered
associative container ([[unord.req]](unord.req "23.2.8Unordered associative containers"))[.](#overview-1.sentence-1)
It may be used to transfer that
ownership to another container with compatible nodes[.](#overview-1.sentence-2)
Containers with
compatible nodes have the same node handle type[.](#overview-1.sentence-3)
Elements may be transferred in
either direction between container types in the same row of
Table [75](#tab:container.node.compat "Table 75: Container types with compatible nodes")[.](#overview-1.sentence-4)
Table [75](#tab:container.node.compat) — Container types with compatible nodes [[tab:container.node.compat]](./tab:container.node.compat)
| [🔗](#tab:container.node.compat-row-1)<br>map<K, T, C1, A> | map<K, T, C2, A> |
| --- | --- |
| [🔗](#tab:container.node.compat-row-2)<br>map<K, T, C1, A> | multimap<K, T, C2, A> |
| [🔗](#tab:container.node.compat-row-3)<br>set<K, C1, A> | set<K, C2, A> |
| [🔗](#tab:container.node.compat-row-4)<br>set<K, C1, A> | multiset<K, C2, A> |
| [🔗](#tab:container.node.compat-row-5)<br>unordered_map<K, T, H1, E1, A> | unordered_map<K, T, H2, E2, A> |
| [🔗](#tab:container.node.compat-row-6)<br>unordered_map<K, T, H1, E1, A> | unordered_multimap<K, T, H2, E2, A> |
| [🔗](#tab:container.node.compat-row-7)<br>unordered_set<K, H1, E1, A> | unordered_set<K, H2, E2, A> |
| [🔗](#tab:container.node.compat-row-8)<br>unordered_set<K, H1, E1, A> | unordered_multiset<K, H2, E2, A> |
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2347)
If a node handle is not empty, then it contains an allocator that is equal to
the allocator of the container when the element was extracted[.](#overview-2.sentence-1)
If a node handle
is empty, it contains no allocator[.](#overview-2.sentence-2)
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2352)
Class *node-handle* is for exposition only[.](#overview-3.sentence-1)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2355)
If a user-defined specialization of pair exists forpair<const Key, T> or pair<Key, T>, where Key is the
container's key_type and T is the container'smapped_type, the behavior of operations involving node handles is
undefined[.](#overview-4.sentence-1)
template<*unspecified*>class *node-handle* {public:// These type declarations are described in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") and [[unord.req]](unord.req "23.2.8Unordered associative containers").using value_type = *see below*; // not present for map containersusing key_type = *see below*; // not present for set containersusing mapped_type = *see below*; // not present for set containersusing allocator_type = *see below*;
private:using container_node_type = *unspecified*; // *exposition only*using ator_traits = allocator_traits<allocator_type>; // *exposition only*typename ator_traits::template rebind_traits<container_node_type>::pointer ptr_; // *exposition only* optional<allocator_type> alloc_; // *exposition only*public:// [[container.node.cons]](#cons "23.2.5.2Constructors, copy, and assignment"), constructors, copy, and assignmentconstexpr *node-handle*() noexcept : ptr_(), alloc_() {}constexpr *node-handle*(*node-handle*&&) noexcept; constexpr *node-handle*& operator=(*node-handle*&&); // [[container.node.dtor]](#dtor "23.2.5.3Destructor"), destructorconstexpr ~*node-handle*(); // [[container.node.observers]](#observers "23.2.5.4Observers"), observersconstexpr value_type& value() const; // not present for map containers key_type& key() const; // not present for set containersconstexpr mapped_type& mapped() const; // not present for set containersconstexpr allocator_type get_allocator() const; constexpr explicit operator bool() const noexcept; constexpr bool empty() const noexcept; // [[container.node.modifiers]](#modifiers "23.2.5.5Modifiers"), modifiersconstexpr void swap(*node-handle*&)noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); friend constexpr void swap(*node-handle*& x, *node-handle*& y) noexcept(noexcept(x.swap(y))) { x.swap(y); }};
#### [23.2.5.2](#cons) Constructors, copy, and assignment [[container.node.cons]](container.node.cons)
[🔗](#cons-itemdecl:1)
`constexpr node-handle(node-handle&& nh) noexcept;
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2416)
*Effects*: Constructs a *node-handle* object initializingptr_ with nh.ptr_[.](#cons-1.sentence-1)
Move constructs alloc_ withnh.alloc_[.](#cons-1.sentence-2)
Assigns nullptr to nh.ptr_ and assignsnullopt to nh.alloc_[.](#cons-1.sentence-3)
[🔗](#cons-itemdecl:2)
`constexpr node-handle& operator=(node-handle&& nh);
`
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2429)
*Preconditions*: Either !alloc_, orator_traits::propagate_on_container_move_assignment::value is true, or alloc_ == nh.alloc_[.](#cons-2.sentence-1)
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2435)
*Effects*:
- [(3.1)](#cons-3.1)
If ptr_ != nullptr, destroys the value_type subobject in the container_node_type object pointed to by ptr_ by calling ator_traits::destroy, then deallocates ptr_ by
calling ator_traits::template rebind_traits<container_node_type>::deallocate[.](#cons-3.1.sentence-1)
- [(3.2)](#cons-3.2)
Assigns nh.ptr_ to ptr_[.](#cons-3.2.sentence-1)
- [(3.3)](#cons-3.3)
If !alloc_ or ator_traits::propagate_on_container_move_assignment::value is true, move assigns nh.alloc_ to alloc_[.](#cons-3.3.sentence-1)
- [(3.4)](#cons-3.4)
Assignsnullptr to nh.ptr_ and assigns nullopt tonh.alloc_[.](#cons-3.4.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2454)
*Returns*: *this[.](#cons-4.sentence-1)
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2458)
*Throws*: Nothing[.](#cons-5.sentence-1)
#### [23.2.5.3](#dtor) Destructor [[container.node.dtor]](container.node.dtor)
[🔗](#dtor-itemdecl:1)
`constexpr ~node-handle();
`
[1](#dtor-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2470)
*Effects*: If ptr_ != nullptr, destroys the value_type subobject
in the container_node_type object pointed to by ptr_ by callingator_traits::destroy, then deallocates ptr_ by callingator_traits::template rebind_traits<container_node_type>::deallocate[.](#dtor-1.sentence-1)
#### [23.2.5.4](#observers) Observers [[container.node.observers]](container.node.observers)
[🔗](#observers-itemdecl:1)
`constexpr value_type& value() const;
`
[1](#observers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2485)
*Preconditions*: empty() == false[.](#observers-1.sentence-1)
[2](#observers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2489)
*Returns*: A reference to the value_type subobject in thecontainer_node_type object pointed to by ptr_[.](#observers-2.sentence-1)
[3](#observers-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2494)
*Throws*: Nothing[.](#observers-3.sentence-1)
[🔗](#observers-itemdecl:2)
`key_type& key() const;
`
[4](#observers-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2504)
*Preconditions*: empty() == false[.](#observers-4.sentence-1)
[5](#observers-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2508)
*Returns*: A non-const reference to the key_type member of thevalue_type subobject in the container_node_type object
pointed to by ptr_[.](#observers-5.sentence-1)
[6](#observers-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2514)
*Throws*: Nothing[.](#observers-6.sentence-1)
[7](#observers-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2518)
*Remarks*: Modifying the key through the returned reference is permitted[.](#observers-7.sentence-1)
[🔗](#observers-itemdecl:3)
`constexpr mapped_type& mapped() const;
`
[8](#observers-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2528)
*Preconditions*: empty() == false[.](#observers-8.sentence-1)
[9](#observers-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2532)
*Returns*: A reference to the mapped_type member of thevalue_type subobject in the container_node_type object
pointed to by ptr_[.](#observers-9.sentence-1)
[10](#observers-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2538)
*Throws*: Nothing[.](#observers-10.sentence-1)
[🔗](#observers-itemdecl:4)
`constexpr allocator_type get_allocator() const;
`
[11](#observers-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2548)
*Preconditions*: empty() == false[.](#observers-11.sentence-1)
[12](#observers-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2552)
*Returns*: *alloc_[.](#observers-12.sentence-1)
[13](#observers-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2556)
*Throws*: Nothing[.](#observers-13.sentence-1)
[🔗](#observers-itemdecl:5)
`constexpr explicit operator bool() const noexcept;
`
[14](#observers-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2566)
*Returns*: ptr_ != nullptr[.](#observers-14.sentence-1)
[🔗](#observers-itemdecl:6)
`constexpr bool empty() const noexcept;
`
[15](#observers-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2576)
*Returns*: ptr_ == nullptr[.](#observers-15.sentence-1)
#### [23.2.5.5](#modifiers) Modifiers [[container.node.modifiers]](container.node.modifiers)
[🔗](#modifiers-itemdecl:1)
`constexpr void swap(node-handle& nh)
noexcept(ator_traits::propagate_on_container_swap::value ||
ator_traits::is_always_equal::value);
`
[1](#modifiers-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2590)
*Preconditions*: !alloc_, or !nh.alloc_, orator_traits::propagate_on_container_swap::value is true,
or alloc_ == nh.alloc_[.](#modifiers-1.sentence-1)
[2](#modifiers-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L2596)
*Effects*: Calls swap(ptr_, nh.ptr_)[.](#modifiers-2.sentence-1)
If !alloc_, or!nh.alloc_, or ator_traits::propagate_on_container_swap::value is true calls swap(alloc_, nh.alloc_)[.](#modifiers-2.sentence-2)