293 lines
12 KiB
Markdown
293 lines
12 KiB
Markdown
[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.1 Overview [container.node.overview]") is an object that accepts ownership of a single element
|
||
from an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers")) or an unordered
|
||
associative container ([[unord.req]](unord.req "23.2.8 Unordered 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.7 Associative containers") and [[unord.req]](unord.req "23.2.8 Unordered 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.2 Constructors, 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.3 Destructor"), destructorconstexpr ~*node-handle*(); // [[container.node.observers]](#observers "23.2.5.4 Observers"), 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.5 Modifiers"), 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)
|