This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

909
cppdraft/flat/map.md Normal file

File diff suppressed because one or more lines are too long

111
cppdraft/flat/map/access.md Normal file
View File

@@ -0,0 +1,111 @@
[flat.map.access]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.access)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#access)
#### 23.6.8.6 Access [flat.map.access]
[🔗](#lib:operator%5b%5d,flat_map)
`constexpr mapped_type& operator[](const key_type& x);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17597)
*Effects*: Equivalent to: return try_emplace(x).first->second;
[🔗](#lib:operator%5b%5d,flat_map_)
`constexpr mapped_type& operator[](key_type&& x);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17608)
*Effects*: Equivalent to: return try_emplace(std::move(x)).first->second;
[🔗](#lib:operator%5b%5d,flat_map__)
`template<class K> constexpr mapped_type& operator[](K&& x);
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17619)
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Compare::is_transparent is valid and
denotes a type[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17624)
*Effects*: Equivalent to: return try_emplace(std::forward<K>(x)).first->second;
[🔗](#lib:at,flat_map)
`constexpr mapped_type& at(const key_type& x);
constexpr const mapped_type& at(const key_type& x) const;
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17636)
*Returns*: A reference to the mapped_type corresponding
to x in *this[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17641)
*Throws*: An exception object of type out_of_range if
no such element is present[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17646)
*Complexity*: Logarithmic[.](#7.sentence-1)
[🔗](#lib:at,flat_map_)
`template<class K> constexpr mapped_type& at(const K& x);
template<class K> constexpr const mapped_type& at(const K& x) const;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17658)
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17663)
*Preconditions*: The expression find(x) is well-formed and has well-defined behavior[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17667)
*Returns*: A reference to the mapped_type corresponding tox in *this[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17672)
*Throws*: An exception object of type out_of_range if no such element is present[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17677)
*Complexity*: Logarithmic[.](#12.sentence-1)

View File

@@ -0,0 +1,31 @@
[flat.map.capacity]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.capacity)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#capacity)
#### 23.6.8.5 Capacity [flat.map.capacity]
[🔗](#lib:size,flat_map)
`constexpr size_type size() const noexcept;
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17573)
*Returns*: *c*.keys.size()[.](#1.sentence-1)
[🔗](#lib:max_size,flat_map)
`constexpr size_type max_size() const noexcept;
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17584)
*Returns*: min<size_type>(*c*.keys.max_size(), *c*.values.max_size())[.](#2.sentence-1)

49
cppdraft/flat/map/cons.md Normal file
View File

@@ -0,0 +1,49 @@
[flat.map.cons]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.cons)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#cons)
#### 23.6.8.3 Constructors [flat.map.cons]
[🔗](#lib:flat_map,constructor)
`constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17425)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp;
sorts the range [begin(), end()) with respect to value_comp(); and
finally erases the duplicate elements as if by:auto zv = views::zip(*c*.keys, *c*.values);auto it = ranges::unique(zv, *key-equiv*(*compare*)).begin();auto dist = distance(zv.begin(), it);*c*.keys.erase(*c*.keys.begin() + dist, *c*.keys.end());*c*.values.erase(*c*.values.begin() + dist, *c*.values.end());
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17441)
*Complexity*: Linear in N if the container arguments are already sorted
with respect to value_comp() and otherwise NlogN,
where N is the value of key_cont.size() before this call[.](#2.sentence-1)
[🔗](#lib:flat_map,constructor_)
`constexpr flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17455)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17462)
*Complexity*: Constant[.](#4.sentence-1)

View File

@@ -0,0 +1,108 @@
[flat.map.cons.alloc]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.cons.alloc)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#cons.alloc)
#### 23.6.8.4 Constructors with allocators [flat.map.cons.alloc]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17469)
The constructors in this subclause shall not participate in overload resolution
unless uses_allocator_v<key_container_type, Alloc> is true and uses_allocator_v<mapped_container_type, Alloc> is true[.](#1.sentence-1)
[🔗](#lib:flat_map,constructor)
`template<class Alloc>
constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
const Alloc& a);
template<class Alloc>
constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont,
const key_compare& comp, const Alloc& a);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17485)
*Effects*: Equivalent to flat_map(key_cont, mapped_cont) andflat_map(key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17492)
*Complexity*: Same as flat_map(key_cont, mapped_cont) andflat_map(key_cont, mapped_cont, comp), respectively[.](#3.sentence-1)
[🔗](#lib:flat_map,constructor_)
`template<class Alloc>
constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const Alloc& a);
template<class Alloc>
constexpr flat_map(sorted_unique_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const key_compare& comp,
const Alloc& a);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17510)
*Effects*: Equivalent to flat_map(sorted_unique, key_cont, mapped_cont) andflat_map(sorted_unique, key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17517)
*Complexity*: Linear[.](#5.sentence-1)
[🔗](#lib:flat_map,constructor__)
`template<class Alloc>
constexpr explicit flat_map(const Alloc& a);
template<class Alloc>
constexpr flat_map(const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_map(const flat_map&, const Alloc& a);
template<class Alloc>
constexpr flat_map(flat_map&&, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_map(from_range_t, R&& rg, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_map(initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_map(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_map(sorted_unique_t, initializer_list<value_type> il,
const key_compare& comp, const Alloc& a);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17558)
*Effects*: Equivalent to the corresponding non-allocator constructors
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#6.sentence-1)

32
cppdraft/flat/map/defn.md Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,58 @@
[flat.map.erasure]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.erasure)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#erasure)
#### 23.6.8.8 Erasure [flat.map.erasure]
[🔗](#lib:erase_if,flat_map)
`template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
class Predicate>
constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18116)
*Preconditions*: Key and T meet the *Cpp17MoveAssignable* requirements[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18120)
*Effects*: Let E be bool(pred(pair<const Key&, const T&>(e)))[.](#2.sentence-1)
Erases all elements e in c for which E holds[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18125)
*Returns*: The number of elements erased[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18129)
*Complexity*: Exactly c.size() applications of the predicate[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18133)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#5.sentence-1)
If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67valid but unspecified state"))[.](#5.sentence-2)
[*Note [1](#note-1)*:
c still meets its invariants,
but can be empty[.](#5.sentence-3)
— *end note*]

View File

@@ -0,0 +1,407 @@
[flat.map.modifiers]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.modifiers)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#modifiers)
#### 23.6.8.7 Modifiers [flat.map.modifiers]
[🔗](#lib:emplace,flat_map)
`template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17690)
*Constraints*: is_constructible_v<pair<key_type, mapped_type>, Args...> is true[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17694)
*Effects*: Initializes an object t of type pair<key_type, mapped_type> with std::forward<Args>(args)...;
if the map already contains an element
whose key is equivalent to t.first,*this is unchanged[.](#2.sentence-1)
Otherwise, equivalent to:auto key_it = ranges::upper_bound(*c*.keys, t.first, *compare*);auto value_it = *c*.values.begin() + distance(*c*.keys.begin(), key_it);*c*.keys.insert(key_it, std::move(t.first));*c*.values.insert(value_it, std::move(t.second));
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17709)
*Returns*: The bool component of the returned pair is true if and only if the insertion took place, and
the iterator component of the pair points to
the element with key equivalent to t.first[.](#3.sentence-1)
[🔗](#lib:insert,flat_map)
`template<class P> constexpr pair<iterator, bool> insert(P&& x);
template<class P> constexpr iterator insert(const_iterator position, P&& x);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17724)
*Constraints*: is_constructible_v<pair<key_type, mapped_type>, P> is true[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17728)
*Effects*: The first form is equivalent to return emplace(std::forward<P>(x));[.](#5.sentence-1)
The second form is equivalent toreturn emplace_hint(position, std::forward<P>(x));[.](#5.sentence-2)
[🔗](#lib:insert,flat_map_)
`template<class InputIterator>
constexpr void insert(InputIterator first, InputIterator last);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17742)
*Effects*: Adds elements to *c* as if by:for (; first != last; ++first) { value_type value = *first; *c*.keys.insert(*c*.keys.end(), std::move(value.first)); *c*.values.insert(*c*.values.end(), std::move(value.second));}
Then, sorts the range of newly inserted elements
with respect to value_comp();
merges the resulting sorted range and
the sorted range of pre-existing elements into a single sorted range; and
finally erases the duplicate elements as if by:auto zv = views::zip(*c*.keys, *c*.values);auto it = ranges::unique(zv, *key-equiv*(*compare*)).begin();auto dist = distance(zv.begin(), it);*c*.keys.erase(*c*.keys.begin() + dist, *c*.keys.end());*c*.values.erase(*c*.values.begin() + dist, *c*.values.end());
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17765)
*Complexity*: N + MlogM,
where N is size() before the operation andM is distance(first, last)[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17771)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#8.sentence-1)
[🔗](#lib:insert,flat_map__)
`template<class InputIterator>
constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17783)
*Effects*: Adds elements to *c* as if by:for (; first != last; ++first) { value_type value = *first; *c*.keys.insert(*c*.keys.end(), std::move(value.first)); *c*.values.insert(*c*.values.end(), std::move(value.second));}
Then, merges the sorted range of newly added elements and
the sorted range of pre-existing elements into a single sorted range; and
finally erases the duplicate elements as if by:auto zv = views::zip(*c*.keys, *c*.values);auto it = ranges::unique(zv, *key-equiv*(*compare*)).begin();auto dist = distance(zv.begin(), it);*c*.keys.erase(*c*.keys.begin() + dist, *c*.keys.end());*c*.values.erase(*c*.values.begin() + dist, *c*.values.end());
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17804)
*Complexity*: Linear in N, where N is size() after the operation[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17808)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#11.sentence-1)
[🔗](#lib:insert_range,flat_map)
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>
constexpr void insert_range(R&& rg);
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17820)
*Effects*: Adds elements to *c* as if by:for (const auto& e : rg) {*c*.keys.insert(*c*.keys.end(), e.first); *c*.values.insert(*c*.values.end(), e.second);}
Then, sorts the range of newly inserted elements
with respect to value_comp();
merges the resulting sorted range and
the sorted range of pre-existing elements into a single sorted range; and
finally erases the duplicate elements as if by:auto zv = views::zip(*c*.keys, *c*.values);auto it = ranges::unique(zv, *key-equiv*(*compare*)).begin();auto dist = distance(zv.begin(), it);*c*.keys.erase(*c*.keys.begin() + dist, *c*.keys.end());*c*.values.erase(*c*.values.begin() + dist, *c*.values.end());
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17842)
*Complexity*: N + MlogM,
where N is size() before the operation andM is ranges::distance(rg)[.](#13.sentence-1)
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17848)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#14.sentence-1)
[🔗](#lib:try_emplace,flat_map)
`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... 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);
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17866)
*Constraints*: is_constructible_v<mapped_type, Args...> is true[.](#15.sentence-1)
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17870)
*Effects*: If the map already contains an element whose key is equivalent to k,*this and args... are unchanged[.](#16.sentence-1)
Otherwise equivalent to:auto key_it = ranges::upper_bound(*c*.keys, k, *compare*);auto value_it = *c*.values.begin() + distance(*c*.keys.begin(), key_it);*c*.keys.insert(key_it, std::forward<decltype(k)>(k));*c*.values.emplace(value_it, std::forward<Args>(args)...);
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17882)
*Returns*: In the first two overloads,
the bool component of the returned pair is true if and only if the insertion took place[.](#17.sentence-1)
The returned iterator points to the map element
whose key is equivalent to k[.](#17.sentence-2)
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17890)
*Complexity*: The same as emplace for the first two overloads, and
the same as emplace_hint for the last two overloads[.](#18.sentence-1)
[🔗](#lib:try_emplace,flat_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);
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17905)
*Constraints*:
- [(19.1)](#19.1)
The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#19.1.sentence-1)
- [(19.2)](#19.2)
is_constructible_v<key_type, K> is true[.](#19.2.sentence-1)
- [(19.3)](#19.3)
is_constructible_v<mapped_type, Args...> is true[.](#19.3.sentence-1)
- [(19.4)](#19.4)
For the first overload,is_convertible_v<K&&, const_iterator> andis_convertible_v<K&&, iterator> are both false[.](#19.4.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17921)
*Preconditions*: The conversion from k into key_type constructs
an object u,
for which find(k) == find(u) is true[.](#20.sentence-1)
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17927)
*Effects*: If the map already contains an element whose key is equivalent to k,*this and args... are unchanged[.](#21.sentence-1)
Otherwise equivalent to:auto key_it = upper_bound(*c*.keys.begin(), *c*.keys.end(), k, *compare*);auto value_it = *c*.values.begin() + distance(*c*.keys.begin(), key_it);*c*.keys.emplace(key_it, std::forward<K>(k));*c*.values.emplace(value_it, std::forward<Args>(args)...);
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17939)
*Returns*: In the first overload,
the bool component of the returned pair is true if and only if the insertion took place[.](#22.sentence-1)
The returned iterator points to the map element
whose key is equivalent to k[.](#22.sentence-2)
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17947)
*Complexity*: The same as emplace and emplace_hint, respectively[.](#23.sentence-1)
[🔗](#lib:insert_or_assign,flat_map)
`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 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);
`
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17965)
*Constraints*: is_assignable_v<mapped_type&, M> is true andis_constructible_v<mapped_type, M> is true[.](#24.sentence-1)
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17970)
*Effects*: If the map already contains an element e whose key is equivalent to k,
assigns std::forward<M>(obj) to e.second[.](#25.sentence-1)
Otherwise, equivalent totry_emplace(std::forward<decltype(k)>(k), std::forward<M>(obj)) for the first two overloads ortry_emplace(hint, std::forward<decltype(k)>(k), std::forward<M>(obj)) for the last two overloads[.](#25.sentence-2)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17985)
*Returns*: In the first two overloads, the bool component of the returned pair
is true if and only if the insertion took place[.](#26.sentence-1)
The returned
iterator points to the map element whose key is equivalent to k[.](#26.sentence-2)
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17991)
*Complexity*: The same as emplace for the first two overloads and
the same as emplace_hint for the last two overloads[.](#27.sentence-1)
[🔗](#lib:insert_or_assign,flat_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);
`
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18006)
*Constraints*:
- [(28.1)](#28.1)
The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#28.1.sentence-1)
- [(28.2)](#28.2)
is_constructible_v<key_type, K> is true[.](#28.2.sentence-1)
- [(28.3)](#28.3)
is_assignable_v<mapped_type&, M> is true[.](#28.3.sentence-1)
- [(28.4)](#28.4)
is_constructible_v<mapped_type, M> is true[.](#28.4.sentence-1)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18020)
*Preconditions*: The conversion from k into key_type constructs
an object u, for which find(k) == find(u) is true[.](#29.sentence-1)
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18025)
*Effects*: If the map already contains an element e whose key is equivalent to k,
assigns std::forward<M>(obj) to e.second[.](#30.sentence-1)
Otherwise, equivalent totry_emplace(std::forward<K>(k), std::forward<M>(obj)) for the first overload ortry_emplace(hint, std::forward<K>(k), std::forward<M>(obj)) for the second overload[.](#30.sentence-2)
[31](#31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18040)
*Returns*: In the first overload,
the bool component of the returned pair is true if and only if the insertion took place[.](#31.sentence-1)
The returned iterator points to the map element
whose key is equivalent to k[.](#31.sentence-2)
[32](#32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18048)
*Complexity*: The same as emplace and emplace_hint, respectively[.](#32.sentence-1)
[🔗](#lib:swap,flat_map)
`constexpr void swap(flat_map& y) noexcept;
`
[33](#33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18059)
*Effects*: Equivalent to:ranges::swap(*compare*, y.*compare*);
ranges::swap(*c*.keys, y.*c*.keys);
ranges::swap(*c*.values, y.*c*.values);
[🔗](#lib:extract,flat_map)
`constexpr containers extract() &&;
`
[34](#34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18075)
*Postconditions*: *this is emptied, even if the function exits via an exception[.](#34.sentence-1)
[35](#35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18079)
*Returns*: std::move(*c*)[.](#35.sentence-1)
[🔗](#lib:replace,flat_map)
`constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont);
`
[36](#36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18090)
*Preconditions*: key_cont.size() == mapped_cont.size() is true,
the elements of key_cont are sorted with respect to *compare*, andkey_cont contains no equal elements[.](#36.sentence-1)
[37](#37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18096)
*Effects*: Equivalent to:*c*.keys = std::move(key_cont);*c*.values = std::move(mapped_cont);

View File

@@ -0,0 +1,162 @@
[flat.map.overview]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.overview)
### 23.6.8 Class template flat_map [[flat.map]](flat.map#overview)
#### 23.6.8.1 Overview [flat.map.overview]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L16954)
A flat_map is a container adaptor
that provides an associative container interface
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[.](#1.sentence-1)
flat_map supports iterators
that meet the *Cpp17InputIterator* requirements and
model the[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L16967)
A flat_map meets all of the requirements
of a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) and
of a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4Optional container requirements"))[.](#2.sentence-1)
flat_map meets the requirements of
an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")),
except that:
- [(2.1)](#2.1)
it does not meet the requirements related to node handles ([[container.node]](container.node "23.2.5Node handles")),
- [(2.2)](#2.2)
it does not meet the requirements related to iterator invalidation, and
- [(2.3)](#2.3)
the time complexity of the operations that insert or erase a single
element from the map is linear, including the ones that take an insertion
position iterator[.](#2.sentence-2)
[*Note [1](#note-1)*:
A flat_map does not meet the additional requirements of
an allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers"))[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L16990)
A flat_map also provides most operations
described in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") for unique keys[.](#3.sentence-1)
This means that a flat_map supports
the a_uniq operations in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") but not the a_eq operations[.](#3.sentence-2)
For a flat_map<Key, T> the key_type is Key and
the value_type is pair<Key, T>[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17000)
Descriptions are provided here only for operations on flat_map that
are not described in one of those sets of requirements or for operations where
there is additional semantic information[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17005)
A flat_map maintains the following invariants:
- [(5.1)](#5.1)
it contains the same number of keys and values;
- [(5.2)](#5.2)
the keys are sorted with respect to the comparison object; and
- [(5.3)](#5.3)
the value at offset off within the value container is
the value associated with the key at offset off within the key container[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17018)
If any member function in [[flat.map.defn]](flat.map.defn "23.6.8.2Definition") exits via an exception
the invariants are restored[.](#6.sentence-1)
[*Note [2](#note-2)*:
This can result in the flat_map being emptied[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17025)
Any type C that meets the sequence container requirements ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers"))
can be used to instantiate flat_map,
as long asC::iterator meets the *Cpp17RandomAccessIterator* requirements and
invocations of
member functions C::size and C::max_size do not exit via an exception[.](#7.sentence-1)
In particular, vector ([[vector]](vector "23.3.13Class template vector")) and deque ([[deque]](deque "23.3.5Class template deque"))
can be used[.](#7.sentence-2)
[*Note [3](#note-3)*:
vector<bool> is not a sequence container[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17039)
The program is ill-formed ifKey is not the same type as KeyContainer::value_type orT is not the same type as MappedContainer::value_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17044)
The effect of calling a constructor
that takes
both key_container_type and mapped_container_type arguments with
containers of different sizes is undefined[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17050)
The effect of calling a constructor or member function
that takes a sorted_unique_t argument with
a container, containers, or range
that is not sorted with respect to key_comp(), or
that contains equal elements,
is undefined[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L17058)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#11.sentence-1)

15
cppdraft/flat/map/syn.md Normal file
View File

@@ -0,0 +1,15 @@
[flat.map.syn]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.map.syn)
### 23.6.7 Header <flat_map> synopsis [flat.map.syn]
[🔗](#header:%3cflat_map%3e)
#include <compare> // see [[compare.syn]](compare.syn "17.12.1Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2Header <initializer_­list> synopsis")namespace std {// [[flat.map]](flat.map "23.6.8Class template flat_­map"), class template flat_maptemplate<class Key, class T, class Compare = less<Key>, class KeyContainer = vector<Key>, class MappedContainer = vector<T>>class flat_map; struct sorted_unique_t { explicit sorted_unique_t() = default; }; inline constexpr sorted_unique_t sorted_unique{}; template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Allocator>struct uses_allocator<flat_map<Key, T, Compare, KeyContainer, MappedContainer>,
Allocator>; // [[flat.map.erasure]](flat.map.erasure "23.6.8.8Erasure"), erasure for flat_maptemplate<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate>constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type
erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred); // [[flat.multimap]](flat.multimap "23.6.9Class template flat_­multimap"), class template flat_multimaptemplate<class Key, class T, class Compare = less<Key>, class KeyContainer = vector<Key>, class MappedContainer = vector<T>>class flat_multimap; struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; inline constexpr sorted_equivalent_t sorted_equivalent{}; template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Allocator>struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
Allocator>; // [[flat.multimap.erasure]](flat.multimap.erasure "23.6.9.5Erasure"), erasure for flat_multimaptemplate<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate>constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);}

391
cppdraft/flat/multimap.md Normal file
View File

@@ -0,0 +1,391 @@
[flat.multimap]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap)
### 23.6.9 Class template flat_multimap [flat.multimap]
#### [23.6.9.1](#overview) Overview [[flat.multimap.overview]](flat.multimap.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18148)
A flat_multimap is a container adaptor
that provides an associative container interface
that supports equivalent keys
(i.e., possibly containing multiple copies of the same key value) and
provides for fast retrieval of values of another type T based on the keys[.](#overview-1.sentence-1)
flat_multimap supports iterators that meet
the *Cpp17InputIterator* requirements and
model the[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#overview-1.sentence-2)
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18161)
A flat_multimap meets all of the requirements
for a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) and
for a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4Optional container requirements"))[.](#overview-2.sentence-1)
flat_multimap meets the requirements of
an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")), except that:
- [(2.1)](#overview-2.1)
it does not meet the requirements related to node handles ([[container.node]](container.node "23.2.5Node handles")),
- [(2.2)](#overview-2.2)
it does not meet the requirements related to iterator invalidation, and
- [(2.3)](#overview-2.3)
the time complexity of the operations
that insert or erase a single element from the map is linear,
including the ones that take an insertion position iterator[.](#overview-2.sentence-2)
[*Note [1](#overview-note-1)*:
A flat_multimap does not meet the additional requirements of an
allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers"))[.](#overview-2.sentence-3)
— *end note*]
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18183)
A flat_multimap also provides most operations described
in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") for equal keys[.](#overview-3.sentence-1)
This means that a flat_multimap supports
the a_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") but not the a_uniq operations[.](#overview-3.sentence-2)
For a flat_multimap<Key, T> the key_type is Key and
the value_type is pair<Key, T>[.](#overview-3.sentence-3)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18193)
Except as otherwise noted,
operations on flat_multimap are equivalent to those of flat_map,
except that flat_multimap operations
do not remove or replace elements with equal keys[.](#overview-4.sentence-1)
[*Example [1](#overview-example-1)*:
flat_multimap constructors and emplace do not erase
non-unique elements after sorting them[.](#overview-4.sentence-2)
— *end example*]
[5](#overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18203)
A flat_multimap maintains the following invariants:
- [(5.1)](#overview-5.1)
it contains the same number of keys and values;
- [(5.2)](#overview-5.2)
the keys are sorted with respect to the comparison object; and
- [(5.3)](#overview-5.3)
the value at offset off within the value container is the value
associated with the key at offset off within the key container[.](#overview-5.sentence-1)
[6](#overview-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18215)
If any member function in [[flat.multimap.defn]](#defn "23.6.9.2Definition") exits via an exception,
the invariants are restored[.](#overview-6.sentence-1)
[*Note [2](#overview-note-2)*:
This can result in the flat_multimap being emptied[.](#overview-6.sentence-2)
— *end note*]
[7](#overview-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18222)
Any type C that meets the sequence container requirements ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers"))
can be used to instantiate flat_multimap,
as long asC::iterator meets the *Cpp17RandomAccessIterator* requirements and
invocations of
member functions C::size and C::max_size do not exit via an exception[.](#overview-7.sentence-1)
In particular,vector ([[vector]](vector "23.3.13Class template vector")) and deque ([[deque]](deque "23.3.5Class template deque")) can be used[.](#overview-7.sentence-2)
[*Note [3](#overview-note-3)*:
vector<bool> is not a sequence container[.](#overview-7.sentence-3)
— *end note*]
[8](#overview-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18236)
The program is ill-formed ifKey is not the same type as KeyContainer::value_type orT is not the same type as MappedContainer::value_type[.](#overview-8.sentence-1)
[9](#overview-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18241)
The effect of calling a constructor
that takes both key_container_type andmapped_container_type arguments
with containers of different sizes is undefined[.](#overview-9.sentence-1)
[10](#overview-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18247)
The effect of calling a constructor or member function
that takes a sorted_equivalent_t argument
with a container, containers, or range
that are not sorted with respect to key_comp() is undefined[.](#overview-10.sentence-1)
[11](#overview-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18253)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#overview-11.sentence-1)
#### [23.6.9.2](#defn) Definition [[flat.multimap.defn]](flat.multimap.defn)
namespace std {template<class Key, class T, class Compare = less<Key>, class KeyContainer = vector<Key>, class MappedContainer = vector<T>>class flat_multimap {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair<key_type, mapped_type>; using key_compare = Compare; using reference = pair<const key_type&, mapped_type&>; using const_reference = pair<const key_type&, const mapped_type&>; using size_type = size_t; using difference_type = ptrdiff_t; using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using key_container_type = KeyContainer; using mapped_container_type = MappedContainer; class value_compare {private: key_compare *comp*; // *exposition only*constexpr value_compare(key_compare c) : *comp*(c) { } // *exposition only*public:constexpr bool operator()(const_reference x, const_reference y) const {return *comp*(x.first, y.first); }}; struct containers { key_container_type keys;
mapped_container_type values; }; // [[flat.multimap.cons]](#cons "23.6.9.3Constructors"), constructorsconstexpr flat_multimap() : flat_multimap(key_compare()) { }constexpr explicit flat_multimap(const key_compare& comp): *c*(), *compare*(comp) { }constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); constexpr flat_multimap(sorted_equivalent_t,
key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); template<class InputIterator>constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp){ insert(first, last); }template<class InputIterator>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp) { insert(sorted_equivalent, first, last); }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr flat_multimap(from_range_t, R&& rg): flat_multimap(from_range, std::forward<R>(rg), key_compare()) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp): flat_multimap(comp) { insert_range(std::forward<R>(rg)); }constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare()): flat_multimap(il.begin(), il.end(), comp) { }constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const key_compare& comp = key_compare()): flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { }// [[flat.multimap.cons.alloc]](#cons.alloc "23.6.9.4Constructors with allocators"), constructors with allocatorstemplate<class Alloc>constexpr explicit flat_multimap(const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(const flat_multimap&, const Alloc& a); template<class Alloc>constexpr flat_multimap(flat_multimap&&, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a); template<class Alloc>constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
flat_multimap& operator=(initializer_list<value_type>); // 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){ return emplace(x); }constexpr iterator insert(value_type&& x){ return emplace(std::move(x)); }constexpr iterator insert(const_iterator position, const value_type& x){ return emplace_hint(position, x); }constexpr iterator insert(const_iterator position, value_type&& x){ return emplace_hint(position, std::move(x)); }template<class P> constexpr iterator insert(P&& x); template<class P>constexpr iterator insert(const_iterator position, P&&); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator>constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type> il){ insert(il.begin(), il.end()); }constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il){ insert(sorted_equivalent, il.begin(), il.end()); }constexpr containers extract() &&; constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); 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(flat_multimap&) noexcept; constexpr void clear() noexcept; // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; constexpr const key_container_type& keys() const noexcept { return *c*.keys; }constexpr const mapped_container_type& values() const noexcept { return *c*.values; }// 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; friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y); friend constexpr *synth-three-way-result*<value_type>operator<=>(const flat_multimap& x, const flat_multimap& y); friend constexpr void swap(flat_multimap& x, flat_multimap& y) noexcept{ x.swap(y); }private: containers *c*; // *exposition only* key_compare *compare*; // *exposition only*}; template<class KeyContainer, class MappedContainer, class Compare = less<typename KeyContainer::value_type>> flat_multimap(KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Allocator> flat_multimap(KeyContainer, MappedContainer, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare, class Allocator> flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare = less<typename KeyContainer::value_type>> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Allocator> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare, class Allocator> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>> flat_multimap(InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>, Compare>; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>> flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>, Compare>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Compare = less<*range-key-type*<R>>, class Allocator = allocator<byte>> flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> flat_multimap<*range-key-type*<R>, *range-mapped-type*<R>, Compare,
vector<*range-key-type*<R>, *alloc-rebind*<Allocator, *range-key-type*<R>>>,
vector<*range-mapped-type*<R>, *alloc-rebind*<Allocator, *range-mapped-type*<R>>>>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Allocator> flat_multimap(from_range_t, R&&, Allocator)-> flat_multimap<*range-key-type*<R>, *range-mapped-type*<R>, less<*range-key-type*<R>>,
vector<*range-key-type*<R>, *alloc-rebind*<Allocator, *range-key-type*<R>>>,
vector<*range-mapped-type*<R>, *alloc-rebind*<Allocator, *range-mapped-type*<R>>>>; template<class Key, class T, class Compare = less<Key>> flat_multimap(initializer_list<pair<Key, T>>, Compare = Compare())-> flat_multimap<Key, T, Compare>; template<class Key, class T, class Compare = less<Key>> flat_multimap(sorted_equivalent_t, initializer_list<pair<Key, T>>, Compare = Compare())-> flat_multimap<Key, T, Compare>; template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Allocator>struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
Allocator>: bool_constant<uses_allocator_v<KeyContainer, Allocator> && uses_allocator_v<MappedContainer, Allocator>> { };}
[1](#defn-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18572)
The member type containers has the data members and special members
specified above[.](#defn-1.sentence-1)
It has no base classes or members other than those
specified[.](#defn-1.sentence-2)
#### [23.6.9.3](#cons) Constructors [[flat.multimap.cons]](flat.multimap.cons)
[🔗](#lib:flat_multimap,constructor)
`constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18586)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp;
sorts the range [begin(), end()) with respect to value_comp()[.](#cons-1.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18594)
*Complexity*: Linear in N if the container arguments are already sorted
with respect to value_comp() and otherwise NlogN,
where N is the value of key_cont.size() before this call[.](#cons-2.sentence-1)
[🔗](#lib:flat_multimap,constructor_)
`constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont,
mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18609)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp[.](#cons-3.sentence-1)
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18616)
*Complexity*: Constant[.](#cons-4.sentence-1)
#### [23.6.9.4](#cons.alloc) Constructors with allocators [[flat.multimap.cons.alloc]](flat.multimap.cons.alloc)
[1](#cons.alloc-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18623)
The constructors in this subclause shall not participate in overload resolution
unless uses_allocator_v<key_container_type, Alloc> is true and uses_allocator_v<mapped_container_type, Alloc> is true[.](#cons.alloc-1.sentence-1)
[🔗](#lib:flat_multimap,constructor__)
`template<class Alloc>
constexpr flat_multimap(const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const key_container_type& key_cont,
const mapped_container_type& mapped_cont,
const key_compare& comp, const Alloc& a);
`
[2](#cons.alloc-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18640)
*Effects*: Equivalent to flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#cons.alloc-2.sentence-1)
[3](#cons.alloc-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18647)
*Complexity*: Same as flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively[.](#cons.alloc-3.sentence-1)
[🔗](#lib:flat_multimap,constructor___)
`template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const key_compare& comp,
const Alloc& a);
`
[4](#cons.alloc-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18665)
*Effects*: Equivalent to flat_multimap(sorted_equivalent, key_cont, mapped_cont) andflat_multimap(sorted_equivalent, key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#cons.alloc-4.sentence-1)
[5](#cons.alloc-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18672)
*Complexity*: Linear[.](#cons.alloc-5.sentence-1)
[🔗](#lib:flat_multimap,constructor____)
`template<class Alloc>
constexpr explicit flat_multimap(const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const flat_multimap&, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(flat_multimap&&, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp,
const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
const key_compare& comp, const Alloc& a);
`
[6](#cons.alloc-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18715)
*Effects*: Equivalent to the corresponding non-allocator constructors
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#cons.alloc-6.sentence-1)
#### [23.6.9.5](#erasure) Erasure [[flat.multimap.erasure]](flat.multimap.erasure)
[🔗](#lib:erase_if,flat_multimap)
`template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
class Predicate>
constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
`
[1](#erasure-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18733)
*Preconditions*: Key and T meet the *Cpp17MoveAssignable* requirements[.](#erasure-1.sentence-1)
[2](#erasure-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18737)
*Effects*: Let E be bool(pred(pair<const Key&, const T&>(e)))[.](#erasure-2.sentence-1)
Erases all elements e in c for which E holds[.](#erasure-2.sentence-2)
[3](#erasure-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18742)
*Returns*: The number of elements erased[.](#erasure-3.sentence-1)
[4](#erasure-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18746)
*Complexity*: Exactly c.size() applications of the predicate[.](#erasure-4.sentence-1)
[5](#erasure-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18750)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#erasure-5.sentence-1)
If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67valid but unspecified state"))[.](#erasure-5.sentence-2)
[*Note [1](#erasure-note-1)*:
c still meets its invariants,
but can be empty[.](#erasure-5.sentence-3)
— *end note*]

View File

@@ -0,0 +1,49 @@
[flat.multimap.cons]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap.cons)
### 23.6.9 Class template flat_multimap [[flat.multimap]](flat.multimap#cons)
#### 23.6.9.3 Constructors [flat.multimap.cons]
[🔗](#lib:flat_multimap,constructor)
`constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18586)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp;
sorts the range [begin(), end()) with respect to value_comp()[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18594)
*Complexity*: Linear in N if the container arguments are already sorted
with respect to value_comp() and otherwise NlogN,
where N is the value of key_cont.size() before this call[.](#2.sentence-1)
[🔗](#lib:flat_multimap,constructor_)
`constexpr flat_multimap(sorted_equivalent_t, key_container_type key_cont,
mapped_container_type mapped_cont,
const key_compare& comp = key_compare());
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18609)
*Effects*: Initializes*c*.keys with std::move(key_cont),*c*.values with std::move(mapped_cont), and*compare* with comp[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18616)
*Complexity*: Constant[.](#4.sentence-1)

View File

@@ -0,0 +1,111 @@
[flat.multimap.cons.alloc]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap.cons.alloc)
### 23.6.9 Class template flat_multimap [[flat.multimap]](flat.multimap#cons.alloc)
#### 23.6.9.4 Constructors with allocators [flat.multimap.cons.alloc]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18623)
The constructors in this subclause shall not participate in overload resolution
unless uses_allocator_v<key_container_type, Alloc> is true and uses_allocator_v<mapped_container_type, Alloc> is true[.](#1.sentence-1)
[🔗](#lib:flat_multimap,constructor)
`template<class Alloc>
constexpr flat_multimap(const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const key_container_type& key_cont,
const mapped_container_type& mapped_cont,
const key_compare& comp, const Alloc& a);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18640)
*Effects*: Equivalent to flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18647)
*Complexity*: Same as flat_multimap(key_cont, mapped_cont) andflat_multimap(key_cont, mapped_cont, comp), respectively[.](#3.sentence-1)
[🔗](#lib:flat_multimap,constructor_)
`template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont,
const mapped_container_type& mapped_cont, const key_compare& comp,
const Alloc& a);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18665)
*Effects*: Equivalent to flat_multimap(sorted_equivalent, key_cont, mapped_cont) andflat_multimap(sorted_equivalent, key_cont, mapped_cont, comp), respectively,
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18672)
*Complexity*: Linear[.](#5.sentence-1)
[🔗](#lib:flat_multimap,constructor__)
`template<class Alloc>
constexpr explicit flat_multimap(const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(const flat_multimap&, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(flat_multimap&&, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp,
const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il,
const key_compare& comp, const Alloc& a);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18715)
*Effects*: Equivalent to the corresponding non-allocator constructors
except that *c*.keys and *c*.values are constructed
with uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#6.sentence-1)

View File

@@ -0,0 +1,36 @@
[flat.multimap.defn]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap.defn)
### 23.6.9 Class template flat_multimap [[flat.multimap]](flat.multimap#defn)
#### 23.6.9.2 Definition [flat.multimap.defn]
namespace std {template<class Key, class T, class Compare = less<Key>, class KeyContainer = vector<Key>, class MappedContainer = vector<T>>class flat_multimap {public:// typesusing key_type = Key; using mapped_type = T; using value_type = pair<key_type, mapped_type>; using key_compare = Compare; using reference = pair<const key_type&, mapped_type&>; using const_reference = pair<const key_type&, const mapped_type&>; using size_type = size_t; using difference_type = ptrdiff_t; using iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using const_iterator = *implementation-defined*; // see [[container.requirements]](container.requirements "23.2Requirements")using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; using key_container_type = KeyContainer; using mapped_container_type = MappedContainer; class value_compare {private: key_compare *comp*; // *exposition only*constexpr value_compare(key_compare c) : *comp*(c) { } // *exposition only*public:constexpr bool operator()(const_reference x, const_reference y) const {return *comp*(x.first, y.first); }}; struct containers { key_container_type keys;
mapped_container_type values; }; // [[flat.multimap.cons]](flat.multimap.cons "23.6.9.3Constructors"), constructorsconstexpr flat_multimap() : flat_multimap(key_compare()) { }constexpr explicit flat_multimap(const key_compare& comp): *c*(), *compare*(comp) { }constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); constexpr flat_multimap(sorted_equivalent_t,
key_container_type key_cont, mapped_container_type mapped_cont, const key_compare& comp = key_compare()); template<class InputIterator>constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp){ insert(first, last); }template<class InputIterator>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()): *c*(), *compare*(comp) { insert(sorted_equivalent, first, last); }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr flat_multimap(from_range_t, R&& rg): flat_multimap(from_range, std::forward<R>(rg), key_compare()) { }template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp): flat_multimap(comp) { insert_range(std::forward<R>(rg)); }constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare()): flat_multimap(il.begin(), il.end(), comp) { }constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const key_compare& comp = key_compare()): flat_multimap(sorted_equivalent, il.begin(), il.end(), comp) { }// [[flat.multimap.cons.alloc]](flat.multimap.cons.alloc "23.6.9.4Constructors with allocators"), constructors with allocatorstemplate<class Alloc>constexpr explicit flat_multimap(const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc>constexpr flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(const flat_multimap&, const Alloc& a); template<class Alloc>constexpr flat_multimap(flat_multimap&&, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc>constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a); template<class Alloc>constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc>constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
flat_multimap& operator=(initializer_list<value_type>); // 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){ return emplace(x); }constexpr iterator insert(value_type&& x){ return emplace(std::move(x)); }constexpr iterator insert(const_iterator position, const value_type& x){ return emplace_hint(position, x); }constexpr iterator insert(const_iterator position, value_type&& x){ return emplace_hint(position, std::move(x)); }template<class P> constexpr iterator insert(P&& x); template<class P>constexpr iterator insert(const_iterator position, P&&); template<class InputIterator>constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator>constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<[*container-compatible-range*](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>constexpr void insert_range(R&& rg); constexpr void insert(initializer_list<value_type> il){ insert(il.begin(), il.end()); }constexpr void insert(sorted_equivalent_t, initializer_list<value_type> il){ insert(sorted_equivalent, il.begin(), il.end()); }constexpr containers extract() &&; constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); 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(flat_multimap&) noexcept; constexpr void clear() noexcept; // observersconstexpr key_compare key_comp() const; constexpr value_compare value_comp() const; constexpr const key_container_type& keys() const noexcept { return *c*.keys; }constexpr const mapped_container_type& values() const noexcept { return *c*.values; }// 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; friend constexpr bool operator==(const flat_multimap& x, const flat_multimap& y); friend constexpr *synth-three-way-result*<value_type>operator<=>(const flat_multimap& x, const flat_multimap& y); friend constexpr void swap(flat_multimap& x, flat_multimap& y) noexcept{ x.swap(y); }private: containers *c*; // *exposition only* key_compare *compare*; // *exposition only*}; template<class KeyContainer, class MappedContainer, class Compare = less<typename KeyContainer::value_type>> flat_multimap(KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Allocator> flat_multimap(KeyContainer, MappedContainer, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare, class Allocator> flat_multimap(KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare = less<typename KeyContainer::value_type>> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare = Compare())-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Allocator> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
less<typename KeyContainer::value_type>, KeyContainer, MappedContainer>; template<class KeyContainer, class MappedContainer, class Compare, class Allocator> flat_multimap(sorted_equivalent_t, KeyContainer, MappedContainer, Compare, Allocator)-> flat_multimap<typename KeyContainer::value_type, typename MappedContainer::value_type,
Compare, KeyContainer, MappedContainer>; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>> flat_multimap(InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>, Compare>; template<class InputIterator, class Compare = less<*iter-key-type*<InputIterator>>> flat_multimap(sorted_equivalent_t, InputIterator, InputIterator, Compare = Compare())-> flat_multimap<*iter-key-type*<InputIterator>, *iter-mapped-type*<InputIterator>, Compare>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Compare = less<*range-key-type*<R>>, class Allocator = allocator<byte>> flat_multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())-> flat_multimap<*range-key-type*<R>, *range-mapped-type*<R>, Compare,
vector<*range-key-type*<R>, *alloc-rebind*<Allocator, *range-key-type*<R>>>,
vector<*range-mapped-type*<R>, *alloc-rebind*<Allocator, *range-mapped-type*<R>>>>; template<ranges::[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") R, class Allocator> flat_multimap(from_range_t, R&&, Allocator)-> flat_multimap<*range-key-type*<R>, *range-mapped-type*<R>, less<*range-key-type*<R>>,
vector<*range-key-type*<R>, *alloc-rebind*<Allocator, *range-key-type*<R>>>,
vector<*range-mapped-type*<R>, *alloc-rebind*<Allocator, *range-mapped-type*<R>>>>; template<class Key, class T, class Compare = less<Key>> flat_multimap(initializer_list<pair<Key, T>>, Compare = Compare())-> flat_multimap<Key, T, Compare>; template<class Key, class T, class Compare = less<Key>> flat_multimap(sorted_equivalent_t, initializer_list<pair<Key, T>>, Compare = Compare())-> flat_multimap<Key, T, Compare>; template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Allocator>struct uses_allocator<flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>,
Allocator>: bool_constant<uses_allocator_v<KeyContainer, Allocator> && uses_allocator_v<MappedContainer, Allocator>> { };}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18572)
The member type containers has the data members and special members
specified above[.](#1.sentence-1)
It has no base classes or members other than those
specified[.](#1.sentence-2)

View File

@@ -0,0 +1,58 @@
[flat.multimap.erasure]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap.erasure)
### 23.6.9 Class template flat_multimap [[flat.multimap]](flat.multimap#erasure)
#### 23.6.9.5 Erasure [flat.multimap.erasure]
[🔗](#lib:erase_if,flat_multimap)
`template<class Key, class T, class Compare, class KeyContainer, class MappedContainer,
class Predicate>
constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type
erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18733)
*Preconditions*: Key and T meet the *Cpp17MoveAssignable* requirements[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18737)
*Effects*: Let E be bool(pred(pair<const Key&, const T&>(e)))[.](#2.sentence-1)
Erases all elements e in c for which E holds[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18742)
*Returns*: The number of elements erased[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18746)
*Complexity*: Exactly c.size() applications of the predicate[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18750)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#5.sentence-1)
If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67valid but unspecified state"))[.](#5.sentence-2)
[*Note [1](#note-1)*:
c still meets its invariants,
but can be empty[.](#5.sentence-3)
— *end note*]

View File

@@ -0,0 +1,165 @@
[flat.multimap.overview]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multimap.overview)
### 23.6.9 Class template flat_multimap [[flat.multimap]](flat.multimap#overview)
#### 23.6.9.1 Overview [flat.multimap.overview]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18148)
A flat_multimap is a container adaptor
that provides an associative container interface
that supports equivalent keys
(i.e., possibly containing multiple copies of the same key value) and
provides for fast retrieval of values of another type T based on the keys[.](#1.sentence-1)
flat_multimap supports iterators that meet
the *Cpp17InputIterator* requirements and
model the[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18161)
A flat_multimap meets all of the requirements
for a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) and
for a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4Optional container requirements"))[.](#2.sentence-1)
flat_multimap meets the requirements of
an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")), except that:
- [(2.1)](#2.1)
it does not meet the requirements related to node handles ([[container.node]](container.node "23.2.5Node handles")),
- [(2.2)](#2.2)
it does not meet the requirements related to iterator invalidation, and
- [(2.3)](#2.3)
the time complexity of the operations
that insert or erase a single element from the map is linear,
including the ones that take an insertion position iterator[.](#2.sentence-2)
[*Note [1](#note-1)*:
A flat_multimap does not meet the additional requirements of an
allocator-aware container ([[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers"))[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18183)
A flat_multimap also provides most operations described
in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") for equal keys[.](#3.sentence-1)
This means that a flat_multimap supports
the a_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") but not the a_uniq operations[.](#3.sentence-2)
For a flat_multimap<Key, T> the key_type is Key and
the value_type is pair<Key, T>[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18193)
Except as otherwise noted,
operations on flat_multimap are equivalent to those of flat_map,
except that flat_multimap operations
do not remove or replace elements with equal keys[.](#4.sentence-1)
[*Example [1](#example-1)*:
flat_multimap constructors and emplace do not erase
non-unique elements after sorting them[.](#4.sentence-2)
— *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18203)
A flat_multimap maintains the following invariants:
- [(5.1)](#5.1)
it contains the same number of keys and values;
- [(5.2)](#5.2)
the keys are sorted with respect to the comparison object; and
- [(5.3)](#5.3)
the value at offset off within the value container is the value
associated with the key at offset off within the key container[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18215)
If any member function in [[flat.multimap.defn]](flat.multimap.defn "23.6.9.2Definition") exits via an exception,
the invariants are restored[.](#6.sentence-1)
[*Note [2](#note-2)*:
This can result in the flat_multimap being emptied[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18222)
Any type C that meets the sequence container requirements ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers"))
can be used to instantiate flat_multimap,
as long asC::iterator meets the *Cpp17RandomAccessIterator* requirements and
invocations of
member functions C::size and C::max_size do not exit via an exception[.](#7.sentence-1)
In particular,vector ([[vector]](vector "23.3.13Class template vector")) and deque ([[deque]](deque "23.3.5Class template deque")) can be used[.](#7.sentence-2)
[*Note [3](#note-3)*:
vector<bool> is not a sequence container[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18236)
The program is ill-formed ifKey is not the same type as KeyContainer::value_type orT is not the same type as MappedContainer::value_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18241)
The effect of calling a constructor
that takes both key_container_type andmapped_container_type arguments
with containers of different sizes is undefined[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18247)
The effect of calling a constructor or member function
that takes a sorted_equivalent_t argument
with a container, containers, or range
that are not sorted with respect to key_comp() is undefined[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18253)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#11.sentence-1)

429
cppdraft/flat/multiset.md Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
[flat.multiset.cons]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset.cons)
### 23.6.12 Class template flat_multiset [[flat.multiset]](flat.multiset#cons)
#### 23.6.12.3 Constructors [flat.multiset.cons]
[🔗](#lib:flat_multiset,constructor)
`constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare());
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19839)
*Effects*: Initializes *c* with std::move(cont) and*compare* with comp, and
sorts the range [begin(), end()) with respect to *compare*[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19845)
*Complexity*: Linear in N if cont is already sorted with respect to *compare* and
otherwise NlogN, where N is the value of cont.size() before this call[.](#2.sentence-1)

View File

@@ -0,0 +1,106 @@
[flat.multiset.cons.alloc]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset.cons.alloc)
### 23.6.12 Class template flat_multiset [[flat.multiset]](flat.multiset#cons.alloc)
#### 23.6.12.4 Constructors with allocators [flat.multiset.cons.alloc]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19853)
The constructors in this subclause shall not participate in overload resolution
unless uses_allocator_v<container_type, Alloc> is true[.](#1.sentence-1)
[🔗](#lib:flat_multiset,constructor)
`template<class Alloc>
constexpr flat_multiset(const container_type& cont, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19866)
*Effects*: Equivalent to flat_multiset(cont) andflat_multiset(cont, comp), respectively,
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19873)
*Complexity*: Same as flat_multiset(cont) andflat_multiset(cont, comp), respectively[.](#3.sentence-1)
[🔗](#lib:flat_multiset,constructor_)
`template<class Alloc>
constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(sorted_equivalent_t, const container_type& cont,
const key_compare& comp, const Alloc& a);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19889)
*Effects*: Equivalent to flat_multiset(sorted_equivalent, cont) andflat_multiset(sorted_equivalent, cont, comp), respectively,
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19896)
*Complexity*: Linear[.](#5.sentence-1)
[🔗](#lib:flat_multiset,constructor__)
`template<class Alloc>
constexpr explicit flat_multiset(const Alloc& a);
template<class Alloc>
constexpr flat_multiset(const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(const flat_multiset&, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(flat_multiset&&, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multiset(InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp,
const Alloc& a);
template<class Alloc>
constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il,
const key_compare& comp, const Alloc& a);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19939)
*Effects*: Equivalent to the corresponding non-allocator constructors
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#6.sentence-1)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,56 @@
[flat.multiset.erasure]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset.erasure)
### 23.6.12 Class template flat_multiset [[flat.multiset]](flat.multiset#erasure)
#### 23.6.12.6 Erasure [flat.multiset.erasure]
[🔗](#lib:erase_if,flat_multiset)
`template<class Key, class Compare, class KeyContainer, class Predicate>
constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type
erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20071)
*Preconditions*: Key meets the *Cpp17MoveAssignable* requirements[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20075)
*Effects*: Let E be bool(pred(as_const(e)))[.](#2.sentence-1)
Erases all elements e in c for which E holds[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20080)
*Returns*: The number of elements erased[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20084)
*Complexity*: Exactly c.size() applications of the predicate[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20088)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#5.sentence-1)
If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67valid but unspecified state"))[.](#5.sentence-2)
[*Note [1](#note-1)*:
c still meets its invariants, but can be empty[.](#5.sentence-3)
— *end note*]

View File

@@ -0,0 +1,125 @@
[flat.multiset.modifiers]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset.modifiers)
### 23.6.12 Class template flat_multiset [[flat.multiset]](flat.multiset#modifiers)
#### 23.6.12.5 Modifiers [flat.multiset.modifiers]
[🔗](#lib:emplace,flat_multiset)
`template<class... Args> constexpr iterator emplace(Args&&... args);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19954)
*Constraints*: is_constructible_v<value_type, Args...> is true[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19958)
*Effects*: First, initializes an object t of type value_type with std::forward<Args>(args)...,
then inserts t as if by:auto it = ranges::upper_bound(*c*, t, *compare*);*c*.insert(it, std::move(t));
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19968)
*Returns*: An iterator that points to the inserted element[.](#3.sentence-1)
[🔗](#lib:insert,flat_multiset)
`template<class InputIterator>
constexpr void insert(InputIterator first, InputIterator last);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19980)
*Effects*: Adds elements to *c* as if by:*c*.insert(*c*.end(), first, last);
Then, sorts the range of newly inserted elements with respect to *compare*,
and merges the resulting sorted range and
the sorted range of pre-existing elements into a single sorted range[.](#4.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19990)
*Complexity*: N + MlogM, where N is size() before the operation and M is distance(first, last)[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19995)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#6.sentence-1)
[🔗](#lib:insert,flat_multiset_)
`template<class InputIterator>
constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last);
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20007)
*Effects*: Equivalent to insert(first, last)[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20011)
*Complexity*: Linear[.](#8.sentence-1)
[🔗](#lib:swap,flat_multiset)
`constexpr void swap(flat_multiset& y) noexcept;
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20022)
*Effects*: Equivalent to:ranges::swap(*compare*, y.*compare*);
ranges::swap(*c*, y.*c*);
[🔗](#lib:extract,flat_multiset)
`constexpr container_type extract() &&;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20037)
*Postconditions*: *this is emptied, even if the function exits via an exception[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20041)
*Returns*: std::move(*c*)[.](#11.sentence-1)
[🔗](#lib:replace,flat_multiset)
`constexpr void replace(container_type&& cont);
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20052)
*Preconditions*: The elements of cont are sorted with respect to *compare*[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20056)
*Effects*: Equivalent to: *c* = std::move(cont);

View File

@@ -0,0 +1,134 @@
[flat.multiset.overview]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.multiset.overview)
### 23.6.12 Class template flat_multiset [[flat.multiset]](flat.multiset#overview)
#### 23.6.12.1 Overview [flat.multiset.overview]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19475)
A flat_multiset is a container adaptor
that provides an associative container interface
that supports equivalent keys
(i.e., possibly containing multiple copies of the same key value) and
provides for fast retrieval of the keys themselves[.](#1.sentence-1)
flat_multiset supports iterators that model the[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19485)
A flat_multiset meets all of the requirements
for a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) and
for a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4Optional container requirements"))[.](#2.sentence-1)
flat_multiset meets the requirements of
an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")), except that:
- [(2.1)](#2.1)
it does not meet the requirements
related to node handles ([[container.node.overview]](container.node.overview "23.2.5.1Overview")),
- [(2.2)](#2.2)
it does not meet the requirements related to iterator invalidation, and
- [(2.3)](#2.3)
the time complexity of the operations
that insert or erase a single element from the
set is linear,
including the ones that take an insertion position iterator[.](#2.sentence-2)
[*Note [1](#note-1)*:
A flat_multiset does not meet
the additional requirements of an allocator-aware container,
as described in [[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers")[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19510)
A flat_multiset also provides most operations
described in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") for equal keys[.](#3.sentence-1)
This means that a flat_multiset supports
the a_eq operations in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") but not the a_uniq operations[.](#3.sentence-2)
For a flat_multiset<Key>,
both the key_type and value_type are Key[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19519)
Descriptions are provided here only for operations on flat_multiset that are not described in one of the general sections or
for operations where there is additional semantic information[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19524)
A flat_multiset maintains the invariant
that the keys are sorted with respect to the comparison object[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19528)
If any member function in [[flat.multiset.defn]](flat.multiset.defn "23.6.12.2Definition") exits via an exception,
the invariant is restored[.](#6.sentence-1)
[*Note [2](#note-2)*:
This can result in the flat_multiset's being emptied[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19535)
Any sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers"))
supporting *Cpp17RandomAccessIterator* can be used to instantiate flat_multiset[.](#7.sentence-1)
In particular,vector ([[vector]](vector "23.3.13Class template vector")) and deque ([[deque]](deque "23.3.5Class template deque")) can be used[.](#7.sentence-2)
[*Note [3](#note-3)*:
vector<bool> is not a sequence container[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19545)
The program is ill-formed if Key is not the same type
as KeyContainer::value_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19549)
The effect of calling a constructor or member function
that takes a sorted_equivalent_t argument with a range
that is not sorted with respect to key_comp() is undefined[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19554)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#10.sentence-1)

483
cppdraft/flat/set.md Normal file

File diff suppressed because one or more lines are too long

30
cppdraft/flat/set/cons.md Normal file
View File

@@ -0,0 +1,30 @@
[flat.set.cons]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.cons)
### 23.6.11 Class template flat_set [[flat.set]](flat.set#cons)
#### 23.6.11.3 Constructors [flat.set.cons]
[🔗](#lib:flat_set,constructor)
`constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare());
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19167)
*Effects*: Initializes *c* with std::move(cont) and*compare* with comp,
sorts the range [begin(), end()) with respect to *compare*, and
finally erases all but the first element
from each group of consecutive equivalent elements[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19175)
*Complexity*: Linear in N if cont is already sorted with respect to *compare* and
otherwise NlogN, where N is the value of cont.size() before this call[.](#2.sentence-1)

View File

@@ -0,0 +1,105 @@
[flat.set.cons.alloc]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.cons.alloc)
### 23.6.11 Class template flat_set [[flat.set]](flat.set#cons.alloc)
#### 23.6.11.4 Constructors with allocators [flat.set.cons.alloc]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19183)
The constructors in this subclause shall not participate in overload resolution
unless uses_allocator_v<container_type, Alloc> is true[.](#1.sentence-1)
[🔗](#lib:flat_set,constructor)
`template<class Alloc>
constexpr flat_set(const container_type& cont, const Alloc& a);
template<class Alloc>
constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a);
`
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19196)
*Effects*: Equivalent toflat_set(cont) and flat_set(cont, comp), respectively,
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19203)
*Complexity*: Same as flat_set(cont) and flat_set(cont, comp), respectively[.](#3.sentence-1)
[🔗](#lib:flat_set,constructor_)
`template<class Alloc>
constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a);
template<class Alloc>
constexpr flat_set(sorted_unique_t, const container_type& cont,
const key_compare& comp, const Alloc& a);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19218)
*Effects*: Equivalent toflat_set(sorted_unique, cont) andflat_set(sorted_unique, cont,
comp), respectively,
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19226)
*Complexity*: Linear[.](#5.sentence-1)
[🔗](#lib:flat_set,constructor__)
`template<class Alloc>
constexpr explicit flat_set(const Alloc& a);
template<class Alloc>
constexpr flat_set(const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_set(const flat_set&, const Alloc& a);
template<class Alloc>
constexpr flat_set(flat_set&&, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp,
const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a);
template<class InputIterator, class Alloc>
constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last,
const key_compare& comp, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_set(from_range_t, R&& rg, const Alloc& a);
template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R, class Alloc>
constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_set(initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_set(initializer_list<value_type> il, const key_compare& comp, const Alloc& a);
template<class Alloc>
constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a);
template<class Alloc>
constexpr flat_set(sorted_unique_t, initializer_list<value_type> il,
const key_compare& comp, const Alloc& a);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19267)
*Effects*: Equivalent to the corresponding non-allocator constructors
except that *c* is constructed with
uses-allocator construction ([[allocator.uses.construction]](allocator.uses.construction "20.2.8.2Uses-allocator construction"))[.](#6.sentence-1)

15
cppdraft/flat/set/defn.md Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,56 @@
[flat.set.erasure]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.erasure)
### 23.6.11 Class template flat_set [[flat.set]](flat.set#erasure)
#### 23.6.11.6 Erasure [flat.set.erasure]
[🔗](#lib:erase_if,flat_set)
`template<class Key, class Compare, class KeyContainer, class Predicate>
constexpr typename flat_set<Key, Compare, KeyContainer>::size_type
erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19444)
*Preconditions*: Key meets the *Cpp17MoveAssignable* requirements[.](#1.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19448)
*Effects*: Let E be bool(pred(as_const(e)))[.](#2.sentence-1)
Erases all elements e in c for which E holds[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19453)
*Returns*: The number of elements erased[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19457)
*Complexity*: Exactly c.size() applications of the predicate[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19461)
*Remarks*: Stable ([[algorithm.stable]](algorithm.stable "16.4.6.8Requirements for stable algorithms"))[.](#5.sentence-1)
If an invocation of erase_if exits via an exception,c is in a valid but unspecified state ([[defns.valid]](defns.valid "3.67valid but unspecified state"))[.](#5.sentence-2)
[*Note [1](#note-1)*:
c still meets its invariants, but can be empty[.](#5.sentence-3)
— *end note*]

View File

@@ -0,0 +1,175 @@
[flat.set.modifiers]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.modifiers)
### 23.6.11 Class template flat_set [[flat.set]](flat.set#modifiers)
#### 23.6.11.5 Modifiers [flat.set.modifiers]
[🔗](#lib:insert,flat_set)
`template<class K> constexpr pair<iterator, bool> insert(K&& x);
template<class K> constexpr iterator insert(const_iterator hint, K&& x);
`
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19283)
*Constraints*: The [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Compare::is_transparent is valid and denotes a type[.](#1.sentence-1)
is_constructible_v<value_type, K> is true[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19289)
*Preconditions*: The conversion from x into value_type constructs
an object u, for which find(x) == find(u) is true[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19294)
*Effects*: If the set already contains an element equivalent to x,*this and x are unchanged[.](#3.sentence-1)
Otherwise,
inserts a new element as if by emplace(std::forward<K>(x))[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19301)
*Returns*: In the first overload,
the bool component of the returned pair is true if and only if the insertion took place[.](#4.sentence-1)
The returned iterator points to the element
whose key is equivalent to x[.](#4.sentence-2)
[🔗](#lib:insert,flat_set_)
`template<class InputIterator>
constexpr void insert(InputIterator first, InputIterator last);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19317)
*Effects*: Adds elements to *c* as if by:*c*.insert(*c*.end(), first, last);
Then,
sorts the range of newly inserted elements with respect to *compare*;
merges the resulting sorted range and
the sorted range of pre-existing elements into a single sorted range; and
finally erases all but the first element
from each group of consecutive equivalent elements[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19330)
*Complexity*: N + MlogM, where N is size() before the operation andM is distance(first, last)[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19335)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#7.sentence-1)
[🔗](#lib:insert,flat_set__)
`template<class InputIterator>
constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19347)
*Effects*: Equivalent to insert(first, last)[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19351)
*Complexity*: Linear[.](#9.sentence-1)
[🔗](#lib:insert_range,flat_set)
`template<[container-compatible-range](container.intro.reqmts#concept:container-compatible-range "23.2.2.1Introduction[container.intro.reqmts]")<value_type> R>
constexpr void insert_range(R&& rg);
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19363)
*Effects*: Adds elements to *c* as if by:for (const auto& e : rg) {*c*.insert(*c*.end(), e);}
Then,
sorts the range of newly inserted elements with respect to *compare*;
merges the resulting sorted range and
the sorted range of pre-existing elements into a single sorted range; and
finally erases all but the first element
from each group of consecutive equivalent elements[.](#10.sentence-2)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19378)
*Complexity*: N + MlogM, where N is size() before the operation and M is ranges::distance(rg)[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19383)
*Remarks*: Since this operation performs an in-place merge, it may allocate memory[.](#12.sentence-1)
[🔗](#lib:swap,flat_set)
`constexpr void swap(flat_set& y) noexcept;
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19394)
*Effects*: Equivalent to:ranges::swap(*compare*, y.*compare*);
ranges::swap(*c*, y.*c*);
[🔗](#lib:extract,flat_set)
`constexpr container_type extract() &&;
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19409)
*Postconditions*: *this is emptied, even if the function exits via an exception[.](#14.sentence-1)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19413)
*Returns*: std::move(*c*)[.](#15.sentence-1)
[🔗](#lib:replace,flat_set)
`constexpr void replace(container_type&& cont);
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19424)
*Preconditions*: The elements of cont are sorted with respect to *compare*, andcont contains no equal elements[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L19429)
*Effects*: Equivalent to: *c* = std::move(cont);

View File

@@ -0,0 +1,137 @@
[flat.set.overview]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.overview)
### 23.6.11 Class template flat_set [[flat.set]](flat.set#overview)
#### 23.6.11.1 Overview [flat.set.overview]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18805)
A flat_set is a container adaptor
that provides an associative container interface
that supports unique keys
(i.e., contains at most one of each key value) and
provides for fast retrieval of the keys themselves[.](#1.sentence-1)
flat_set supports iterators that model
the [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") concept ([[iterator.concept.random.access]](iterator.concept.random.access "24.3.4.13Concept random_­access_­iterator"))[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18815)
A flat_set meets all of the requirements
for a container ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) and
for a reversible container ([[container.rev.reqmts]](container.rev.reqmts "23.2.2.3Reversible container requirements")),
plus the optional container requirements ([[container.opt.reqmts]](container.opt.reqmts "23.2.2.4Optional container requirements"))[.](#2.sentence-1)
flat_set meets the requirements of
an associative container ([[associative.reqmts]](associative.reqmts "23.2.7Associative containers")), except that:
- [(2.1)](#2.1)
it does not meet the requirements
related to node handles ([[container.node.overview]](container.node.overview "23.2.5.1Overview")),
- [(2.2)](#2.2)
it does not meet the requirements related to iterator invalidation, and
- [(2.3)](#2.3)
the time complexity of the operations
that insert or erase a single element from the set
is linear,
including the ones that take an insertion position iterator[.](#2.sentence-2)
[*Note [1](#note-1)*:
A flat_set does not meet
the additional requirements of an allocator-aware container,
as described in [[container.alloc.reqmts]](container.alloc.reqmts "23.2.2.5Allocator-aware containers")[.](#2.sentence-3)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18840)
A flat_set also provides most operations
described in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") for unique keys[.](#3.sentence-1)
This means that a flat_set supports
the a_uniq operations in [[associative.reqmts]](associative.reqmts "23.2.7Associative containers") but not the a_eq operations[.](#3.sentence-2)
For a flat_set<Key>,
both the key_type and value_type are Key[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18849)
Descriptions are provided here only for operations on flat_set that are not described in one of those sets of requirements or
for operations where there is additional semantic information[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18854)
A flat_set maintains the invariant that the keys are sorted with
respect to the comparison object[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18858)
If any member function in [[flat.set.defn]](flat.set.defn "23.6.11.2Definition") exits via an exception,
the invariant is restored[.](#6.sentence-1)
[*Note [2](#note-2)*:
This can result in the flat_set's being emptied[.](#6.sentence-2)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18865)
Any sequence container ([[sequence.reqmts]](sequence.reqmts "23.2.4Sequence containers"))
supporting *Cpp17RandomAccessIterator* can be used to instantiate flat_set[.](#7.sentence-1)
In particular, vector ([[vector]](vector "23.3.13Class template vector")) and deque ([[deque]](deque "23.3.5Class template deque"))
can be used[.](#7.sentence-2)
[*Note [3](#note-3)*:
vector<bool> is not a sequence container[.](#7.sentence-3)
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18875)
The program is ill-formed if Key is not the same type
as KeyContainer::value_type[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18879)
The effect of calling a constructor or member function
that takes a sorted_unique_t argument
with a range that is not sorted with respect to key_comp(), or
that contains equal elements, is undefined[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L18885)
The types iterator and const_iterator meet
the constexpr iterator requirements ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General"))[.](#10.sentence-1)

11
cppdraft/flat/set/syn.md Normal file
View File

@@ -0,0 +1,11 @@
[flat.set.syn]
# 23 Containers library [[containers]](./#containers)
## 23.6 Container adaptors [[container.adaptors]](container.adaptors#flat.set.syn)
### 23.6.10 Header <flat_set> synopsis [flat.set.syn]
#include <compare> // see [[compare.syn]](compare.syn "17.12.1Header <compare> synopsis")#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2Header <initializer_­list> synopsis")namespace std {// [[flat.set]](flat.set "23.6.11Class template flat_­set"), class template flat_settemplate<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>class flat_set; struct sorted_unique_t { explicit sorted_unique_t() = default; }; inline constexpr sorted_unique_t sorted_unique{}; template<class Key, class Compare, class KeyContainer, class Allocator>struct uses_allocator<flat_set<Key, Compare, KeyContainer>, Allocator>; // [[flat.set.erasure]](flat.set.erasure "23.6.11.6Erasure"), erasure for flat_settemplate<class Key, class Compare, class KeyContainer, class Predicate>constexpr typename flat_set<Key, Compare, KeyContainer>::size_type
erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred); // [[flat.multiset]](flat.multiset "23.6.12Class template flat_­multiset"), class template flat_multisettemplate<class Key, class Compare = less<Key>, class KeyContainer = vector<Key>>class flat_multiset; struct sorted_equivalent_t { explicit sorted_equivalent_t() = default; }; inline constexpr sorted_equivalent_t sorted_equivalent{}; template<class Key, class Compare, class KeyContainer, class Allocator>struct uses_allocator<flat_multiset<Key, Compare, KeyContainer>, Allocator>; // [[flat.multiset.erasure]](flat.multiset.erasure "23.6.12.6Erasure"), erasure for flat_multisettemplate<class Key, class Compare, class KeyContainer, class Predicate>constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type
erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred);}