1031 lines
83 KiB
Markdown
1031 lines
83 KiB
Markdown
[associative]
|
||
|
||
# 23 Containers library [[containers]](./#containers)
|
||
|
||
## 23.4 Associative containers [associative]
|
||
|
||
### [23.4.1](#general) General [[associative.general]](associative.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11363)
|
||
|
||
The header [<map>](#header:%3cmap%3e "23.4.2 Header <map> synopsis [associative.map.syn]") defines the class templatesmap and multimap;
|
||
the header [<set>](#header:%3cset%3e "23.4.5 Header <set> synopsis [associative.set.syn]") defines the class templatesset and multiset[.](#general-1.sentence-1)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11369)
|
||
|
||
The following exposition-only alias templates may appear in deduction guides for associative containers:template<class InputIterator>using *iter-value-type* =typename iterator_traits<InputIterator>::value_type; // *exposition only*template<class InputIterator>using *iter-key-type* = remove_const_t< tuple_element_t<0, *iter-value-type*<InputIterator>>>; // *exposition only*template<class InputIterator>using *iter-mapped-type* = tuple_element_t<1, *iter-value-type*<InputIterator>>; // *exposition only*template<class InputIterator>using *iter-to-alloc-type* = pair< add_const_t<tuple_element_t<0, *iter-value-type*<InputIterator>>>,
|
||
tuple_element_t<1, *iter-value-type*<InputIterator>>>; // *exposition only*template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") Range>using *range-key-type* = remove_const_t<typename ranges::range_value_t<Range>::first_type>; // *exposition only*template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") Range>using *range-mapped-type* = typename ranges::range_value_t<Range>::second_type; // *exposition only*template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") Range>using *range-to-alloc-type* = pair<add_const_t<typename ranges::range_value_t<Range>::first_type>, typename ranges::range_value_t<Range>::second_type>; // *exposition only*
|
||
|
||
### [23.4.2](#map.syn) Header <map> synopsis [[associative.map.syn]](associative.map.syn)
|
||
|
||
[ð](#header:%3cmap%3e)
|
||
|
||
#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2 Header <initializer_list> synopsis")namespace std {// [[map]](#map "23.4.3 Class template map"), class template maptemplate<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>>class map; template<class Key, class T, class Compare, class Allocator>constexpr bool operator==(const map<Key, T, Compare, Allocator>& x, const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator>constexpr *synth-three-way-result*<pair<const Key, T>>operator<=>(const map<Key, T, Compare, Allocator>& x, const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator>constexpr void swap(map<Key, T, Compare, Allocator>& x,
|
||
map<Key, T, Compare, Allocator>& y)noexcept(noexcept(x.swap(y))); // [[map.erasure]](#map.erasure "23.4.3.5 Erasure"), erasure for maptemplate<class Key, class T, class Compare, class Allocator, class Predicate>constexpr typename map<Key, T, Compare, Allocator>::size_type
|
||
erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // [[multimap]](#multimap "23.4.4 Class template multimap"), class template multimaptemplate<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>>class multimap; template<class Key, class T, class Compare, class Allocator>constexpr bool operator==(const multimap<Key, T, Compare, Allocator>& x, const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator>constexpr *synth-three-way-result*<pair<const Key, T>>operator<=>(const multimap<Key, T, Compare, Allocator>& x, const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator>constexpr void swap(multimap<Key, T, Compare, Allocator>& x,
|
||
multimap<Key, T, Compare, Allocator>& y)noexcept(noexcept(x.swap(y))); // [[multimap.erasure]](#multimap.erasure "23.4.4.4 Erasure"), erasure for multimaptemplate<class Key, class T, class Compare, class Allocator, class Predicate>constexpr typename multimap<Key, T, Compare, Allocator>::size_type
|
||
erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); namespace pmr {template<class Key, class T, class Compare = less<Key>>using map = std::map<Key, T, Compare,
|
||
polymorphic_allocator<pair<const Key, T>>>; template<class Key, class T, class Compare = less<Key>>using multimap = std::multimap<Key, T, Compare,
|
||
polymorphic_allocator<pair<const Key, T>>>; }}
|
||
|
||
### [23.4.3](#map) Class template map [[map]](map)
|
||
|
||
#### [23.4.3.1](#map.overview) Overview [[map.overview]](map.overview)
|
||
|
||
[1](#map.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11467)
|
||
|
||
A map is an associative container that
|
||
supports unique keys (i.e., contains at most one of each key value) and
|
||
provides for fast retrieval of values of another type T based
|
||
on the keys[.](#map.overview-1.sentence-1)
|
||
|
||
The map class supports bidirectional iterators[.](#map.overview-1.sentence-2)
|
||
|
||
[2](#map.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11473)
|
||
|
||
A map meets all of the requirements of
|
||
a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")),
|
||
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")),
|
||
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and
|
||
of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers"))[.](#map.overview-2.sentence-1)
|
||
|
||
Amap also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for unique keys[.](#map.overview-2.sentence-2)
|
||
|
||
This means that amap supports thea_uniq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not thea_eq operations[.](#map.overview-2.sentence-3)
|
||
|
||
For amap<Key,T> thekey_type isKey and thevalue_type ispair<const Key,T>[.](#map.overview-2.sentence-4)
|
||
|
||
Descriptions are provided here only for operations onmap that are not described in one of those tables
|
||
or for operations where there is additional semantic information[.](#map.overview-2.sentence-5)
|
||
|
||
[3](#map.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11506)
|
||
|
||
The types iterator and const_iterator meet
|
||
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#map.overview-3.sentence-1)
|
||
|
||
[ð](#lib:comp,map::value_compare)
|
||
|
||
namespace std {template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>>class map {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair<const Key, T>; using key_compare = Compare; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = *unspecified*; using insert_return_type = *insert-return-type*<iterator, node_type>; class value_compare {protected: Compare comp; constexpr value_compare(Compare c) : comp(c) {}public:constexpr bool operator()(const value_type& x, const value_type& y) const {return comp(x.first, y.first); }}; // [[map.cons]](#map.cons "23.4.3.2 Constructors, copy, and assignment"), construct/copy/destroyconstexpr map() : map(Compare()) { }constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator>constexpr map(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr map(const map& x); constexpr map(map&& x); explicit map(const Allocator&); constexpr map(const map&, const type_identity_t<Allocator>&); constexpr map(map&&, const type_identity_t<Allocator>&); constexpr map(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator>constexpr map(InputIterator first, InputIterator last, const Allocator& a): map(first, last, Compare(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr map(from_range_t, R&& rg, const Allocator& a): map(from_range, std::forward<R>(rg), Compare(), a) { }constexpr map(initializer_list<value_type> il, const Allocator& a): map(il, Compare(), a) { }constexpr ~map(); constexpr map& operator=(const map& x); constexpr map& operator=(map&& x)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr map& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [[map.access]](#map.access "23.4.3.3 Element access"), element accessconstexpr mapped_type& operator[](const key_type& x); constexpr mapped_type& operator[](key_type&& x); template<class K> constexpr mapped_type& operator[](K&& x); constexpr mapped_type& at(const key_type& x); constexpr const mapped_type& at(const key_type& x) const; template<class K> constexpr mapped_type& at(const K& x); template<class K> constexpr const mapped_type& at(const K& x) const; // [[map.modifiers]](#map.modifiers "23.4.3.4 Modifiers"), modifierstemplate<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args>constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair<iterator, bool> insert(const value_type& x); constexpr pair<iterator, bool> insert(value_type&& x); template<class P> constexpr pair<iterator, bool> insert(P&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class P>constexpr iterator insert(const_iterator position, P&&); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); template<class... Args>constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args>constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class K, class... Args>constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class... Args>constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args>constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template<class K, class... Args>constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template<class M>constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M>constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class K, class M>constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class M>constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M>constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template<class K, class M>constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); constexpr iterator erase(iterator position); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(map&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2>constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2>constexpr void merge(map<Key, T, C2, Allocator>&& source); template<class C2>constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2>constexpr void merge(multimap<Key, T, C2, Allocator>&& source); // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // map operationsconstexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K>constexpr pair<iterator, iterator> equal_range(const K& x); template<class K>constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>, class Allocator = allocator<*iter-to-alloc-type*<InputIterator>>> map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())-> map<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>, Compare, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Compare = less<*range-key-type*<R>, class Allocator = allocator<*range-to-alloc-type*<R>>> map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> map<*range-key-type*<R>, *range-mapped-type*<R>, Compare, Allocator>; template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> map(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())-> map<Key, T, Compare, Allocator>; template<class InputIterator, class Allocator> map(InputIterator, InputIterator, Allocator)-> map<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>,
|
||
less<*iter-key-type*<InputIterator>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator> map(from_range_t, R&&, Allocator)-> map<*range-key-type*<R>, *range-mapped-type*<R>, less<*range-key-type*<R>>, Allocator>; template<class Key, class T, class Allocator> map(initializer_list<pair<Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>;}
|
||
|
||
#### [23.4.3.2](#map.cons) Constructors, copy, and assignment [[map.cons]](map.cons)
|
||
|
||
[ð](#lib:map,constructor)
|
||
|
||
`constexpr explicit map(const Compare& comp, const Allocator& = Allocator());
|
||
`
|
||
|
||
[1](#map.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11751)
|
||
|
||
*Effects*: Constructs an emptymap using the specified comparison object and allocator[.](#map.cons-1.sentence-1)
|
||
|
||
[2](#map.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11757)
|
||
|
||
*Complexity*: Constant[.](#map.cons-2.sentence-1)
|
||
|
||
[ð](#lib:map,constructor_)
|
||
|
||
`template<class InputIterator>
|
||
constexpr map(InputIterator first, InputIterator last,
|
||
const Compare& comp = Compare(), const Allocator& = Allocator());
|
||
`
|
||
|
||
[3](#map.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11770)
|
||
|
||
*Effects*: Constructs an emptymap using the specified comparison object and allocator,
|
||
and inserts elements from the range
|
||
[first, last)[.](#map.cons-3.sentence-1)
|
||
|
||
[4](#map.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11778)
|
||
|
||
*Complexity*: Linear in N if the range
|
||
[first, last)
|
||
is already sorted with respect to comp and otherwise NlogN, where N is last - first[.](#map.cons-4.sentence-1)
|
||
|
||
[ð](#lib:map,constructor__)
|
||
|
||
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>
|
||
constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(),
|
||
const Allocator& = Allocator());
|
||
`
|
||
|
||
[5](#map.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11795)
|
||
|
||
*Effects*: Constructs an empty map using the specified comparison object and allocator,
|
||
and inserts elements from the range rg[.](#map.cons-5.sentence-1)
|
||
|
||
[6](#map.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11801)
|
||
|
||
*Complexity*: Linear in N if rg is already sorted with respect to comp and
|
||
otherwise NlogN, where N is ranges::distance(rg)[.](#map.cons-6.sentence-1)
|
||
|
||
#### [23.4.3.3](#map.access) Element access [[map.access]](map.access)
|
||
|
||
[ð](#lib:operator%5b%5d,map)
|
||
|
||
`constexpr mapped_type& operator[](const key_type& x);
|
||
`
|
||
|
||
[1](#map.access-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11815)
|
||
|
||
*Effects*: Equivalent to: return try_emplace(x).first->second;
|
||
|
||
[ð](#lib:operator%5b%5d,map_)
|
||
|
||
`constexpr mapped_type& operator[](key_type&& x);
|
||
`
|
||
|
||
[2](#map.access-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11826)
|
||
|
||
*Effects*: Equivalent to: return try_emplace(std::move(x)).first->second;
|
||
|
||
[ð](#lib:operator%5b%5d,map__)
|
||
|
||
`template<class K> constexpr mapped_type& operator[](K&& x);
|
||
`
|
||
|
||
[3](#map.access-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11837)
|
||
|
||
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#map.access-3.sentence-1)
|
||
|
||
[4](#map.access-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11842)
|
||
|
||
*Effects*: Equivalent to: return try_emplace(std::forward<K>(x)).first->second;
|
||
|
||
[ð](#lib:at,map)
|
||
|
||
`constexpr mapped_type& at(const key_type& x);
|
||
constexpr const mapped_type& at(const key_type& x) const;
|
||
`
|
||
|
||
[5](#map.access-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11854)
|
||
|
||
*Returns*: A reference to the mapped_type corresponding to x in *this[.](#map.access-5.sentence-1)
|
||
|
||
[6](#map.access-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11858)
|
||
|
||
*Throws*: An exception object of type out_of_range if
|
||
no such element is present[.](#map.access-6.sentence-1)
|
||
|
||
[7](#map.access-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11863)
|
||
|
||
*Complexity*: Logarithmic[.](#map.access-7.sentence-1)
|
||
|
||
[ð](#lib:at,map_)
|
||
|
||
`template<class K> constexpr mapped_type& at(const K& x);
|
||
template<class K> constexpr const mapped_type& at(const K& x) const;
|
||
`
|
||
|
||
[8](#map.access-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11875)
|
||
|
||
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#map.access-8.sentence-1)
|
||
|
||
[9](#map.access-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11880)
|
||
|
||
*Preconditions*: The expression find(x) is well-formed and has well-defined behavior[.](#map.access-9.sentence-1)
|
||
|
||
[10](#map.access-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11884)
|
||
|
||
*Returns*: A reference to find(x)->second[.](#map.access-10.sentence-1)
|
||
|
||
[11](#map.access-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11888)
|
||
|
||
*Throws*: An exception object of type out_of_range iffind(x) == end() is true[.](#map.access-11.sentence-1)
|
||
|
||
[12](#map.access-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11893)
|
||
|
||
*Complexity*: Logarithmic[.](#map.access-12.sentence-1)
|
||
|
||
#### [23.4.3.4](#map.modifiers) Modifiers [[map.modifiers]](map.modifiers)
|
||
|
||
[ð](#lib:insert,map)
|
||
|
||
`template<class P>
|
||
constexpr pair<iterator, bool> insert(P&& x);
|
||
template<class P>
|
||
constexpr iterator insert(const_iterator position, P&& x);
|
||
`
|
||
|
||
[1](#map.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11909)
|
||
|
||
*Constraints*: is_constructible_v<value_type, P&&> is true[.](#map.modifiers-1.sentence-1)
|
||
|
||
[2](#map.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11913)
|
||
|
||
*Effects*: The first form is equivalent toreturn emplace(std::forward<P>(x))[.](#map.modifiers-2.sentence-1)
|
||
|
||
The second form is
|
||
equivalent to return emplace_hint(position, std::forward<P>(x))[.](#map.modifiers-2.sentence-2)
|
||
|
||
[ð](#lib:try_emplace,map)
|
||
|
||
`template<class... Args>
|
||
constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
|
||
template<class... Args>
|
||
constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
|
||
`
|
||
|
||
[3](#map.modifiers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11929)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from piecewise_construct, forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-3.sentence-1)
|
||
|
||
[4](#map.modifiers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11935)
|
||
|
||
*Effects*: If the map already contains an element
|
||
whose key is equivalent to k,
|
||
there is no effect[.](#map.modifiers-4.sentence-1)
|
||
|
||
Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(k),forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-4.sentence-2)
|
||
|
||
[5](#map.modifiers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11944)
|
||
|
||
*Returns*: In the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-5.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-5.sentence-2)
|
||
|
||
[6](#map.modifiers-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11952)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint,
|
||
respectively[.](#map.modifiers-6.sentence-1)
|
||
|
||
[ð](#lib:try_emplace,map_)
|
||
|
||
`template<class... Args>
|
||
constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args);
|
||
template<class... Args>
|
||
constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
|
||
`
|
||
|
||
[7](#map.modifiers-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11967)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from piecewise_construct, forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-7.sentence-1)
|
||
|
||
[8](#map.modifiers-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11973)
|
||
|
||
*Effects*: If the map already contains an element
|
||
whose key is equivalent to k,
|
||
there is no effect[.](#map.modifiers-8.sentence-1)
|
||
|
||
Otherwise inserts an object of type value_type constructed with piecewise_construct, forward_as_tuple(std::move(k)),forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-8.sentence-2)
|
||
|
||
[9](#map.modifiers-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11982)
|
||
|
||
*Returns*: In the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-9.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-9.sentence-2)
|
||
|
||
[10](#map.modifiers-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L11990)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint,
|
||
respectively[.](#map.modifiers-10.sentence-1)
|
||
|
||
[ð](#lib:try_emplace,map__)
|
||
|
||
`template<class K, class... Args>
|
||
constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args);
|
||
template<class K, class... Args>
|
||
constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args);
|
||
`
|
||
|
||
[11](#map.modifiers-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12005)
|
||
|
||
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#map.modifiers-11.sentence-1)
|
||
|
||
For the first overload,is_convertible_v<K&&, const_iterator> andis_convertible_v<K&&, iterator> are both false[.](#map.modifiers-11.sentence-2)
|
||
|
||
[12](#map.modifiers-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12014)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map frompiecewise_construct, forward_as_tuple(std::forward<K>(k)),
|
||
forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-12.sentence-1)
|
||
|
||
[13](#map.modifiers-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12020)
|
||
|
||
*Effects*: If the map already contains an element whose key is equivalent to k,
|
||
there is no effect[.](#map.modifiers-13.sentence-1)
|
||
|
||
Otherwise, let r be equal_range(k)[.](#map.modifiers-13.sentence-2)
|
||
|
||
Constructs an object u of type value_type withpiecewise_construct, forward_as_tuple(std::forward<K>(k)),
|
||
forward_as_tuple(std::forward<Args>(args)...)[.](#map.modifiers-13.sentence-3)
|
||
|
||
If equal_range(u.first) == r is false,
|
||
the behavior is undefined[.](#map.modifiers-13.sentence-4)
|
||
|
||
Inserts u into *this[.](#map.modifiers-13.sentence-5)
|
||
|
||
[14](#map.modifiers-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12032)
|
||
|
||
*Returns*: For the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-14.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-14.sentence-2)
|
||
|
||
[15](#map.modifiers-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12040)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint, respectively[.](#map.modifiers-15.sentence-1)
|
||
|
||
[ð](#lib:insert_or_assign,map)
|
||
|
||
`template<class M>
|
||
constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj);
|
||
template<class M>
|
||
constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
|
||
`
|
||
|
||
[16](#map.modifiers-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12054)
|
||
|
||
*Mandates*: is_assignable_v<mapped_type&, M&&> is true[.](#map.modifiers-16.sentence-1)
|
||
|
||
[17](#map.modifiers-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12058)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from k, std::forward<M>(obj)[.](#map.modifiers-17.sentence-1)
|
||
|
||
[18](#map.modifiers-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12063)
|
||
|
||
*Effects*: If the map already contains an element e whose key is equivalent to k,
|
||
assigns std::forward<M>(obj) to e.second[.](#map.modifiers-18.sentence-1)
|
||
|
||
Otherwise inserts an object of type value_type constructed with k, std::forward<M>(obj)[.](#map.modifiers-18.sentence-2)
|
||
|
||
[19](#map.modifiers-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12071)
|
||
|
||
*Returns*: In the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-19.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-19.sentence-2)
|
||
|
||
[20](#map.modifiers-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12079)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint,
|
||
respectively[.](#map.modifiers-20.sentence-1)
|
||
|
||
[ð](#lib:insert_or_assign,map_)
|
||
|
||
`template<class M>
|
||
constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj);
|
||
template<class M>
|
||
constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
|
||
`
|
||
|
||
[21](#map.modifiers-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12094)
|
||
|
||
*Mandates*: is_assignable_v<mapped_type&, M&&> is true[.](#map.modifiers-21.sentence-1)
|
||
|
||
[22](#map.modifiers-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12098)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map from std::move(k), std::forward<M>(obj)[.](#map.modifiers-22.sentence-1)
|
||
|
||
[23](#map.modifiers-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12103)
|
||
|
||
*Effects*: If the map already contains an element e whose key is equivalent to k,
|
||
assigns std::forward<M>(obj) to e.second[.](#map.modifiers-23.sentence-1)
|
||
|
||
Otherwise inserts an object of type value_type constructed with std::move(k), std::forward<M>(obj)[.](#map.modifiers-23.sentence-2)
|
||
|
||
[24](#map.modifiers-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12111)
|
||
|
||
*Returns*: In the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-24.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-24.sentence-2)
|
||
|
||
[25](#map.modifiers-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12119)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint,
|
||
respectively[.](#map.modifiers-25.sentence-1)
|
||
|
||
[ð](#lib:insert_or_assign,map__)
|
||
|
||
`template<class K, class M>
|
||
constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj);
|
||
template<class K, class M>
|
||
constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj);
|
||
`
|
||
|
||
[26](#map.modifiers-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12134)
|
||
|
||
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#map.modifiers-26.sentence-1)
|
||
|
||
[27](#map.modifiers-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12139)
|
||
|
||
*Mandates*: is_assignable_v<mapped_type&, M&&> is true[.](#map.modifiers-27.sentence-1)
|
||
|
||
[28](#map.modifiers-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12143)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into map fromstd::forward<K>(k), std::
|
||
forward<M>(obj)[.](#map.modifiers-28.sentence-1)
|
||
|
||
[29](#map.modifiers-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12148)
|
||
|
||
*Effects*: If the map already contains an element e whose key is equivalent to k,
|
||
assigns std::forward<M>
|
||
(obj) to e.second[.](#map.modifiers-29.sentence-1)
|
||
|
||
Otherwise, let r be equal_range(k)[.](#map.modifiers-29.sentence-2)
|
||
|
||
Constructs an object u of type value_type with std::forward<K>(k), std::forward<M>(obj)[.](#map.modifiers-29.sentence-3)
|
||
|
||
If equal_range(u.first) == r is false,
|
||
the behavior is undefined[.](#map.modifiers-29.sentence-4)
|
||
|
||
Inserts u into *this[.](#map.modifiers-29.sentence-5)
|
||
|
||
[30](#map.modifiers-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12160)
|
||
|
||
*Returns*: For the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#map.modifiers-30.sentence-1)
|
||
|
||
The returned iterator points to the map element
|
||
whose key is equivalent to k[.](#map.modifiers-30.sentence-2)
|
||
|
||
[31](#map.modifiers-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12168)
|
||
|
||
*Complexity*: The same as emplace and emplace_hint, respectively[.](#map.modifiers-31.sentence-1)
|
||
|
||
#### [23.4.3.5](#map.erasure) Erasure [[map.erasure]](map.erasure)
|
||
|
||
[ð](#lib:erase_if,map)
|
||
|
||
`template<class Key, class T, class Compare, class Allocator, class Predicate>
|
||
typename map<Key, T, Compare, Allocator>::size_type
|
||
constexpr erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred);
|
||
`
|
||
|
||
[1](#map.erasure-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12183)
|
||
|
||
*Effects*: Equivalent to:auto original_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) { i = c.erase(i); } else {++i; }}return original_size - c.size();
|
||
|
||
### [23.4.4](#multimap) Class template multimap [[multimap]](multimap)
|
||
|
||
#### [23.4.4.1](#multimap.overview) Overview [[multimap.overview]](multimap.overview)
|
||
|
||
[1](#multimap.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12203)
|
||
|
||
Amultimap is an associative container that supports equivalent keys (i.e., possibly containing multiple copies of
|
||
the same key value) and provides for fast retrieval of values of another typeT based on the keys[.](#multimap.overview-1.sentence-1)
|
||
|
||
Themultimap class
|
||
supports bidirectional iterators[.](#multimap.overview-1.sentence-2)
|
||
|
||
[2](#multimap.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12216)
|
||
|
||
A multimap meets all of the requirements
|
||
of a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")),
|
||
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")),
|
||
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and
|
||
of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers"))[.](#multimap.overview-2.sentence-1)
|
||
|
||
Amultimap also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for equal keys[.](#multimap.overview-2.sentence-2)
|
||
|
||
This means that amultimap supports thea_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not thea_uniq operations[.](#multimap.overview-2.sentence-3)
|
||
|
||
For amultimap<Key,T> thekey_type isKey and thevalue_type ispair<const Key,T>[.](#multimap.overview-2.sentence-4)
|
||
|
||
Descriptions are provided here only for operations onmultimap that are not described in one of those tables
|
||
or for operations where there is additional semantic information[.](#multimap.overview-2.sentence-5)
|
||
|
||
[3](#multimap.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12249)
|
||
|
||
The types iterator and const_iterator meet
|
||
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#multimap.overview-3.sentence-1)
|
||
|
||
[ð](#lib:comp,multimap::value_compare)
|
||
|
||
namespace std {template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>>class multimap {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair<const Key, T>; using key_compare = Compare; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = *unspecified*; class value_compare {protected: Compare comp; constexpr value_compare(Compare c) : comp(c) { }public:constexpr bool operator()(const value_type& x, const value_type& y) const {return comp(x.first, y.first); }}; // [[multimap.cons]](#multimap.cons "23.4.4.2 Constructors"), construct/copy/destroyconstexpr multimap() : multimap(Compare()) { }constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator>constexpr multimap(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr multimap(const multimap& x); constexpr multimap(multimap&& x); constexpr explicit multimap(const Allocator&); constexpr multimap(const multimap&, const type_identity_t<Allocator>&); constexpr multimap(multimap&&, const type_identity_t<Allocator>&); constexpr multimap(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator>constexpr multimap(InputIterator first, InputIterator last, const Allocator& a): multimap(first, last, Compare(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr multimap(from_range_t, R&& rg, const Allocator& a)): multimap(from_range, std::forward<R>(rg), Compare(), a) { }constexpr multimap(initializer_list<value_type> il, const Allocator& a): multimap(il, Compare(), a) { }constexpr ~multimap(); constexpr multimap& operator=(const multimap& x); constexpr multimap& operator=(multimap&& x)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr multimap& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [[multimap.modifiers]](#multimap.modifiers "23.4.4.3 Modifiers"), modifierstemplate<class... Args> constexpr iterator emplace(Args&&... args); template<class... Args>constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr iterator insert(const value_type& x); constexpr iterator insert(value_type&& x); template<class P> constexpr iterator insert(P&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class P> constexpr iterator insert(const_iterator position, P&& x); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> node_type extract(K&& x); constexpr iterator insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(multimap&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2>constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2>constexpr void merge(multimap<Key, T, C2, Allocator>&& source); template<class C2>constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2>constexpr void merge(map<Key, T, C2, Allocator>&& source); // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // map operationsconstexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K>constexpr pair<iterator, iterator> equal_range(const K& x); template<class K>constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>, class Allocator = allocator<*iter-to-alloc-type*<InputIterator>>> multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())-> multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>,
|
||
Compare, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Compare = less<*range-key-type*<R>>, class Allocator = allocator<*range-to-alloc-type*<R>>> multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> multimap<*range-key-type*<R>, *range-mapped-type*<R>, Compare, Allocator>; template<class Key, class T, class Compare = less<Key>, class Allocator = allocator<pair<const Key, T>>> multimap(initializer_list<pair<Key, T>>, Compare = Compare(), Allocator = Allocator())-> multimap<Key, T, Compare, Allocator>; template<class InputIterator, class Allocator> multimap(InputIterator, InputIterator, Allocator)-> multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>,
|
||
less<*iter-key-type*<InputIterator>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator> multimap(from_range_t, R&&, Allocator)-> multimap<*range-key-type*<R>, *range-mapped-type*<R>, less<*range-key-type*<R>>, Allocator>; template<class Key, class T, class Allocator> multimap(initializer_list<pair<Key, T>>, Allocator)-> multimap<Key, T, less<Key>, Allocator>;}
|
||
|
||
#### [23.4.4.2](#multimap.cons) Constructors [[multimap.cons]](multimap.cons)
|
||
|
||
[ð](#lib:multimap,constructor)
|
||
|
||
`constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator());
|
||
`
|
||
|
||
[1](#multimap.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12459)
|
||
|
||
*Effects*: Constructs an emptymultimap using the specified comparison object and allocator[.](#multimap.cons-1.sentence-1)
|
||
|
||
[2](#multimap.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12465)
|
||
|
||
*Complexity*: Constant[.](#multimap.cons-2.sentence-1)
|
||
|
||
[ð](#lib:multimap,constructor_)
|
||
|
||
`template<class InputIterator>
|
||
constexpr multimap(InputIterator first, InputIterator last,
|
||
const Compare& comp = Compare(), const Allocator& = Allocator());
|
||
`
|
||
|
||
[3](#multimap.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12478)
|
||
|
||
*Effects*: Constructs an emptymultimap using the specified comparison object and allocator,
|
||
and inserts elements from the range
|
||
[first, last)[.](#multimap.cons-3.sentence-1)
|
||
|
||
[4](#multimap.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12486)
|
||
|
||
*Complexity*: Linear in N if the range
|
||
[first, last)
|
||
is already sorted with respect to comp and otherwise NlogN,
|
||
where N islast - first[.](#multimap.cons-4.sentence-1)
|
||
|
||
[ð](#lib:multimap,constructor__)
|
||
|
||
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>
|
||
constexpr multimap(from_range_t, R&& rg,
|
||
const Compare& comp = Compare(), const Allocator& = Allocator());
|
||
`
|
||
|
||
[5](#multimap.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12504)
|
||
|
||
*Effects*: Constructs an empty multimap using the specified comparison object and allocator, and
|
||
inserts elements from the range rg[.](#multimap.cons-5.sentence-1)
|
||
|
||
[6](#multimap.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12510)
|
||
|
||
*Complexity*: Linear in N if rg is already sorted with respect to comp and
|
||
otherwise NlogN, where N is ranges::distance(rg)[.](#multimap.cons-6.sentence-1)
|
||
|
||
#### [23.4.4.3](#multimap.modifiers) Modifiers [[multimap.modifiers]](multimap.modifiers)
|
||
|
||
[ð](#lib:insert,multimap)
|
||
|
||
`template<class P> constexpr iterator insert(P&& x);
|
||
template<class P> constexpr iterator insert(const_iterator position, P&& x);
|
||
`
|
||
|
||
[1](#multimap.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12525)
|
||
|
||
*Constraints*: is_constructible_v<value_type, P&&> is true[.](#multimap.modifiers-1.sentence-1)
|
||
|
||
[2](#multimap.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12529)
|
||
|
||
*Effects*: The first form is equivalent toreturn emplace(std::forward<P>(x))[.](#multimap.modifiers-2.sentence-1)
|
||
|
||
The second form is
|
||
equivalent to return emplace_hint(position, std::forward<P>(x))[.](#multimap.modifiers-2.sentence-2)
|
||
|
||
#### [23.4.4.4](#multimap.erasure) Erasure [[multimap.erasure]](multimap.erasure)
|
||
|
||
[ð](#lib:erase_if,multimap)
|
||
|
||
`template<class Key, class T, class Compare, class Allocator, class Predicate>
|
||
typename multimap<Key, T, Compare, Allocator>::size_type
|
||
constexpr erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred);
|
||
`
|
||
|
||
[1](#multimap.erasure-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12546)
|
||
|
||
*Effects*: Equivalent to:auto original_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) { i = c.erase(i); } else {++i; }}return original_size - c.size();
|
||
|
||
### [23.4.5](#set.syn) Header <set> synopsis [[associative.set.syn]](associative.set.syn)
|
||
|
||
[ð](#header:%3cset%3e)
|
||
|
||
#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2 Header <initializer_list> synopsis")namespace std {// [[set]](#set "23.4.6 Class template set"), class template settemplate<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>class set; template<class Key, class Compare, class Allocator>constexpr bool operator==(const set<Key, Compare, Allocator>& x, const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator>constexpr *synth-three-way-result*<Key> operator<=>(const set<Key, Compare, Allocator>& x, const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator>constexpr void swap(set<Key, Compare, Allocator>& x,
|
||
set<Key, Compare, Allocator>& y)noexcept(noexcept(x.swap(y))); // [[set.erasure]](#set.erasure "23.4.6.3 Erasure"), erasure for settemplate<class Key, class Compare, class Allocator, class Predicate>constexpr typename set<Key, Compare, Allocator>::size_type
|
||
erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // [[multiset]](#multiset "23.4.7 Class template multiset"), class template multisettemplate<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>class multiset; template<class Key, class Compare, class Allocator>constexpr bool operator==(const multiset<Key, Compare, Allocator>& x, const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator>constexpr *synth-three-way-result*<Key>operator<=>(const multiset<Key, Compare, Allocator>& x, const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator>constexpr void swap(multiset<Key, Compare, Allocator>& x,
|
||
multiset<Key, Compare, Allocator>& y)noexcept(noexcept(x.swap(y))); // [[multiset.erasure]](#multiset.erasure "23.4.7.3 Erasure"), erasure for multisettemplate<class Key, class Compare, class Allocator, class Predicate>constexpr typename multiset<Key, Compare, Allocator>::size_type
|
||
erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); namespace pmr {template<class Key, class Compare = less<Key>>using set = std::set<Key, Compare, polymorphic_allocator<Key>>; template<class Key, class Compare = less<Key>>using multiset = std::multiset<Key, Compare, polymorphic_allocator<Key>>; }}
|
||
|
||
### [23.4.6](#set) Class template set [[set]](set)
|
||
|
||
#### [23.4.6.1](#set.overview) Overview [[set.overview]](set.overview)
|
||
|
||
[1](#set.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12627)
|
||
|
||
Aset is an associative container that supports unique keys (i.e., contains at most one of each key value) and
|
||
provides for fast retrieval of the keys themselves[.](#set.overview-1.sentence-1)
|
||
|
||
Theset class
|
||
supports bidirectional iterators[.](#set.overview-1.sentence-2)
|
||
|
||
[2](#set.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12637)
|
||
|
||
A set meets all of the requirements
|
||
of a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")),
|
||
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")),
|
||
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and
|
||
of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers"))[.](#set.overview-2.sentence-1)
|
||
|
||
Aset also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for unique keys[.](#set.overview-2.sentence-2)
|
||
|
||
This means that aset supports thea_uniq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not thea_eq operations[.](#set.overview-2.sentence-3)
|
||
|
||
For aset<Key> both thekey_type andvalue_type areKey[.](#set.overview-2.sentence-4)
|
||
|
||
Descriptions are provided here only for operations onset that are not described in one of these tables
|
||
and for operations where there is additional semantic information[.](#set.overview-2.sentence-5)
|
||
|
||
[3](#set.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12668)
|
||
|
||
The types iterator and const_iterator meet
|
||
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#set.overview-3.sentence-1)
|
||
|
||
namespace std {template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>class set {public:// typesusing key_type = Key; using key_compare = Compare; using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = *unspecified*; using insert_return_type = *insert-return-type*<iterator, node_type>; // [[set.cons]](#set.cons "23.4.6.2 Constructors, copy, and assignment"), construct/copy/destroyconstexpr set() : set(Compare()) { }constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator>constexpr set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr set(const set& x); constexpr set(set&& x); constexpr explicit set(const Allocator&); constexpr set(const set&, const type_identity_t<Allocator>&); constexpr set(set&&, const type_identity_t<Allocator>&); constexpr set(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator>constexpr set(InputIterator first, InputIterator last, const Allocator& a): set(first, last, Compare(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr set(from_range_t, R&& rg, const Allocator& a)): set(from_range, std::forward<R>(rg), Compare(), a) { }constexpr set(initializer_list<value_type> il, const Allocator& a): set(il, Compare(), a) { }constexpr ~set(); constexpr set& operator=(const set& x); constexpr set& operator=(set&& x)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr set& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // [[set.modifiers]](#set.modifiers "23.4.6.4 Modifiers"), modifierstemplate<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args>constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr pair<iterator,bool> insert(const value_type& x); constexpr pair<iterator,bool> insert(value_type&& x); template<class K> constexpr pair<iterator, bool> insert(K&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class K> constexpr iterator insert(const_iterator position, K&& x); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr insert_return_type insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position)requires (<iterator, const_iterator>); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(set&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2>constexpr void merge(set<Key, C2, Allocator>& source); template<class C2>constexpr void merge(set<Key, C2, Allocator>&& source); template<class C2>constexpr void merge(multiset<Key, C2, Allocator>& source); template<class C2>constexpr void merge(multiset<Key, C2, Allocator>&& source); // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // set operationsconstexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K>constexpr pair<iterator, iterator> equal_range(const K& x); template<class K>constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<*iter-value-type*<InputIterator>>, class Allocator = allocator<*iter-value-type*<InputIterator>>> set(InputIterator, InputIterator,
|
||
Compare = Compare(), Allocator = Allocator())-> set<*iter-value-type*<InputIterator>, Compare, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Compare = less<ranges::range_value_t<R>>, class Allocator = allocator<ranges::range_value_t<R>>> set(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> set<ranges::range_value_t<R>, Compare, Allocator>; template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> set(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())-> set<Key, Compare, Allocator>; template<class InputIterator, class Allocator> set(InputIterator, InputIterator, Allocator)-> set<*iter-value-type*<InputIterator>,
|
||
less<*iter-value-type*<InputIterator>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator> set(from_range_t, R&&, Allocator)-> set<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; template<class Key, class Allocator> set(initializer_list<Key>, Allocator) -> set<Key, less<Key>, Allocator>;}
|
||
|
||
#### [23.4.6.2](#set.cons) Constructors, copy, and assignment [[set.cons]](set.cons)
|
||
|
||
[ð](#lib:set,constructor)
|
||
|
||
`constexpr explicit set(const Compare& comp, const Allocator& = Allocator());
|
||
`
|
||
|
||
[1](#set.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12866)
|
||
|
||
*Effects*: Constructs an empty set using the specified comparison object and allocator[.](#set.cons-1.sentence-1)
|
||
|
||
[2](#set.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12870)
|
||
|
||
*Complexity*: Constant[.](#set.cons-2.sentence-1)
|
||
|
||
[ð](#lib:set,constructor_)
|
||
|
||
`template<class InputIterator>
|
||
constexpr set(InputIterator first, InputIterator last,
|
||
const Compare& comp = Compare(), const Allocator& = Allocator());
|
||
`
|
||
|
||
[3](#set.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12883)
|
||
|
||
*Effects*: Constructs an emptyset using the specified comparison object and allocator,
|
||
and inserts elements from the range
|
||
[first, last)[.](#set.cons-3.sentence-1)
|
||
|
||
[4](#set.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12891)
|
||
|
||
*Complexity*: Linear in N if the range
|
||
[first, last)
|
||
is already sorted with respect to comp and otherwise NlogN,
|
||
where N islast - first[.](#set.cons-4.sentence-1)
|
||
|
||
[ð](#lib:set,constructor__)
|
||
|
||
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>
|
||
constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(),
|
||
const Allocator& = Allocator());
|
||
`
|
||
|
||
[5](#set.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12909)
|
||
|
||
*Effects*: Constructs an empty set using the specified comparison object and allocator,
|
||
and inserts elements from the range rg[.](#set.cons-5.sentence-1)
|
||
|
||
[6](#set.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12914)
|
||
|
||
*Complexity*: Linear in N if rg is already sorted with respect to comp and
|
||
otherwise NlogN, where N is ranges::distance(rg)[.](#set.cons-6.sentence-1)
|
||
|
||
#### [23.4.6.3](#set.erasure) Erasure [[set.erasure]](set.erasure)
|
||
|
||
[ð](#lib:erase_if,set)
|
||
|
||
`template<class Key, class Compare, class Allocator, class Predicate>
|
||
constexpr typename set<Key, Compare, Allocator>::size_type
|
||
erase_if(set<Key, Compare, Allocator>& c, Predicate pred);
|
||
`
|
||
|
||
[1](#set.erasure-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12930)
|
||
|
||
*Effects*: Equivalent to:auto original_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) { i = c.erase(i); } else {++i; }}return original_size - c.size();
|
||
|
||
#### [23.4.6.4](#set.modifiers) Modifiers [[set.modifiers]](set.modifiers)
|
||
|
||
[ð](#lib:insert,set)
|
||
|
||
`template<class K> constexpr pair<iterator, bool> insert(K&& x);
|
||
template<class K> constexpr iterator insert(const_iterator hint, K&& x);
|
||
`
|
||
|
||
[1](#set.modifiers-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12955)
|
||
|
||
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#set.modifiers-1.sentence-1)
|
||
|
||
For the second overload,is_convertible_v<K&&, const_iterator> andis_convertible_v<K&&, iterator> are both false[.](#set.modifiers-1.sentence-2)
|
||
|
||
[2](#set.modifiers-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12963)
|
||
|
||
*Preconditions*: value_type is *Cpp17EmplaceConstructible* into set fromstd::forward<K>(x)[.](#set.modifiers-2.sentence-1)
|
||
|
||
[3](#set.modifiers-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12968)
|
||
|
||
*Effects*: If the set already contains an element that is equivalent to x,
|
||
there is no effect[.](#set.modifiers-3.sentence-1)
|
||
|
||
Otherwise, let r be equal_range(x)[.](#set.modifiers-3.sentence-2)
|
||
|
||
Constructs an object u of type value_type with std::forward<K>(x)[.](#set.modifiers-3.sentence-3)
|
||
|
||
If equal_range(u) == r is false, the behavior is undefined[.](#set.modifiers-3.sentence-4)
|
||
|
||
Inserts u into *this[.](#set.modifiers-3.sentence-5)
|
||
|
||
[4](#set.modifiers-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12978)
|
||
|
||
*Returns*: For the first overload,
|
||
the bool component of the returned pair is true if and only if the insertion took place[.](#set.modifiers-4.sentence-1)
|
||
|
||
The returned iterator points to the set element that is equivalent to x[.](#set.modifiers-4.sentence-2)
|
||
|
||
[5](#set.modifiers-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12985)
|
||
|
||
*Complexity*: Logarithmic[.](#set.modifiers-5.sentence-1)
|
||
|
||
### [23.4.7](#multiset) Class template multiset [[multiset]](multiset)
|
||
|
||
#### [23.4.7.1](#multiset.overview) Overview [[multiset.overview]](multiset.overview)
|
||
|
||
[1](#multiset.overview-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L12994)
|
||
|
||
Amultiset is an associative container that supports equivalent keys (i.e., possibly contains multiple copies of
|
||
the same key value) and provides for fast retrieval of the keys themselves[.](#multiset.overview-1.sentence-1)
|
||
|
||
Themultiset class
|
||
supports bidirectional iterators[.](#multiset.overview-1.sentence-2)
|
||
|
||
[2](#multiset.overview-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13004)
|
||
|
||
A multiset meets all of the requirements
|
||
of a container ([[container.reqmts]](container.reqmts "23.2.2.2 Container requirements")),
|
||
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3 Reversible container requirements")),
|
||
of an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5 Allocator-aware containers")), and
|
||
of an associative container ([[associative.reqmts]](associative.reqmts "23.2.7 Associative containers"))[.](#multiset.overview-2.sentence-1)
|
||
|
||
multiset also provides most operations described in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") for duplicate keys[.](#multiset.overview-2.sentence-2)
|
||
|
||
This means that amultiset supports thea_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7 Associative containers") but not thea_uniq operations[.](#multiset.overview-2.sentence-3)
|
||
|
||
For amultiset<Key> both thekey_type andvalue_type areKey[.](#multiset.overview-2.sentence-4)
|
||
|
||
Descriptions are provided here only for operations onmultiset that are not described in one of these tables
|
||
and for operations where there is additional semantic information[.](#multiset.overview-2.sentence-5)
|
||
|
||
[3](#multiset.overview-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13034)
|
||
|
||
The types iterator and const_iterator meet
|
||
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General"))[.](#multiset.overview-3.sentence-1)
|
||
|
||
namespace std {template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>>class multiset {public:// typesusing key_type = Key; using key_compare = Compare; using value_type = Key; using value_compare = Compare; using allocator_type = Allocator; using pointer = typename allocator_traits<Allocator>::pointer; using const_pointer = typename allocator_traits<Allocator>::const_pointer; using reference = value_type&; using const_reference = const value_type&; using size_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using difference_type = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2 Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using node_type = *unspecified*; // [[multiset.cons]](#multiset.cons "23.4.7.2 Constructors"), construct/copy/destroyconstexpr multiset() : multiset(Compare()) { }constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator>constexpr multiset(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator()); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); constexpr multiset(const multiset& x); constexpr multiset(multiset&& x); constexpr explicit multiset(const Allocator&); constexpr multiset(const multiset&, const type_identity_t<Allocator>&); constexpr multiset(multiset&&, const type_identity_t<Allocator>&); constexpr multiset(initializer_list<value_type>, const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator>constexpr multiset(InputIterator first, InputIterator last, const Allocator& a): multiset(first, last, Compare(), a) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr multiset(from_range_t, R&& rg, const Allocator& a)): multiset(from_range, std::forward<R>(rg), Compare(), a) { }constexpr multiset(initializer_list<value_type> il, const Allocator& a): multiset(il, Compare(), a) { }constexpr ~multiset(); constexpr multiset& operator=(const multiset& x); constexpr multiset& operator=(multiset&& x)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); constexpr multiset& operator=(initializer_list<value_type>); constexpr allocator_type get_allocator() const noexcept; // iteratorsconstexpr iterator begin() noexcept; constexpr const_iterator begin() const noexcept; constexpr iterator end() noexcept; constexpr const_iterator end() const noexcept; constexpr reverse_iterator rbegin() noexcept; constexpr const_reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() noexcept; constexpr const_reverse_iterator rend() const noexcept; constexpr const_iterator cbegin() const noexcept; constexpr const_iterator cend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept; constexpr const_reverse_iterator crend() const noexcept; // capacityconstexpr bool empty() const noexcept; constexpr size_type size() const noexcept; constexpr size_type max_size() const noexcept; // modifierstemplate<class... Args> constexpr iterator emplace(Args&&... args); template<class... Args>constexpr iterator emplace_hint(const_iterator position, Args&&... args); constexpr iterator insert(const value_type& x); constexpr iterator insert(value_type&& x); constexpr iterator insert(const_iterator position, const value_type& x); constexpr iterator insert(const_iterator position, value_type&& x); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type>); constexpr node_type extract(const_iterator position); constexpr node_type extract(const key_type& x); template<class K> constexpr node_type extract(K&& x); constexpr iterator insert(node_type&& nh); constexpr iterator insert(const_iterator hint, node_type&& nh); constexpr iterator erase(iterator position)requires (<iterator, const_iterator>); constexpr iterator erase(const_iterator position); constexpr size_type erase(const key_type& x); template<class K> constexpr size_type erase(K&& x); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void swap(multiset&)noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); constexpr void clear() noexcept; template<class C2>constexpr void merge(multiset<Key, C2, Allocator>& source); template<class C2>constexpr void merge(multiset<Key, C2, Allocator>&& source); template<class C2>constexpr void merge(set<Key, C2, Allocator>& source); template<class C2>constexpr void merge(set<Key, C2, Allocator>&& source); // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; // set operationsconstexpr iterator find(const key_type& x); constexpr const_iterator find(const key_type& x) const; template<class K> constexpr iterator find(const K& x); template<class K> constexpr const_iterator find(const K& x) const; constexpr size_type count(const key_type& x) const; template<class K> constexpr size_type count(const K& x) const; constexpr bool contains(const key_type& x) const; template<class K> constexpr bool contains(const K& x) const; constexpr iterator lower_bound(const key_type& x); constexpr const_iterator lower_bound(const key_type& x) const; template<class K> constexpr iterator lower_bound(const K& x); template<class K> constexpr const_iterator lower_bound(const K& x) const; constexpr iterator upper_bound(const key_type& x); constexpr const_iterator upper_bound(const key_type& x) const; template<class K> constexpr iterator upper_bound(const K& x); template<class K> constexpr const_iterator upper_bound(const K& x) const; constexpr pair<iterator, iterator> equal_range(const key_type& x); constexpr pair<const_iterator, const_iterator> equal_range(const key_type& x) const; template<class K>constexpr pair<iterator, iterator> equal_range(const K& x); template<class K>constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<*iter-value-type*<InputIterator>>, class Allocator = allocator<*iter-value-type*<InputIterator>>> multiset(InputIterator, InputIterator,
|
||
Compare = Compare(), Allocator = Allocator())-> multiset<*iter-value-type*<InputIterator>, Compare, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Compare = less<ranges::range_value_t<R>>, class Allocator = allocator<ranges::range_value_t<R>>> multiset(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> multiset<ranges::range_value_t<R>, Compare, Allocator>; template<class Key, class Compare = less<Key>, class Allocator = allocator<Key>> multiset(initializer_list<Key>, Compare = Compare(), Allocator = Allocator())-> multiset<Key, Compare, Allocator>; template<class InputIterator, class Allocator> multiset(InputIterator, InputIterator, Allocator)-> multiset<*iter-value-type*<InputIterator>,
|
||
less<*iter-value-type*<InputIterator>>, Allocator>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") R, class Allocator> multiset(from_range_t, R&&, Allocator)-> multiset<ranges::range_value_t<R>, less<ranges::range_value_t<R>>, Allocator>; template<class Key, class Allocator> multiset(initializer_list<Key>, Allocator) -> multiset<Key, less<Key>, Allocator>;}
|
||
|
||
#### [23.4.7.2](#multiset.cons) Constructors [[multiset.cons]](multiset.cons)
|
||
|
||
[ð](#lib:multiset,constructor)
|
||
|
||
`constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator());
|
||
`
|
||
|
||
[1](#multiset.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13229)
|
||
|
||
*Effects*: Constructs an empty multiset using the specified comparison object and allocator[.](#multiset.cons-1.sentence-1)
|
||
|
||
[2](#multiset.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13233)
|
||
|
||
*Complexity*: Constant[.](#multiset.cons-2.sentence-1)
|
||
|
||
[ð](#lib:multiset,constructor_)
|
||
|
||
`template<class InputIterator>
|
||
constexpr multiset(InputIterator first, InputIterator last,
|
||
const Compare& comp = Compare(), const Allocator& = Allocator());
|
||
`
|
||
|
||
[3](#multiset.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13246)
|
||
|
||
*Effects*: Constructs an emptymultiset using the specified comparison object and allocator,
|
||
and inserts elements from the range
|
||
[first, last)[.](#multiset.cons-3.sentence-1)
|
||
|
||
[4](#multiset.cons-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13254)
|
||
|
||
*Complexity*: Linear in N if the range
|
||
[first, last)
|
||
is already sorted with respect to comp and otherwise NlogN,
|
||
where N islast - first[.](#multiset.cons-4.sentence-1)
|
||
|
||
[ð](#lib:multiset,constructor__)
|
||
|
||
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1 Introduction [container.intro.reqmts]")<value_type> R>
|
||
constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(),
|
||
const Allocator& = Allocator());
|
||
`
|
||
|
||
[5](#multiset.cons-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13272)
|
||
|
||
*Effects*: Constructs an empty multiset using the specified comparison object and allocator, and
|
||
inserts elements from the range rg[.](#multiset.cons-5.sentence-1)
|
||
|
||
[6](#multiset.cons-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13278)
|
||
|
||
*Complexity*: Linear in N if rg is already sorted with respect to comp and
|
||
otherwise NlogN, where N is ranges::distance(rg)[.](#multiset.cons-6.sentence-1)
|
||
|
||
#### [23.4.7.3](#multiset.erasure) Erasure [[multiset.erasure]](multiset.erasure)
|
||
|
||
[ð](#lib:erase_if,multiset)
|
||
|
||
`template<class Key, class Compare, class Allocator, class Predicate>
|
||
constexpr typename multiset<Key, Compare, Allocator>::size_type
|
||
erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred);
|
||
`
|
||
|
||
[1](#multiset.erasure-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L13294)
|
||
|
||
*Effects*: Equivalent to:auto original_size = c.size();for (auto i = c.begin(), last = c.end(); i != last; ) {if (pred(*i)) { i = c.erase(i); } else {++i; }}return original_size - c.size();
|