-
Notifications
You must be signed in to change notification settings - Fork 803
P3567R2 flat_meow fixes
#8524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
P3567R2 flat_meow fixes
#8524
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17033,7 +17033,9 @@ | |||||||||
|
|
||||||||||
| \pnum | ||||||||||
| If any member function in \ref{flat.map.defn} exits via an exception | ||||||||||
| the invariants are restored. | ||||||||||
| the invariants of the object argument are restored. | ||||||||||
| For the move constructor and move assignment operator, | ||||||||||
| the invariants of both arguments are restored. | ||||||||||
| \begin{note} | ||||||||||
| This can result in the \tcode{flat_map} being emptied. | ||||||||||
| \end{note} | ||||||||||
|
|
@@ -17118,6 +17120,11 @@ | |||||||||
| // \ref{flat.map.cons}, constructors | ||||||||||
| constexpr flat_map() : flat_map(key_compare()) { } | ||||||||||
|
|
||||||||||
| constexpr flat_map(const flat_map&); | ||||||||||
| constexpr flat_map(flat_map&&); | ||||||||||
| constexpr flat_map& operator=(const flat_map&); | ||||||||||
| constexpr flat_map& operator=(flat_map&&); | ||||||||||
|
|
||||||||||
| constexpr explicit flat_map(const key_compare& comp) | ||||||||||
| : @\exposid{c}@(), @\exposid{compare}@(comp) { } | ||||||||||
|
|
||||||||||
|
|
@@ -17258,6 +17265,8 @@ | |||||||||
| constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(R&& rg); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_unique_t, R&& rg); | ||||||||||
|
|
||||||||||
| constexpr void insert(initializer_list<value_type> il) | ||||||||||
| { insert(il.begin(), il.end()); } | ||||||||||
|
|
@@ -17298,7 +17307,7 @@ | |||||||||
| template<class K> constexpr size_type erase(K&& x); | ||||||||||
| constexpr iterator erase(const_iterator first, const_iterator last); | ||||||||||
|
|
||||||||||
| constexpr void swap(flat_map& y) noexcept; | ||||||||||
| constexpr void swap(flat_map& y) noexcept(@\seebelow@); | ||||||||||
| constexpr void clear() noexcept; | ||||||||||
|
|
||||||||||
| // observers | ||||||||||
|
|
@@ -17341,7 +17350,7 @@ | |||||||||
| friend constexpr @\exposid{synth-three-way-result}@<value_type> | ||||||||||
| operator<=>(const flat_map& x, const flat_map& y); | ||||||||||
|
|
||||||||||
| friend constexpr void swap(flat_map& x, flat_map& y) noexcept | ||||||||||
| friend constexpr void swap(flat_map& x, flat_map& y) noexcept(noexcept(x.swap(y))) | ||||||||||
| { x.swap(y); } | ||||||||||
|
|
||||||||||
| private: | ||||||||||
|
|
@@ -17816,10 +17825,10 @@ | |||||||||
| \effects | ||||||||||
| Adds elements to \exposid{c} as if by: | ||||||||||
| \begin{codeblock} | ||||||||||
| for (const auto& e : rg) { | ||||||||||
| @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), e.first); | ||||||||||
| @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), e.second); | ||||||||||
| } | ||||||||||
| ranges::for_each(rg, [&](value_type e) { | ||||||||||
| @\exposid{c}@.keys.insert(@\exposid{c}@.keys.end(), std::move(e.first)); | ||||||||||
| @\exposid{c}@.values.insert(@\exposid{c}@.values.end(), std::move(e.second)); | ||||||||||
| }); | ||||||||||
| \end{codeblock} | ||||||||||
| Then, sorts the range of newly inserted elements | ||||||||||
| with respect to \tcode{value_comp()}; | ||||||||||
|
|
@@ -17845,6 +17854,22 @@ | |||||||||
| Since this operation performs an in-place merge, it may allocate memory. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{insert_range}{flat_map}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_unique_t, R&& rg); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
| \pnum | ||||||||||
| \effects | ||||||||||
| Equivalent to \tcode{insert_range(rg)}. | ||||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \complexity | ||||||||||
| Linear in $N$, where $N$ is \tcode{size()} after the operation. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{try_emplace}{flat_map}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| template<class... Args> | ||||||||||
|
|
@@ -18047,7 +18072,10 @@ | |||||||||
|
|
||||||||||
| \indexlibrarymember{swap}{flat_map}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| constexpr void swap(flat_map& y) noexcept; | ||||||||||
| constexpr void swap(flat_map& y) | ||||||||||
| noexcept(is_nothrow_swappable_v<key_container_type> && | ||||||||||
| is_nothrow_swappable_v<mapped_container_type> && | ||||||||||
| is_nothrow_swappable_v<key_compare>); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
|
|
@@ -18209,7 +18237,9 @@ | |||||||||
|
|
||||||||||
| \pnum | ||||||||||
| If any member function in \ref{flat.multimap.defn} exits via an exception, | ||||||||||
| the invariants are restored. | ||||||||||
| the invariants of the object argument are restored. | ||||||||||
| For the move constructor and move assignment operator, | ||||||||||
| the invariants of both arguments are restored. | ||||||||||
| \begin{note} | ||||||||||
| This can result in the \tcode{flat_multimap} being emptied. | ||||||||||
| \end{note} | ||||||||||
|
|
@@ -18292,6 +18322,11 @@ | |||||||||
| // \ref{flat.multimap.cons}, constructors | ||||||||||
| constexpr flat_multimap() : flat_multimap(key_compare()) { } | ||||||||||
|
|
||||||||||
| constexpr flat_multimap(const flat_multimap&); | ||||||||||
| constexpr flat_multimap(flat_multimap&&); | ||||||||||
| constexpr flat_multimap& operator=(const flat_multimap&); | ||||||||||
| constexpr flat_multimap& operator=(flat_multimap&&); | ||||||||||
|
|
||||||||||
| constexpr explicit flat_multimap(const key_compare& comp) | ||||||||||
| : @\exposid{c}@(), @\exposid{compare}@(comp) { } | ||||||||||
|
|
||||||||||
|
|
@@ -18425,6 +18460,8 @@ | |||||||||
| constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(R&& rg); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_equivalent_t, R&& rg); | ||||||||||
|
|
||||||||||
| constexpr void insert(initializer_list<value_type> il) | ||||||||||
| { insert(il.begin(), il.end()); } | ||||||||||
|
|
@@ -18440,7 +18477,10 @@ | |||||||||
| 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 swap(flat_multimap&) | ||||||||||
| noexcept(is_nothrow_swappable_v<key_container_type> && | ||||||||||
| is_nothrow_swappable_v<mapped_container_type> && | ||||||||||
| is_nothrow_swappable_v<key_compare>); | ||||||||||
| constexpr void clear() noexcept; | ||||||||||
|
|
||||||||||
| // observers | ||||||||||
|
|
@@ -18484,7 +18524,8 @@ | |||||||||
| friend constexpr @\exposid{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 | ||||||||||
| friend constexpr void swap(flat_multimap& x, flat_multimap& y) | ||||||||||
| noexcept(noexcept(x.swap(y))) | ||||||||||
| { x.swap(y); } | ||||||||||
|
|
||||||||||
| private: | ||||||||||
|
|
@@ -18852,7 +18893,9 @@ | |||||||||
|
|
||||||||||
| \pnum | ||||||||||
| If any member function in \ref{flat.set.defn} exits via an exception, | ||||||||||
| the invariant is restored. | ||||||||||
| the invariant of the object argument is restored. | ||||||||||
| For the move constructor and move assignment operator, | ||||||||||
| the invariants of both arguments are restored. | ||||||||||
| \begin{note} | ||||||||||
| This can result in the \tcode{flat_set}'s being emptied. | ||||||||||
| \end{note} | ||||||||||
|
|
@@ -18906,6 +18949,11 @@ | |||||||||
| // \ref{flat.set.cons}, constructors | ||||||||||
| constexpr flat_set() : flat_set(key_compare()) { } | ||||||||||
|
|
||||||||||
| constexpr flat_set(const flat_set&); | ||||||||||
| constexpr flat_set(flat_set&&); | ||||||||||
| constexpr flat_set& operator=(const flat_set&); | ||||||||||
| constexpr flat_set& operator=(flat_set&&); | ||||||||||
|
|
||||||||||
| constexpr explicit flat_set(const key_compare& comp) | ||||||||||
| : @\exposid{c}@(), @\exposid{compare}@(comp) { } | ||||||||||
|
|
||||||||||
|
|
@@ -19031,6 +19079,8 @@ | |||||||||
| constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(R&& rg); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_unique_t, R&& rg); | ||||||||||
|
|
||||||||||
| constexpr void insert(initializer_list<value_type> il) | ||||||||||
| { insert(il.begin(), il.end()); } | ||||||||||
|
|
@@ -19046,7 +19096,7 @@ | |||||||||
| template<class K> constexpr size_type erase(K&& x); | ||||||||||
| constexpr iterator erase(const_iterator first, const_iterator last); | ||||||||||
|
|
||||||||||
| constexpr void swap(flat_set& y) noexcept; | ||||||||||
| constexpr void swap(flat_set& y) noexcept(@\seebelow@); | ||||||||||
| constexpr void clear() noexcept; | ||||||||||
|
|
||||||||||
| // observers | ||||||||||
|
|
@@ -19087,7 +19137,8 @@ | |||||||||
| friend constexpr @\exposid{synth-three-way-result}@<value_type> | ||||||||||
| operator<=>(const flat_set& x, const flat_set& y); | ||||||||||
|
|
||||||||||
| friend constexpr void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } | ||||||||||
| friend constexpr void swap(flat_set& x, flat_set& y) noexcept(noexcept(x.swap(y))) | ||||||||||
| { x.swap(y); } | ||||||||||
|
|
||||||||||
| private: | ||||||||||
| container_type @\exposidnc{c}@; // \expos | ||||||||||
|
|
@@ -19359,9 +19410,9 @@ | |||||||||
| \effects | ||||||||||
| Adds elements to \exposid{c} as if by: | ||||||||||
| \begin{codeblock} | ||||||||||
| for (const auto& e : rg) { | ||||||||||
| @\exposid{c}@.insert(@\exposid{c}@.end(), e); | ||||||||||
| } | ||||||||||
| ranges::for_each(rg, [&](auto&& e) { | ||||||||||
| @\exposid{c}@.insert(@\exposid{c}@.end(), std::forward<decltype(e)>(e)); | ||||||||||
| }); | ||||||||||
| \end{codeblock} | ||||||||||
| Then, | ||||||||||
| sorts the range of newly inserted elements with respect to \exposid{compare}; | ||||||||||
|
|
@@ -19380,9 +19431,27 @@ | |||||||||
| Since this operation performs an in-place merge, it may allocate memory. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{insert_range}{flat_set}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_unique_t, R&& rg); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
| \pnum | ||||||||||
| \effects | ||||||||||
| Equivalent to \tcode{insert_range(rg)}. | ||||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \complexity | ||||||||||
| Linear in $N$, where $N$ is \tcode{size()} after the operation. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{swap}{flat_set}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| constexpr void swap(flat_set& y) noexcept; | ||||||||||
| constexpr void swap(flat_set& y) | ||||||||||
| noexcept(is_nothrow_swappable_v<container_type> && | ||||||||||
| is_nothrow_swappable_v<key_compare>); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
|
|
@@ -19522,7 +19591,9 @@ | |||||||||
|
|
||||||||||
| \pnum | ||||||||||
| If any member function in \ref{flat.multiset.defn} exits via an exception, | ||||||||||
| the invariant is restored. | ||||||||||
| the invariant of the object argument is restored. | ||||||||||
| For the move constructor and move assignment operator, | ||||||||||
| the invariants of both arguments are restored. | ||||||||||
| \begin{note} | ||||||||||
| This can result in the \tcode{flat_multiset}'s being emptied. | ||||||||||
| \end{note} | ||||||||||
|
|
@@ -19575,6 +19646,11 @@ | |||||||||
| // \ref{flat.multiset.cons}, constructors | ||||||||||
| constexpr flat_multiset() : flat_multiset(key_compare()) { } | ||||||||||
|
|
||||||||||
| constexpr flat_multiset(const flat_multiset&); | ||||||||||
| constexpr flat_multiset(flat_multiset&&); | ||||||||||
| constexpr flat_multiset& operator=(const flat_multiset&); | ||||||||||
| constexpr flat_multiset& operator=(flat_multiset&&); | ||||||||||
|
|
||||||||||
| constexpr explicit flat_multiset(const key_compare& comp) | ||||||||||
| : @\exposid{c}@(), @\exposid{compare}@(comp) { } | ||||||||||
|
|
||||||||||
|
|
@@ -19702,6 +19778,8 @@ | |||||||||
| constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(R&& rg); | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_equivalent_t, R&& rg); | ||||||||||
|
|
||||||||||
| constexpr void insert(initializer_list<value_type> il) | ||||||||||
| { insert(il.begin(), il.end()); } | ||||||||||
|
|
@@ -19717,7 +19795,7 @@ | |||||||||
| template<class K> constexpr size_type erase(K&& x); | ||||||||||
| constexpr iterator erase(const_iterator first, const_iterator last); | ||||||||||
|
|
||||||||||
| constexpr void swap(flat_multiset& y) noexcept; | ||||||||||
| constexpr void swap(flat_multiset& y) noexcept(@\seebelow@); | ||||||||||
| constexpr void clear() noexcept; | ||||||||||
|
|
||||||||||
| // observers | ||||||||||
|
|
@@ -19758,7 +19836,8 @@ | |||||||||
| friend constexpr @\exposid{synth-three-way-result}@<value_type> | ||||||||||
| operator<=>(const flat_multiset& x, const flat_multiset& y); | ||||||||||
|
|
||||||||||
| friend constexpr void swap(flat_multiset& x, flat_multiset& y) noexcept | ||||||||||
| friend constexpr void swap(flat_multiset& x, flat_multiset& y) | ||||||||||
| noexcept(noexcept(x.swap(y))) | ||||||||||
| { x.swap(y); } | ||||||||||
|
|
||||||||||
| private: | ||||||||||
|
|
@@ -20005,12 +20084,60 @@ | |||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \complexity | ||||||||||
| Linear. | ||||||||||
| Linear in $N$, where $N$ is \tcode{size()} after the operation. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{insert_range}{flat_multiset}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| void insert_range(R&& rg); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
| \pnum | ||||||||||
| \effects | ||||||||||
| Adds elements to \exposid{c} as if by: | ||||||||||
| \begin{codeblock} | ||||||||||
| ranges::for_each(rg, [&](auto&& e) { | ||||||||||
| @\exposid{c}@.insert(@\exposid{c}@.end(), std::forward<decltype(e)>(e)); | ||||||||||
| }); | ||||||||||
| \end{codeblock} | ||||||||||
| Then, sorts the range of newly inserted elements with respect to \exposid{compare}, | ||||||||||
| and merges the resulting sorted range and | ||||||||||
| the sorted range of pre-existing elements into a single sorted range. | ||||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \complexity | ||||||||||
| $N$ + $M \log M$, where $N$ is \tcode{size()} before the operation and $M$ | ||||||||||
| is \tcode{ranges::distance(rg)}. | ||||||||||
|
Comment on lines
+20111
to
+20112
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
(semantic break)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The chosen line break is consistent with what we have further up for The |
||||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \remarks | ||||||||||
| Since this operation performs an in-place merge, | ||||||||||
| it may allocate memory. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{insert_range}{flat_multiset}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| template<@\exposconcept{container-compatible-range}@<value_type> R> | ||||||||||
| constexpr void insert_range(sorted_equivalent_t, R&& rg); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
| \pnum | ||||||||||
| \effects | ||||||||||
| Equivalent to \tcode{insert_range(rg)}. | ||||||||||
|
|
||||||||||
| \pnum | ||||||||||
| \complexity | ||||||||||
| Linear in $N$, where $N$ is \tcode{size()} after the operation. | ||||||||||
| \end{itemdescr} | ||||||||||
|
|
||||||||||
| \indexlibrarymember{swap}{flat_multiset}% | ||||||||||
| \begin{itemdecl} | ||||||||||
| constexpr void swap(flat_multiset& y) noexcept; | ||||||||||
| constexpr void swap(flat_multiset& y) | ||||||||||
| noexcept(is_nothrow_swappable_v<container_type> && | ||||||||||
| is_nothrow_swappable_v<key_compare>); | ||||||||||
| \end{itemdecl} | ||||||||||
|
|
||||||||||
| \begin{itemdescr} | ||||||||||
|
|
||||||||||
Uh oh!
There was an error while loading. Please reload this page.