diff --git a/source/containers.tex b/source/containers.tex index a36bba936c..e305ff2c24 100644 --- a/source/containers.tex +++ b/source/containers.tex @@ -2311,27 +2311,27 @@ public: // \ref{container.node.cons}, constructors, copy, and assignment constexpr @\placeholdernc{node-handle}@() noexcept : ptr_(), alloc_() {} - @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&&) noexcept; - @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&&); + constexpr @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&&) noexcept; + constexpr @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&&); // \ref{container.node.dtor}, destructor - ~@\placeholdernc{node-handle}@(); + constexpr ~@\placeholdernc{node-handle}@(); // \ref{container.node.observers}, observers - value_type& value() const; // not present for map containers - key_type& key() const; // not present for set containers - mapped_type& mapped() const; // not present for set containers + constexpr value_type& value() const; // not present for map containers + key_type& key() const; // not present for set containers + constexpr mapped_type& mapped() const; // not present for set containers - allocator_type get_allocator() const; - explicit operator bool() const noexcept; - bool empty() const noexcept; + constexpr allocator_type get_allocator() const; + constexpr explicit operator bool() const noexcept; + constexpr bool empty() const noexcept; // \ref{container.node.modifiers}, modifiers - void swap(@\placeholdernc{node-handle}@&) + constexpr void swap(@\placeholdernc{node-handle}@&) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); - friend void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { + constexpr friend void swap(@\placeholdernc{node-handle}@& x, @\placeholdernc{node-handle}@& y) noexcept(noexcept(x.swap(y))) { x.swap(y); } }; @@ -2340,7 +2340,7 @@ \rSec3[container.node.cons]{Constructors, copy, and assignment} \begin{itemdecl} -@\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&& nh) noexcept; +constexpr @\placeholdernc{node-handle}@(@\placeholdernc{node-handle}@&& nh) noexcept; \end{itemdecl} \begin{itemdescr} @@ -2353,7 +2353,7 @@ \end{itemdescr} \begin{itemdecl} -@\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&& nh); +constexpr @\placeholdernc{node-handle}@& operator=(@\placeholdernc{node-handle}@&& nh); \end{itemdecl} \begin{itemdescr} @@ -2395,7 +2395,7 @@ \rSec3[container.node.dtor]{Destructor} \begin{itemdecl} -~@\placeholdernc{node-handle}@(); +constexpr ~@\placeholdernc{node-handle}@(); \end{itemdecl} \begin{itemdescr} @@ -2410,7 +2410,7 @@ \rSec3[container.node.observers]{Observers} \begin{itemdecl} -value_type& value() const; +constexpr value_type& value() const; \end{itemdecl} \begin{itemdescr} @@ -2453,7 +2453,7 @@ \end{itemdescr} \begin{itemdecl} -mapped_type& mapped() const; +constexpr mapped_type& mapped() const; \end{itemdecl} \begin{itemdescr} @@ -2472,9 +2472,8 @@ Nothing. \end{itemdescr} - \begin{itemdecl} -allocator_type get_allocator() const; +constexpr allocator_type get_allocator() const; \end{itemdecl} \begin{itemdescr} @@ -2492,7 +2491,7 @@ \end{itemdescr} \begin{itemdecl} -explicit operator bool() const noexcept; +constexpr explicit operator bool() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -2502,7 +2501,7 @@ \end{itemdescr} \begin{itemdecl} -bool empty() const noexcept; +constexpr bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -2514,7 +2513,7 @@ \rSec3[container.node.modifiers]{Modifiers} \begin{itemdecl} -void swap(@\placeholdernc{node-handle}@& nh) +constexpr void swap(@\placeholdernc{node-handle}@& nh) noexcept(ator_traits::propagate_on_container_swap::value || ator_traits::is_always_equal::value); \end{itemdecl} @@ -6381,21 +6380,21 @@ template<class T, class Allocator = allocator<T>> class deque; template<class T, class Allocator> - bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y); + constexpr bool operator==(const deque<T, Allocator>& x, const deque<T, Allocator>& y); template<class T, class Allocator> - @\placeholder{synth-three-way-result}@<T> operator<=>(const deque<T, Allocator>& x, + constexpr @\placeholder{synth-three-way-result}@<T> operator<=>(const deque<T, Allocator>& x, @\itcorr@ const deque<T, Allocator>& y); template<class T, class Allocator> - void swap(deque<T, Allocator>& x, deque<T, Allocator>& y) + constexpr void swap(deque<T, Allocator>& x, deque<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{deque.erasure}, erasure template<class T, class Allocator, class U = T> - typename deque<T, Allocator>::size_type + constexpr typename deque<T, Allocator>::size_type erase(deque<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> - typename deque<T, Allocator>::size_type + constexpr typename deque<T, Allocator>::size_type erase_if(deque<T, Allocator>& c, Predicate pred); namespace pmr { @@ -6431,6 +6430,10 @@ that are not described in one of these tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template<class T, class Allocator = allocator<T>> @@ -6451,97 +6454,98 @@ using const_reverse_iterator = std::reverse_iterator<const_iterator>; // \ref{deque.cons}, construct/copy/destroy - deque() : deque(Allocator()) { } - explicit deque(const Allocator&); - explicit deque(size_type n, const Allocator& = Allocator()); - deque(size_type n, const T& value, const Allocator& = Allocator()); + constexpr deque() : deque(Allocator()) { } + constexpr explicit deque(const Allocator&); + constexpr explicit deque(size_type n, const Allocator& = Allocator()); + constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> - deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<T> R> - deque(from_range_t, R&& rg, const Allocator& = Allocator()); - deque(const deque& x); - deque(deque&&); - deque(const deque&, const type_identity_t<Allocator>&); - deque(deque&&, const type_identity_t<Allocator>&); - deque(initializer_list<T>, const Allocator& = Allocator()); - - ~deque(); - deque& operator=(const deque& x); - deque& operator=(deque&& x) + constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr deque(const deque& x); + constexpr deque(deque&&); + constexpr deque(const deque&, const type_identity_t<Allocator>&); + constexpr deque(deque&&, const type_identity_t<Allocator>&); + constexpr deque(initializer_list<T>, const Allocator& = Allocator()); + + constexpr ~deque(); + constexpr deque& operator=(const deque& x); + constexpr deque& operator=(deque&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); - deque& operator=(initializer_list<T>); + constexpr deque& operator=(initializer_list<T>); template<class InputIterator> - void assign(InputIterator first, InputIterator last); + constexpr void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - void assign_range(R&& rg); - void assign(size_type n, const T& t); - void assign(initializer_list<T>); - allocator_type get_allocator() const noexcept; + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list<T>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr 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; // \ref{deque.capacity}, capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - void resize(size_type sz); - void resize(size_type sz, const T& c); - void shrink_to_fit(); + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); + constexpr void shrink_to_fit(); // element access - reference operator[](size_type n); - const_reference operator[](size_type n) const; - reference at(size_type n); - const_reference at(size_type n) const; - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; + constexpr reference operator[](size_type n); + constexpr const_reference operator[](size_type n) const; + constexpr reference at(size_type n); + constexpr const_reference at(size_type n) const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; // \ref{deque.modifiers}, modifiers - template<class... Args> reference emplace_front(Args&&... args); - template<class... Args> reference emplace_back(Args&&... args); - template<class... Args> iterator emplace(const_iterator position, Args&&... args); + template<class... Args> constexpr reference emplace_front(Args&&... args); + template<class... Args> constexpr reference emplace_back(Args&&... args); + template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); - void push_front(const T& x); - void push_front(T&& x); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); - void push_back(const T& x); - void push_back(T&& x); + constexpr void prepend_range(R&& rg); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void append_range(R&& rg); + constexpr void append_range(R&& rg); - iterator insert(const_iterator position, const T& x); - iterator insert(const_iterator position, T&& x); - iterator insert(const_iterator position, size_type n, const T& x); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> - iterator insert(const_iterator position, InputIterator first, InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range(const_iterator position, R&& rg); - iterator insert(const_iterator position, initializer_list<T>); + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list<T>); - void pop_front(); - void pop_back(); + constexpr void pop_front(); + constexpr void pop_back(); - iterator erase(const_iterator position); - iterator erase(const_iterator first, const_iterator last); - void swap(deque&) + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(deque&) noexcept(allocator_traits<Allocator>::is_always_equal::value); - void clear() noexcept; + constexpr void clear() noexcept; }; template<class InputIterator, class Allocator = allocator<@\placeholder{iter-value-type}@<InputIterator>>> @@ -6558,7 +6562,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} -explicit deque(const Allocator&); +constexpr explicit deque(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -6575,7 +6579,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} -explicit deque(size_type n, const Allocator& = Allocator()); +constexpr explicit deque(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6595,7 +6599,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} -deque(size_type n, const T& value, const Allocator& = Allocator()); +constexpr deque(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6618,7 +6622,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} template<class InputIterator> - deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr deque(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6638,7 +6642,7 @@ \indexlibraryctor{deque}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - deque(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr deque(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -6656,7 +6660,7 @@ \indexlibrarymember{resize}{deque}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -6673,7 +6677,7 @@ \indexlibrarymember{resize}{deque}% \begin{itemdecl} -void resize(size_type sz, const T& c); +constexpr void resize(size_type sz, const T& c); \end{itemdecl} \begin{itemdescr} @@ -6690,7 +6694,7 @@ \indexlibrarymember{shrink_to_fit}{deque}% \begin{itemdecl} -void shrink_to_fit(); +constexpr void shrink_to_fit(); \end{itemdecl} \begin{itemdescr} @@ -6732,27 +6736,27 @@ \indexlibrarymember{push_back}{deque}% \indexlibrarymember{emplace}{deque}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> - iterator insert(const_iterator position, - InputIterator first, InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range(const_iterator position, R&& rg); -iterator insert(const_iterator position, initializer_list<T>); - -template<class... Args> reference emplace_front(Args&&... args); -template<class... Args> reference emplace_back(Args&&... args); -template<class... Args> iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list<T>); + +template<class... Args> constexpr reference emplace_front(Args&&... args); +template<class... Args> constexpr reference emplace_back(Args&&... args); +template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); -void push_back(const T& x); -void push_back(T&& x); + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void append_range(R&& rg); + constexpr void append_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -6788,10 +6792,10 @@ \indexlibrarymember{erase}{deque}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); -void pop_front(); -void pop_back(); +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); \end{itemdecl} \begin{itemdescr} @@ -6824,7 +6828,7 @@ \indexlibrarymember{erase}{deque}% \begin{itemdecl} template<class T, class Allocator, class U = T> - typename deque<T, Allocator>::size_type + constexpr typename deque<T, Allocator>::size_type erase(deque<T, Allocator>& c, const U& value); \end{itemdecl} @@ -6843,7 +6847,7 @@ \indexlibrarymember{erase_if}{deque}% \begin{itemdecl} template<class T, class Allocator, class Predicate> - typename deque<T, Allocator>::size_type + constexpr typename deque<T, Allocator>::size_type erase_if(deque<T, Allocator>& c, Predicate pred); \end{itemdecl} @@ -6871,21 +6875,22 @@ template<class T, class Allocator = allocator<T>> class forward_list; template<class T, class Allocator> - bool operator==(const forward_list<T, Allocator>& x, const forward_list<T, Allocator>& y); + constexpr bool operator==(const forward_list<T, Allocator>& x, + const forward_list<T, Allocator>& y); template<class T, class Allocator> - @\placeholder{synth-three-way-result}@<T> operator<=>(const forward_list<T, Allocator>& x, - @\itcorr@ const forward_list<T, Allocator>& y); + constexpr @\placeholder{synth-three-way-result}@<T> operator<=>(const forward_list<T, Allocator>& x, + @\itcorr@ const forward_list<T, Allocator>& y); template<class T, class Allocator> - void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) + constexpr void swap(forward_list<T, Allocator>& x, forward_list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{forward.list.erasure}, erasure template<class T, class Allocator, class U = T> - typename forward_list<T, Allocator>::size_type + constexpr typename forward_list<T, Allocator>::size_type erase(forward_list<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> - typename forward_list<T, Allocator>::size_type + constexpr typename forward_list<T, Allocator>::size_type erase_if(forward_list<T, Allocator>& c, Predicate pred); namespace pmr { @@ -6932,6 +6937,10 @@ take fully-open ranges, not semi-open ranges. \end{note} +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template<class T, class Allocator = allocator<T>> @@ -6950,105 +6959,108 @@ using const_iterator = @\impdefx{type of \tcode{forward_list::const_iterator}}@; // see \ref{container.requirements} // \ref{forward.list.cons}, construct/copy/destroy - forward_list() : forward_list(Allocator()) { } - explicit forward_list(const Allocator&); - explicit forward_list(size_type n, const Allocator& = Allocator()); - forward_list(size_type n, const T& value, const Allocator& = Allocator()); + constexpr forward_list() : forward_list(Allocator()) { } + constexpr explicit forward_list(const Allocator&); + constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); + constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> - forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr forward_list(InputIterator first, InputIterator last, + const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<T> R> - forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); - forward_list(const forward_list& x); - forward_list(forward_list&& x); - forward_list(const forward_list& x, const type_identity_t<Allocator>&); - forward_list(forward_list&& x, const type_identity_t<Allocator>&); - forward_list(initializer_list<T>, const Allocator& = Allocator()); - ~forward_list(); - forward_list& operator=(const forward_list& x); - forward_list& operator=(forward_list&& x) + constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr forward_list(const forward_list& x); + constexpr forward_list(forward_list&& x); + constexpr forward_list(const forward_list& x, const type_identity_t<Allocator>&); + constexpr forward_list(forward_list&& x, const type_identity_t<Allocator>&); + constexpr forward_list(initializer_list<T>, const Allocator& = Allocator()); + constexpr ~forward_list(); + constexpr forward_list& operator=(const forward_list& x); + constexpr forward_list& operator=(forward_list&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); - forward_list& operator=(initializer_list<T>); + constexpr forward_list& operator=(initializer_list<T>); template<class InputIterator> - void assign(InputIterator first, InputIterator last); + constexpr void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - void assign_range(R&& rg); - void assign(size_type n, const T& t); - void assign(initializer_list<T>); - allocator_type get_allocator() const noexcept; + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list<T>); + constexpr allocator_type get_allocator() const noexcept; // \ref{forward.list.iter}, iterators - iterator before_begin() noexcept; - const_iterator before_begin() const noexcept; - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator before_begin() noexcept; + constexpr const_iterator before_begin() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cbefore_begin() const noexcept; - const_iterator cend() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cbefore_begin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - bool empty() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{forward.list.access}, element access - reference front(); - const_reference front() const; + constexpr reference front(); + constexpr const_reference front() const; // \ref{forward.list.modifiers}, modifiers - template<class... Args> reference emplace_front(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); + template<class... Args> constexpr reference emplace_front(Args&&... args); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); - void pop_front(); + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); - template<class... Args> iterator emplace_after(const_iterator position, Args&&... args); - iterator insert_after(const_iterator position, const T& x); - iterator insert_after(const_iterator position, T&& x); + template<class... Args> + constexpr iterator emplace_after(const_iterator position, Args&&... args); + constexpr iterator insert_after(const_iterator position, const T& x); + constexpr iterator insert_after(const_iterator position, T&& x); - iterator insert_after(const_iterator position, size_type n, const T& x); + constexpr iterator insert_after(const_iterator position, size_type n, const T& x); template<class InputIterator> - iterator insert_after(const_iterator position, InputIterator first, InputIterator last); - iterator insert_after(const_iterator position, initializer_list<T> il); + constexpr iterator insert_after(const_iterator position, + InputIterator first, InputIterator last); + constexpr iterator insert_after(const_iterator position, initializer_list<T> il); template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range_after(const_iterator position, R&& rg); + constexpr iterator insert_range_after(const_iterator position, R&& rg); - iterator erase_after(const_iterator position); - iterator erase_after(const_iterator position, const_iterator last); - void swap(forward_list&) + constexpr iterator erase_after(const_iterator position); + constexpr iterator erase_after(const_iterator position, const_iterator last); + constexpr void swap(forward_list&) noexcept(allocator_traits<Allocator>::is_always_equal::value); - void resize(size_type sz); - void resize(size_type sz, const value_type& c); - void clear() noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const value_type& c); + constexpr void clear() noexcept; // \ref{forward.list.ops}, \tcode{forward_list} operations - void splice_after(const_iterator position, forward_list& x); - void splice_after(const_iterator position, forward_list&& x); - void splice_after(const_iterator position, forward_list& x, const_iterator i); - void splice_after(const_iterator position, forward_list&& x, const_iterator i); - void splice_after(const_iterator position, forward_list& x, + constexpr void splice_after(const_iterator position, forward_list& x); + constexpr void splice_after(const_iterator position, forward_list&& x); + constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); + constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i); + constexpr void splice_after(const_iterator position, forward_list& x, const_iterator first, const_iterator last); - void splice_after(const_iterator position, forward_list&& x, + constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator first, const_iterator last); - size_type remove(const T& value); - template<class Predicate> size_type remove_if(Predicate pred); + constexpr size_type remove(const T& value); + template<class Predicate> constexpr size_type remove_if(Predicate pred); size_type unique(); - template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred); + template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred); - void merge(forward_list& x); - void merge(forward_list&& x); - template<class Compare> void merge(forward_list& x, Compare comp); - template<class Compare> void merge(forward_list&& x, Compare comp); + constexpr void merge(forward_list& x); + constexpr void merge(forward_list&& x); + template<class Compare> constexpr void merge(forward_list& x, Compare comp); + template<class Compare> constexpr void merge(forward_list&& x, Compare comp); - void sort(); - template<class Compare> void sort(Compare comp); + constexpr void sort(); + template<class Compare> constexpr void sort(Compare comp); - void reverse() noexcept; + constexpr void reverse() noexcept; }; template<class InputIterator, class Allocator = allocator<@\placeholder{iter-value-type}@<InputIterator>>> @@ -7072,7 +7084,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -explicit forward_list(const Allocator&); +constexpr explicit forward_list(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -7087,7 +7099,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -explicit forward_list(size_type n, const Allocator& = Allocator()); +constexpr explicit forward_list(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7107,7 +7119,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} -forward_list(size_type n, const T& value, const Allocator& = Allocator()); +constexpr forward_list(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7127,7 +7139,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} template<class InputIterator> - forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr forward_list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7143,7 +7155,7 @@ \indexlibraryctor{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr forward_list(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -7162,9 +7174,9 @@ \indexlibrarymember{before_begin}{forward_list}% \indexlibrarymember{cbefore_begin}{forward_list}% \begin{itemdecl} -iterator before_begin() noexcept; -const_iterator before_begin() const noexcept; -const_iterator cbefore_begin() const noexcept; +constexpr iterator before_begin() noexcept; +constexpr const_iterator before_begin() const noexcept; +constexpr const_iterator cbefore_begin() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -7187,8 +7199,8 @@ \indexlibrarymember{front}{forward_list}% \begin{itemdecl} -reference front(); -const_reference front() const; +constexpr reference front(); +constexpr const_reference front() const; \end{itemdecl} \begin{itemdescr} @@ -7214,7 +7226,7 @@ \indexlibrarymember{emplace_front}{forward_list}% \begin{itemdecl} -template<class... Args> reference emplace_front(Args&&... args); +template<class... Args> constexpr reference emplace_front(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7226,8 +7238,8 @@ \indexlibrarymember{push_front}{forward_list}% \begin{itemdecl} -void push_front(const T& x); -void push_front(T&& x); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); \end{itemdecl} \begin{itemdescr} @@ -7239,7 +7251,7 @@ \indexlibrarymember{prepend_range}{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); + constexpr void prepend_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -7253,7 +7265,7 @@ \indexlibrarymember{pop}{forward_list}% \begin{itemdecl} -void pop_front(); +constexpr void pop_front(); \end{itemdecl} \begin{itemdescr} @@ -7264,7 +7276,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, const T& x); +constexpr iterator insert_after(const_iterator position, const T& x); \end{itemdecl} \begin{itemdescr} @@ -7285,7 +7297,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, T&& x); +constexpr iterator insert_after(const_iterator position, T&& x); \end{itemdecl} \begin{itemdescr} @@ -7306,7 +7318,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, size_type n, const T& x); +constexpr iterator insert_after(const_iterator position, size_type n, const T& x); \end{itemdecl} \begin{itemdescr} @@ -7329,7 +7341,8 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} template<class InputIterator> - iterator insert_after(const_iterator position, InputIterator first, InputIterator last); + constexpr iterator insert_after(const_iterator position, + InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -7354,7 +7367,7 @@ \indexlibrarymember{insert_range_after}{forward_list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range_after(const_iterator position, R&& rg); + constexpr iterator insert_range_after(const_iterator position, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -7378,7 +7391,7 @@ \indexlibrarymember{insert_after}{forward_list}% \begin{itemdecl} -iterator insert_after(const_iterator position, initializer_list<T> il); +constexpr iterator insert_after(const_iterator position, initializer_list<T> il); \end{itemdecl} \begin{itemdescr} @@ -7391,7 +7404,7 @@ \indexlibrarymember{emplace_after}{forward_list}% \begin{itemdecl} template<class... Args> - iterator emplace_after(const_iterator position, Args&&... args); + constexpr iterator emplace_after(const_iterator position, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -7414,7 +7427,7 @@ \indexlibrarymember{erase_after}{forward_list}% \begin{itemdecl} -iterator erase_after(const_iterator position); +constexpr iterator erase_after(const_iterator position); \end{itemdecl} \begin{itemdescr} @@ -7437,7 +7450,7 @@ \end{itemdescr} \begin{itemdecl} -iterator erase_after(const_iterator position, const_iterator last); +constexpr iterator erase_after(const_iterator position, const_iterator last); \end{itemdecl} \begin{itemdescr} @@ -7460,7 +7473,7 @@ \indexlibrarymember{resize}{forward_list}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -7476,7 +7489,7 @@ \end{itemdescr} \begin{itemdecl} -void resize(size_type sz, const value_type& c); +constexpr void resize(size_type sz, const value_type& c); \end{itemdecl} \begin{itemdescr} @@ -7494,7 +7507,7 @@ \indexlibrarymember{clear}{forward_list}% \begin{itemdecl} -void clear() noexcept; +constexpr void clear() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7525,8 +7538,8 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x); -void splice_after(const_iterator position, forward_list&& x); +constexpr void splice_after(const_iterator position, forward_list& x); +constexpr void splice_after(const_iterator position, forward_list&& x); \end{itemdecl} \begin{itemdescr} @@ -7556,8 +7569,8 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x, const_iterator i); -void splice_after(const_iterator position, forward_list&& x, const_iterator i); +constexpr void splice_after(const_iterator position, forward_list& x, const_iterator i); +constexpr void splice_after(const_iterator position, forward_list&& x, const_iterator i); \end{itemdecl} \begin{itemdescr} @@ -7588,10 +7601,10 @@ \indexlibrarymember{splice_after}{forward_list}% \begin{itemdecl} -void splice_after(const_iterator position, forward_list& x, - const_iterator first, const_iterator last); -void splice_after(const_iterator position, forward_list&& x, - const_iterator first, const_iterator last); +constexpr void splice_after(const_iterator position, forward_list& x, + const_iterator first, const_iterator last); +constexpr void splice_after(const_iterator position, forward_list&& x, + const_iterator first, const_iterator last); \end{itemdecl} \begin{itemdescr} @@ -7619,8 +7632,8 @@ \indexlibrarymember{remove}{forward_list}% \indexlibrarymember{remove_if}{forward_list}% \begin{itemdecl} -size_type remove(const T& value); -template<class Predicate> size_type remove_if(Predicate pred); +constexpr size_type remove(const T& value); +template<class Predicate> constexpr size_type remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -7652,8 +7665,8 @@ \indexlibrarymember{unique}{forward_list}% \begin{itemdecl} -size_type unique(); -template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred); +constexpr size_type unique(); +template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred); \end{itemdecl} \begin{itemdescr} @@ -7691,10 +7704,10 @@ \indexlibrarymember{merge}{forward_list}% \begin{itemdecl} -void merge(forward_list& x); -void merge(forward_list&& x); -template<class Compare> void merge(forward_list& x, Compare comp); -template<class Compare> void merge(forward_list&& x, Compare comp); +constexpr void merge(forward_list& x); +constexpr void merge(forward_list&& x); +template<class Compare> constexpr void merge(forward_list& x, Compare comp); +template<class Compare> constexpr void merge(forward_list&& x, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -7735,8 +7748,8 @@ \indexlibrarymember{sort}{forward_list}% \begin{itemdecl} -void sort(); -template<class Compare> void sort(Compare comp); +constexpr void sort(); +template<class Compare> constexpr void sort(Compare comp); \end{itemdecl} \begin{itemdescr} @@ -7757,7 +7770,7 @@ \indexlibrarymember{reverse}{forward_list}% \begin{itemdecl} -void reverse() noexcept; +constexpr void reverse() noexcept; \end{itemdecl} \begin{itemdescr} @@ -7776,7 +7789,7 @@ \indexlibrarymember{erase}{forward_list}% \begin{itemdecl} template<class T, class Allocator, class U = T> - typename forward_list<T, Allocator>::size_type + constexpr typename forward_list<T, Allocator>::size_type erase(forward_list<T, Allocator>& c, const U& value); \end{itemdecl} @@ -7789,7 +7802,7 @@ \indexlibrarymember{erase_if}{forward_list}% \begin{itemdecl} template<class T, class Allocator, class Predicate> - typename forward_list<T, Allocator>::size_type + constexpr typename forward_list<T, Allocator>::size_type erase_if(forward_list<T, Allocator>& c, Predicate pred); \end{itemdecl} @@ -7811,21 +7824,21 @@ template<class T, class Allocator = allocator<T>> class list; template<class T, class Allocator> - bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y); + constexpr bool operator==(const list<T, Allocator>& x, const list<T, Allocator>& y); template<class T, class Allocator> - @\placeholder{synth-three-way-result}@<T> operator<=>(const list<T, Allocator>& x, + constexpr @\placeholder{synth-three-way-result}@<T> operator<=>(const list<T, Allocator>& x, @\itcorr@ const list<T, Allocator>& y); template<class T, class Allocator> - void swap(list<T, Allocator>& x, list<T, Allocator>& y) + constexpr void swap(list<T, Allocator>& x, list<T, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{list.erasure}, erasure template<class T, class Allocator, class U = T> - typename list<T, Allocator>::size_type + constexpr typename list<T, Allocator>::size_type erase(list<T, Allocator>& c, const U& value); template<class T, class Allocator, class Predicate> - typename list<T, Allocator>::size_type + constexpr typename list<T, Allocator>::size_type erase_if(list<T, Allocator>& c, Predicate pred); namespace pmr { @@ -7873,6 +7886,10 @@ that are not described in one of these tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\ref{iterator.requirements.general}. + \begin{codeblock} namespace std { template<class T, class Allocator = allocator<T>> @@ -7893,113 +7910,116 @@ using const_reverse_iterator = std::reverse_iterator<const_iterator>; // \ref{list.cons}, construct/copy/destroy - list() : list(Allocator()) { } - explicit list(const Allocator&); - explicit list(size_type n, const Allocator& = Allocator()); - list(size_type n, const T& value, const Allocator& = Allocator()); + constexpr list() : list(Allocator()) { } + constexpr explicit list(const Allocator&); + constexpr explicit list(size_type n, const Allocator& = Allocator()); + constexpr list(size_type n, const T& value, const Allocator& = Allocator()); template<class InputIterator> - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<T> R> - list(from_range_t, R&& rg, const Allocator& = Allocator()); - list(const list& x); - list(list&& x); - list(const list&, const type_identity_t<Allocator>&); - list(list&&, const type_identity_t<Allocator>&); - list(initializer_list<T>, const Allocator& = Allocator()); - ~list(); - list& operator=(const list& x); - list& operator=(list&& x) + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr list(const list& x); + constexpr list(list&& x); + constexpr list(const list&, const type_identity_t<Allocator>&); + constexpr list(list&&, const type_identity_t<Allocator>&); + constexpr list(initializer_list<T>, const Allocator& = Allocator()); + constexpr ~list(); + constexpr list& operator=(const list& x); + constexpr list& operator=(list&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value); - list& operator=(initializer_list<T>); + constexpr list& operator=(initializer_list<T>); template<class InputIterator> - void assign(InputIterator first, InputIterator last); + constexpr void assign(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - void assign_range(R&& rg); - void assign(size_type n, const T& t); - void assign(initializer_list<T>); - allocator_type get_allocator() const noexcept; + constexpr void assign_range(R&& rg); + constexpr void assign(size_type n, const T& t); + constexpr void assign(initializer_list<T>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; - - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + constexpr 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; // \ref{list.capacity}, capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; - void resize(size_type sz); - void resize(size_type sz, const T& c); + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; + constexpr void resize(size_type sz); + constexpr void resize(size_type sz, const T& c); // element access - reference front(); - const_reference front() const; - reference back(); - const_reference back() const; + constexpr reference front(); + constexpr const_reference front() const; + constexpr reference back(); + constexpr const_reference back() const; // \ref{list.modifiers}, modifiers - template<class... Args> reference emplace_front(Args&&... args); - template<class... Args> reference emplace_back(Args&&... args); - void push_front(const T& x); - void push_front(T&& x); + template<class... Args> constexpr reference emplace_front(Args&&... args); + template<class... Args> constexpr reference emplace_back(Args&&... args); + constexpr void push_front(const T& x); + constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); - void pop_front(); - void push_back(const T& x); - void push_back(T&& x); + constexpr void prepend_range(R&& rg); + constexpr void pop_front(); + constexpr void push_back(const T& x); + constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void append_range(R&& rg); - void pop_back(); + constexpr void append_range(R&& rg); + constexpr void pop_back(); - template<class... Args> iterator emplace(const_iterator position, Args&&... args); - iterator insert(const_iterator position, const T& x); - iterator insert(const_iterator position, T&& x); - iterator insert(const_iterator position, size_type n, const T& x); + template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); + constexpr iterator insert(const_iterator position, const T& x); + constexpr iterator insert(const_iterator position, T&& x); + constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> - iterator insert(const_iterator position, InputIterator first, InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range(const_iterator position, R&& rg); - iterator insert(const_iterator position, initializer_list<T> il); + constexpr iterator insert_range(const_iterator position, R&& rg); + constexpr iterator insert(const_iterator position, initializer_list<T> il); - iterator erase(const_iterator position); - iterator erase(const_iterator position, const_iterator last); - void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value); - void clear() noexcept; + constexpr iterator erase(const_iterator position); + constexpr iterator erase(const_iterator position, const_iterator last); + constexpr void swap(list&) noexcept(allocator_traits<Allocator>::is_always_equal::value); + constexpr void clear() noexcept; // \ref{list.ops}, list operations - void splice(const_iterator position, list& x); - void splice(const_iterator position, list&& x); - void splice(const_iterator position, list& x, const_iterator i); - void splice(const_iterator position, list&& x, const_iterator i); - void splice(const_iterator position, list& x, const_iterator first, const_iterator last); - void splice(const_iterator position, list&& x, const_iterator first, const_iterator last); - - size_type remove(const T& value); - template<class Predicate> size_type remove_if(Predicate pred); - - size_type unique(); + constexpr void splice(const_iterator position, list& x); + constexpr void splice(const_iterator position, list&& x); + constexpr void splice(const_iterator position, list& x, const_iterator i); + constexpr void splice(const_iterator position, list&& x, const_iterator i); + constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); + constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); + + constexpr size_type remove(const T& value); + template<class Predicate> constexpr size_type remove_if(Predicate pred); + + constexpr size_type unique(); template<class BinaryPredicate> - size_type unique(BinaryPredicate binary_pred); + constexpr size_type unique(BinaryPredicate binary_pred); - void merge(list& x); - void merge(list&& x); - template<class Compare> void merge(list& x, Compare comp); - template<class Compare> void merge(list&& x, Compare comp); + constexpr void merge(list& x); + constexpr void merge(list&& x); + template<class Compare> constexpr void merge(list& x, Compare comp); + template<class Compare> constexpr void merge(list&& x, Compare comp); - void sort(); - template<class Compare> void sort(Compare comp); + constexpr void sort(); + template<class Compare> constexpr void sort(Compare comp); - void reverse() noexcept; + constexpr void reverse() noexcept; }; template<class InputIterator, class Allocator = allocator<@\placeholder{iter-value-type}@<InputIterator>>> @@ -8023,7 +8043,7 @@ \indexlibraryctor{list}% \begin{itemdecl} -explicit list(const Allocator&); +constexpr explicit list(const Allocator&); \end{itemdecl} \begin{itemdescr} @@ -8038,7 +8058,7 @@ \indexlibraryctor{list}% \begin{itemdecl} -explicit list(size_type n, const Allocator& = Allocator()); +constexpr explicit list(size_type n, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8059,7 +8079,7 @@ \indexlibraryctor{list}% \begin{itemdecl} -list(size_type n, const T& value, const Allocator& = Allocator()); +constexpr list(size_type n, const T& value, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8086,7 +8106,7 @@ \indexlibraryctor{list}% \begin{itemdecl} template<class InputIterator> - list(InputIterator first, InputIterator last, const Allocator& = Allocator()); + constexpr list(InputIterator first, InputIterator last, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8106,7 +8126,7 @@ \indexlibraryctor{list}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - list(from_range_t, R&& rg, const Allocator& = Allocator()); + constexpr list(from_range_t, R&& rg, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -8123,7 +8143,7 @@ \indexlibrarymember{resize}{list}% \begin{itemdecl} -void resize(size_type sz); +constexpr void resize(size_type sz); \end{itemdecl} \begin{itemdescr} @@ -8147,7 +8167,7 @@ \indexlibrarymember{resize}{list}% \begin{itemdecl} -void resize(size_type sz, const T& c); +constexpr void resize(size_type sz, const T& c); \end{itemdecl} \begin{itemdescr} @@ -8175,27 +8195,27 @@ \indexlibrarymember{insert}{list}% \begin{itemdecl} -iterator insert(const_iterator position, const T& x); -iterator insert(const_iterator position, T&& x); -iterator insert(const_iterator position, size_type n, const T& x); +constexpr iterator insert(const_iterator position, const T& x); +constexpr iterator insert(const_iterator position, T&& x); +constexpr iterator insert(const_iterator position, size_type n, const T& x); template<class InputIterator> - iterator insert(const_iterator position, InputIterator first, - InputIterator last); + constexpr iterator insert(const_iterator position, + InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<T> R> - iterator insert_range(const_iterator position, R&& rg); -iterator insert(const_iterator position, initializer_list<T>); - -template<class... Args> reference emplace_front(Args&&... args); -template<class... Args> reference emplace_back(Args&&... args); -template<class... Args> iterator emplace(const_iterator position, Args&&... args); -void push_front(const T& x); -void push_front(T&& x); + constexpr iterator insert_range(const_iterator position, R&& rg); +constexpr iterator insert(const_iterator position, initializer_list<T>); + +template<class... Args> constexpr reference emplace_front(Args&&... args); +template<class... Args> constexpr reference emplace_back(Args&&... args); +template<class... Args> constexpr iterator emplace(const_iterator position, Args&&... args); +constexpr void push_front(const T& x); +constexpr void push_front(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void prepend_range(R&& rg); -void push_back(const T& x); -void push_back(T&& x); + constexpr void prepend_range(R&& rg); +constexpr void push_back(const T& x); +constexpr void push_back(T&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void append_range(R&& rg); + constexpr void append_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -8216,11 +8236,11 @@ \indexlibrarymember{erase}{list}% \begin{itemdecl} -iterator erase(const_iterator position); -iterator erase(const_iterator first, const_iterator last); -void pop_front(); -void pop_back(); -void clear() noexcept; +constexpr iterator erase(const_iterator position); +constexpr iterator erase(const_iterator first, const_iterator last); +constexpr void pop_front(); +constexpr void pop_back(); +constexpr void clear() noexcept; \end{itemdecl} \begin{itemdescr} @@ -8270,8 +8290,8 @@ \indexlibrarymember{splice}{list}% \begin{itemdecl} -void splice(const_iterator position, list& x); -void splice(const_iterator position, list&& x); +constexpr void splice(const_iterator position, list& x); +constexpr void splice(const_iterator position, list&& x); \end{itemdecl} \begin{itemdescr} @@ -8309,8 +8329,8 @@ \indexlibrarymember{splice}{list}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator i); -void splice(const_iterator position, list&& x, const_iterator i); +constexpr void splice(const_iterator position, list& x, const_iterator i); +constexpr void splice(const_iterator position, list&& x, const_iterator i); \end{itemdecl} \begin{itemdescr} @@ -8355,10 +8375,10 @@ \indexlibrarymember{splice}{list}% \begin{itemdecl} -void splice(const_iterator position, list& x, const_iterator first, - const_iterator last); -void splice(const_iterator position, list&& x, const_iterator first, - const_iterator last); +constexpr void splice(const_iterator position, list& x, + const_iterator first, const_iterator last); +constexpr void splice(const_iterator position, list&& x, + const_iterator first, const_iterator last); \end{itemdecl} \begin{itemdescr} @@ -8398,8 +8418,8 @@ \indexlibrarymember{remove}{list}% \begin{itemdecl} -size_type remove(const T& value); -template<class Predicate> size_type remove_if(Predicate pred); +constexpr size_type remove(const T& value); +template<class Predicate> constexpr size_type remove_if(Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -8433,8 +8453,8 @@ \indexlibrarymember{unique}{list}% \begin{itemdecl} -size_type unique(); -template<class BinaryPredicate> size_type unique(BinaryPredicate binary_pred); +constexpr size_type unique(); +template<class BinaryPredicate> constexpr size_type unique(BinaryPredicate binary_pred); \end{itemdecl} \begin{itemdescr} @@ -8471,10 +8491,10 @@ \indexlibrarymember{merge}{list}% \begin{itemdecl} -void merge(list& x); -void merge(list&& x); -template<class Compare> void merge(list& x, Compare comp); -template<class Compare> void merge(list&& x, Compare comp); +constexpr void merge(list& x); +constexpr void merge(list&& x); +template<class Compare> constexpr void merge(list& x, Compare comp); +template<class Compare> constexpr void merge(list&& x, Compare comp); \end{itemdecl} \begin{itemdescr} @@ -8515,7 +8535,7 @@ \indexlibrarymember{reverse}{list}% \begin{itemdecl} -void reverse() noexcept; +constexpr void reverse() noexcept; \end{itemdecl} \begin{itemdescr} @@ -8561,7 +8581,7 @@ \begin{itemdecl} template<class T, class Allocator, class U = T> typename list<T, Allocator>::size_type - erase(list<T, Allocator>& c, const U& value); + constexpr erase(list<T, Allocator>& c, const U& value); \end{itemdecl} \begin{itemdescr} @@ -8574,7 +8594,7 @@ \begin{itemdecl} template<class T, class Allocator, class Predicate> typename list<T, Allocator>::size_type - erase_if(list<T, Allocator>& c, Predicate pred); + constexpr erase_if(list<T, Allocator>& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -10202,21 +10222,21 @@ class map; template<class Key, class T, class Compare, class Allocator> - bool operator==(const map<Key, T, Compare, Allocator>& x, - const map<Key, T, Compare, Allocator>& y); + constexpr bool operator==(const map<Key, T, Compare, Allocator>& x, + const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> - @\placeholder{synth-three-way-result}@<pair<const Key, T>> + constexpr @\placeholder{synth-three-way-result}@<pair<const Key, T>> operator<=>(const map<Key, T, Compare, Allocator>& x, const map<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> - void swap(map<Key, T, Compare, Allocator>& x, - map<Key, T, Compare, Allocator>& y) + constexpr void swap(map<Key, T, Compare, Allocator>& x, + map<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{map.erasure}, erasure for \tcode{map} template<class Key, class T, class Compare, class Allocator, class Predicate> - typename map<Key, T, Compare, Allocator>::size_type + constexpr typename map<Key, T, Compare, Allocator>::size_type erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // \ref{multimap}, class template \tcode{multimap} @@ -10225,21 +10245,21 @@ class multimap; template<class Key, class T, class Compare, class Allocator> - bool operator==(const multimap<Key, T, Compare, Allocator>& x, - const multimap<Key, T, Compare, Allocator>& y); + constexpr bool operator==(const multimap<Key, T, Compare, Allocator>& x, + const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> - @\placeholder{synth-three-way-result}@<pair<const Key, T>> + constexpr @\placeholder{synth-three-way-result}@<pair<const Key, T>> operator<=>(const multimap<Key, T, Compare, Allocator>& x, const multimap<Key, T, Compare, Allocator>& y); template<class Key, class T, class Compare, class Allocator> - void swap(multimap<Key, T, Compare, Allocator>& x, + constexpr void swap(multimap<Key, T, Compare, Allocator>& x, multimap<Key, T, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{multimap.erasure}, erasure for \tcode{multimap} template<class Key, class T, class Compare, class Allocator, class Predicate> - typename multimap<Key, T, Compare, Allocator>::size_type + constexpr typename multimap<Key, T, Compare, Allocator>::size_type erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); namespace pmr { @@ -10298,6 +10318,10 @@ that are not described in one of those tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibrarymember{comp}{map::value_compare}% \indexlibrarymember{operator()}{map::value_compare}% \begin{codeblock} @@ -10328,174 +10352,175 @@ class value_compare { protected: Compare comp; - value_compare(Compare c) : comp(c) {} + constexpr value_compare(Compare c) : comp(c) {} public: - bool operator()(const value_type& x, const value_type& y) const { + constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // \ref{map.cons}, construct/copy/destroy - map() : map(Compare()) { } - explicit map(const Compare& comp, const Allocator& = Allocator()); + constexpr map() : map(Compare()) { } + constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<value_type> R> - map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); - map(const map& x); - map(map&& x); + constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); + constexpr map(const map& x); + constexpr map(map&& x); explicit map(const Allocator&); - map(const map&, const type_identity_t<Allocator>&); - map(map&&, const type_identity_t<Allocator>&); - map(initializer_list<value_type>, - const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr map(const map&, const type_identity_t<Allocator>&); + constexpr map(map&&, const type_identity_t<Allocator>&); + constexpr map(initializer_list<value_type>, const Compare& = Compare(), + const Allocator& = Allocator()); template<class InputIterator> - map(InputIterator first, InputIterator last, const Allocator& a) + constexpr map(InputIterator first, InputIterator last, const Allocator& a) : map(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - map(from_range_t, R&& rg, const Allocator& a)) + constexpr map(from_range_t, R&& rg, const Allocator& a)) : map(from_range, std::forward<R>(rg), Compare(), a) { } - map(initializer_list<value_type> il, const Allocator& a) + constexpr map(initializer_list<value_type> il, const Allocator& a) : map(il, Compare(), a) { } - ~map(); - map& operator=(const map& x); - map& operator=(map&& x) + constexpr ~map(); + constexpr map& operator=(const map& x); + constexpr map& operator=(map&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); - map& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + constexpr map& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{map.access}, element access - mapped_type& operator[](const key_type& x); - mapped_type& operator[](key_type&& x); - template<class K> mapped_type& operator[](K&& x); - mapped_type& at(const key_type& x); - const mapped_type& at(const key_type& x) const; - template<class K> mapped_type& at(const K& x); - template<class K> const mapped_type& at(const K& x) const; + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template<class K> constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template<class K> constexpr mapped_type& at(const K& x); + template<class K> constexpr const mapped_type& at(const K& x) const; // \ref{map.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& x); - pair<iterator, bool> insert(value_type&& x); - template<class P> pair<iterator, bool> insert(P&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair<iterator, bool> insert(const value_type& x); + constexpr pair<iterator, bool> insert(value_type&& x); + template<class P> constexpr pair<iterator, bool> insert(P&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); template<class P> - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(map&) + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(map&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); - void clear() noexcept; + constexpr void clear() noexcept; template<class C2> - void merge(map<Key, T, C2, Allocator>& source); + constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2> - void merge(map<Key, T, C2, Allocator>&& source); + constexpr void merge(map<Key, T, C2, Allocator>&& source); template<class C2> - void merge(multimap<Key, T, C2, Allocator>& source); + constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2> - void merge(multimap<Key, T, C2, Allocator>&& source); + constexpr void merge(multimap<Key, T, C2, Allocator>&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<@\placeholder{iter-key-type}@<InputIterator>>, @@ -10534,7 +10559,7 @@ \indexlibraryctor{map}% \begin{itemdecl} -explicit map(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit map(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10552,8 +10577,8 @@ \indexlibraryctor{map}% \begin{itemdecl} template<class InputIterator> - map(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10577,7 +10602,8 @@ \indexlibraryctor{map}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr map(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -10597,7 +10623,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -mapped_type& operator[](const key_type& x); +constexpr mapped_type& operator[](const key_type& x); \end{itemdecl} \begin{itemdescr} @@ -10608,7 +10634,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -mapped_type& operator[](key_type&& x); +constexpr mapped_type& operator[](key_type&& x); \end{itemdecl} \begin{itemdescr} @@ -10619,7 +10645,7 @@ \indexlibrary{\idxcode{operator[]}!\idxcode{map}}% \begin{itemdecl} -template<class K> mapped_type& operator[](K&& x); +template<class K> constexpr mapped_type& operator[](K&& x); \end{itemdecl} \begin{itemdescr} @@ -10635,8 +10661,8 @@ \indexlibrarymember{at}{map}% \begin{itemdecl} -mapped_type& at(const key_type& x); -const mapped_type& at(const key_type& x) const; +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; \end{itemdecl} \begin{itemdescr} @@ -10656,8 +10682,8 @@ \indexlibrarymember{at}{map}% \begin{itemdecl} -template<class K> mapped_type& at(const K& x); -template<class K> const mapped_type& at(const K& x) const; +template<class K> constexpr mapped_type& at(const K& x); +template<class K> constexpr const mapped_type& at(const K& x) const; \end{itemdecl} \begin{itemdescr} @@ -10689,9 +10715,9 @@ \indexlibrarymember{insert}{map}% \begin{itemdecl} template<class P> - pair<iterator, bool> insert(P&& x); + constexpr pair<iterator, bool> insert(P&& x); template<class P> - iterator insert(const_iterator position, P&& x); + constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -10709,9 +10735,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10747,9 +10773,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10785,9 +10811,9 @@ \indexlibrarymember{try_emplace}{map}% \begin{itemdecl} template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -10834,9 +10860,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10874,9 +10900,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10914,9 +10940,9 @@ \indexlibrarymember{insert_or_assign}{map}% \begin{itemdecl} template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -10965,7 +10991,7 @@ \begin{itemdecl} template<class Key, class T, class Compare, class Allocator, class Predicate> typename map<Key, T, Compare, Allocator>::size_type - erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); + constexpr erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -11035,6 +11061,10 @@ that are not described in one of those tables or for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibrarymember{comp}{multimap::value_compare}% \indexlibrarymember{operator()}{multimap::value_compare}% \begin{codeblock} @@ -11064,141 +11094,140 @@ class value_compare { protected: Compare comp; - value_compare(Compare c) : comp(c) { } + constexpr value_compare(Compare c) : comp(c) { } public: - bool operator()(const value_type& x, const value_type& y) const { + constexpr bool operator()(const value_type& x, const value_type& y) const { return comp(x.first, y.first); } }; // \ref{multimap.cons}, construct/copy/destroy - multimap() : multimap(Compare()) { } - explicit multimap(const Compare& comp, const Allocator& = Allocator()); + constexpr multimap() : multimap(Compare()) { } + constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<value_type> R> - multimap(from_range_t, R&& rg, - const Compare& comp = Compare(), const Allocator& = Allocator()); - multimap(const multimap& x); - multimap(multimap&& x); - explicit multimap(const Allocator&); - multimap(const multimap&, const type_identity_t<Allocator>&); - multimap(multimap&&, const type_identity_t<Allocator>&); - multimap(initializer_list<value_type>, - const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr multimap(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multimap(const multimap& x); + constexpr multimap(multimap&& x); + constexpr explicit multimap(const Allocator&); + constexpr multimap(const multimap&, const type_identity_t<Allocator>&); + constexpr multimap(multimap&&, const type_identity_t<Allocator>&); + constexpr multimap(initializer_list<value_type>, + const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator> - multimap(InputIterator first, InputIterator last, const Allocator& a) + constexpr multimap(InputIterator first, InputIterator last, const Allocator& a) : multimap(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - multimap(from_range_t, R&& rg, const Allocator& a)) + constexpr multimap(from_range_t, R&& rg, const Allocator& a)) : multimap(from_range, std::forward<R>(rg), Compare(), a) { } - multimap(initializer_list<value_type> il, const Allocator& a) + constexpr multimap(initializer_list<value_type> il, const Allocator& a) : multimap(il, Compare(), a) { } - ~multimap(); - multimap& operator=(const multimap& x); - multimap& operator=(multimap&& x) + constexpr ~multimap(); + constexpr multimap& operator=(const multimap& x); + constexpr multimap& operator=(multimap&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); - multimap& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + constexpr multimap& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{multimap.modifiers}, modifiers - template<class... Args> iterator emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x); - iterator insert(value_type&& x); - template<class P> iterator insert(P&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - template<class P> iterator insert(const_iterator position, P&& x); + template<class... Args> constexpr iterator emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& x); + constexpr iterator insert(value_type&& x); + template<class P> constexpr iterator insert(P&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); + template<class P> constexpr iterator insert(const_iterator position, P&& x); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); template<class K> node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multimap&) + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(multimap&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); - void clear() noexcept; + constexpr void clear() noexcept; template<class C2> - void merge(multimap<Key, T, C2, Allocator>& source); + constexpr void merge(multimap<Key, T, C2, Allocator>& source); template<class C2> - void merge(multimap<Key, T, C2, Allocator>&& source); + constexpr void merge(multimap<Key, T, C2, Allocator>&& source); template<class C2> - void merge(map<Key, T, C2, Allocator>& source); + constexpr void merge(map<Key, T, C2, Allocator>& source); template<class C2> - void merge(map<Key, T, C2, Allocator>&& source); + constexpr void merge(map<Key, T, C2, Allocator>&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, class Compare = less<@\placeholder{iter-key-type}@<InputIterator>>, @@ -11238,7 +11267,7 @@ \indexlibraryctor{multimap}% \begin{itemdecl} -explicit multimap(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit multimap(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11256,9 +11285,8 @@ \indexlibraryctor{multimap}% \begin{itemdecl} template<class InputIterator> - multimap(InputIterator first, InputIterator last, - const Compare& comp = Compare(), - const Allocator& = Allocator()); + constexpr multimap(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11283,7 +11311,8 @@ \indexlibraryctor{multimap}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - multimap(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multimap(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11303,8 +11332,8 @@ \indexlibrarymember{insert}{multimap}% \begin{itemdecl} -template<class P> iterator insert(P&& x); -template<class P> iterator insert(const_iterator position, P&& x); +template<class P> constexpr iterator insert(P&& x); +template<class P> constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -11325,7 +11354,7 @@ \begin{itemdecl} template<class Key, class T, class Compare, class Allocator, class Predicate> typename multimap<Key, T, Compare, Allocator>::size_type - erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); + constexpr erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); \end{itemdecl} \begin{itemdescr} @@ -11358,20 +11387,20 @@ class set; template<class Key, class Compare, class Allocator> - bool operator==(const set<Key, Compare, Allocator>& x, - const set<Key, Compare, Allocator>& y); + constexpr bool operator==(const set<Key, Compare, Allocator>& x, + const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> - @\placeholder{synth-three-way-result}@<Key> operator<=>(const set<Key, Compare, Allocator>& x, - @\itcorr@ const set<Key, Compare, Allocator>& y); + constexpr @\placeholder{synth-three-way-result}@<Key> operator<=>(const set<Key, Compare, Allocator>& x, + @\itcorr@ const set<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> - void swap(set<Key, Compare, Allocator>& x, - set<Key, Compare, Allocator>& y) + constexpr void swap(set<Key, Compare, Allocator>& x, + set<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{set.erasure}, erasure for \tcode{set} template<class Key, class Compare, class Allocator, class Predicate> - typename set<Key, Compare, Allocator>::size_type + constexpr typename set<Key, Compare, Allocator>::size_type erase_if(set<Key, Compare, Allocator>& c, Predicate pred); // \ref{multiset}, class template \tcode{multiset} @@ -11379,20 +11408,21 @@ class multiset; template<class Key, class Compare, class Allocator> - bool operator==(const multiset<Key, Compare, Allocator>& x, - const multiset<Key, Compare, Allocator>& y); + constexpr bool operator==(const multiset<Key, Compare, Allocator>& x, + const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> - @\placeholder{synth-three-way-result}@<Key> operator<=>(const multiset<Key, Compare, Allocator>& x, - @\itcorr@ const multiset<Key, Compare, Allocator>& y); + constexpr @\placeholder{synth-three-way-result}@<Key> + operator<=>(const multiset<Key, Compare, Allocator>& x, + const multiset<Key, Compare, Allocator>& y); template<class Key, class Compare, class Allocator> - void swap(multiset<Key, Compare, Allocator>& x, - multiset<Key, Compare, Allocator>& y) + constexpr void swap(multiset<Key, Compare, Allocator>& x, + multiset<Key, Compare, Allocator>& y) noexcept(noexcept(x.swap(y))); // \ref{multiset.erasure}, erasure for \tcode{multiset} template<class Key, class Compare, class Allocator, class Predicate> - typename multiset<Key, Compare, Allocator>::size_type + constexpr typename multiset<Key, Compare, Allocator>::size_type erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); namespace pmr { @@ -11450,6 +11480,10 @@ that are not described in one of these tables and for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template<class Key, class Compare = less<Key>, @@ -11476,130 +11510,132 @@ using insert_return_type = @\placeholdernc{insert-return-type}@<iterator, node_type>; // \ref{set.cons}, construct/copy/destroy - set() : set(Compare()) { } - explicit set(const Compare& comp, const Allocator& = Allocator()); + constexpr set() : set(Compare()) { } + constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<value_type> R> - set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); - set(const set& x); - set(set&& x); - explicit set(const Allocator&); - set(const set&, const type_identity_t<Allocator>&); - set(set&&, const type_identity_t<Allocator>&); - set(initializer_list<value_type>, const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr set(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(const set& x); + constexpr set(set&& x); + constexpr explicit set(const Allocator&); + constexpr set(const set&, const type_identity_t<Allocator>&); + constexpr set(set&&, const type_identity_t<Allocator>&); + constexpr set(initializer_list<value_type>, + const Compare& = Compare(), const Allocator& = Allocator()); template<class InputIterator> - set(InputIterator first, InputIterator last, const Allocator& a) + constexpr set(InputIterator first, InputIterator last, const Allocator& a) : set(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - set(from_range_t, R&& rg, const Allocator& a)) + constexpr set(from_range_t, R&& rg, const Allocator& a)) : set(from_range, std::forward<R>(rg), Compare(), a) { } - set(initializer_list<value_type> il, const Allocator& a) + constexpr set(initializer_list<value_type> il, const Allocator& a) : set(il, Compare(), a) { } - ~set(); - set& operator=(const set& x); - set& operator=(set&& x) + constexpr ~set(); + constexpr set& operator=(const set& x); + constexpr set& operator=(set&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); - set& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + constexpr set& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{set.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator,bool> insert(const value_type& x); - pair<iterator,bool> insert(value_type&& x); - template<class K> pair<iterator, bool> insert(K&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); - template<class K> iterator insert(const_iterator position, K&& x); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair<iterator,bool> insert(const value_type& x); + constexpr pair<iterator,bool> insert(value_type&& x); + template<class K> constexpr pair<iterator, bool> insert(K&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); + template<class K> constexpr iterator insert(const_iterator position, K&& x); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@<iterator, const_iterator>); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(set&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(set&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); - void clear() noexcept; + constexpr void clear() noexcept; template<class C2> - void merge(set<Key, C2, Allocator>& source); + constexpr void merge(set<Key, C2, Allocator>& source); template<class C2> - void merge(set<Key, C2, Allocator>&& source); + constexpr void merge(set<Key, C2, Allocator>&& source); template<class C2> - void merge(multiset<Key, C2, Allocator>& source); + constexpr void merge(multiset<Key, C2, Allocator>& source); template<class C2> - void merge(multiset<Key, C2, Allocator>&& source); + constexpr void merge(multiset<Key, C2, Allocator>&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, @@ -11638,7 +11674,7 @@ \indexlibraryctor{set}% \begin{itemdecl} -explicit set(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit set(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11654,8 +11690,8 @@ \indexlibraryctor{set}% \begin{itemdecl} template<class InputIterator> - set(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11680,7 +11716,8 @@ \indexlibraryctor{set}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - set(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr set(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -11700,7 +11737,7 @@ \indexlibrarymember{erase_if}{set}% \begin{itemdecl} template<class Key, class Compare, class Allocator, class Predicate> - typename set<Key, Compare, Allocator>::size_type + constexpr typename set<Key, Compare, Allocator>::size_type erase_if(set<Key, Compare, Allocator>& c, Predicate pred); \end{itemdecl} @@ -11725,8 +11762,8 @@ \indexlibrarymember{insert}{set}% \begin{itemdecl} -template<class K> pair<iterator, bool> insert(K&& x); -template<class K> iterator insert(const_iterator hint, K&& x); +template<class K> constexpr pair<iterator, bool> insert(K&& x); +template<class K> constexpr iterator insert(const_iterator hint, K&& x); \end{itemdecl} \begin{itemdescr} @@ -11809,6 +11846,10 @@ that are not described in one of these tables and for operations where there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \begin{codeblock} namespace std { template<class Key, class Compare = less<Key>, @@ -11834,129 +11875,130 @@ using node_type = @\unspec@; // \ref{multiset.cons}, construct/copy/destroy - multiset() : multiset(Compare()) { } - explicit multiset(const Compare& comp, const Allocator& = Allocator()); + constexpr multiset() : multiset(Compare()) { } + constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); template<class InputIterator> - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); template<@\exposconcept{container-compatible-range}@<value_type> R> - multiset(from_range_t, R&& rg, - const Compare& comp = Compare(), const Allocator& = Allocator()); - multiset(const multiset& x); - multiset(multiset&& x); - explicit multiset(const Allocator&); - multiset(const multiset&, const type_identity_t<Allocator>&); - multiset(multiset&&, const type_identity_t<Allocator>&); - multiset(initializer_list<value_type>, const Compare& = Compare(), - const Allocator& = Allocator()); + constexpr multiset(from_range_t, R&& rg, + const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(const multiset& x); + constexpr multiset(multiset&& x); + constexpr explicit multiset(const Allocator&); + constexpr multiset(const multiset&, const type_identity_t<Allocator>&); + constexpr multiset(multiset&&, const type_identity_t<Allocator>&); + constexpr multiset(initializer_list<value_type>, const Compare& = Compare(), + const Allocator& = Allocator()); template<class InputIterator> - multiset(InputIterator first, InputIterator last, const Allocator& a) + constexpr multiset(InputIterator first, InputIterator last, const Allocator& a) : multiset(first, last, Compare(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - multiset(from_range_t, R&& rg, const Allocator& a)) + constexpr multiset(from_range_t, R&& rg, const Allocator& a)) : multiset(from_range, std::forward<R>(rg), Compare(), a) { } - multiset(initializer_list<value_type> il, const Allocator& a) + constexpr multiset(initializer_list<value_type> il, const Allocator& a) : multiset(il, Compare(), a) { } - ~multiset(); - multiset& operator=(const multiset& x); - multiset& operator=(multiset&& x) + constexpr ~multiset(); + constexpr multiset& operator=(const multiset& x); + constexpr multiset& operator=(multiset&& x) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Compare>); - multiset& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + constexpr multiset& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template<class... Args> iterator emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x); - iterator insert(value_type&& x); - iterator insert(const_iterator position, const value_type& x); - iterator insert(const_iterator position, value_type&& x); + template<class... Args> constexpr iterator emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator insert(const value_type& x); + constexpr iterator insert(value_type&& x); + constexpr iterator insert(const_iterator position, const value_type& x); + constexpr iterator insert(const_iterator position, value_type&& x); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@<iterator, const_iterator>); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(multiset&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& x); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(multiset&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_swappable_v<Compare>); - void clear() noexcept; + constexpr void clear() noexcept; template<class C2> - void merge(multiset<Key, C2, Allocator>& source); + constexpr void merge(multiset<Key, C2, Allocator>& source); template<class C2> - void merge(multiset<Key, C2, Allocator>&& source); + constexpr void merge(multiset<Key, C2, Allocator>&& source); template<class C2> - void merge(set<Key, C2, Allocator>& source); + constexpr void merge(set<Key, C2, Allocator>& source); template<class C2> - void merge(set<Key, C2, Allocator>&& source); + constexpr void merge(set<Key, C2, Allocator>&& source); // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; }; template<class InputIterator, @@ -11995,7 +12037,7 @@ \indexlibraryctor{multiset}% \begin{itemdecl} -explicit multiset(const Compare& comp, const Allocator& = Allocator()); +constexpr explicit multiset(const Compare& comp, const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -12011,8 +12053,8 @@ \indexlibraryctor{multiset}% \begin{itemdecl} template<class InputIterator> - multiset(InputIterator first, InputIterator last, - const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(InputIterator first, InputIterator last, + const Compare& comp = Compare(), const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -12037,7 +12079,8 @@ \indexlibraryctor{multiset}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - multiset(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); + constexpr multiset(from_range_t, R&& rg, const Compare& comp = Compare(), + const Allocator& = Allocator()); \end{itemdecl} \begin{itemdescr} @@ -12058,7 +12101,7 @@ \indexlibrarymember{erase_if}{multiset}% \begin{itemdecl} template<class Key, class Compare, class Allocator, class Predicate> - typename multiset<Key, Compare, Allocator>::size_type + constexpr typename multiset<Key, Compare, Allocator>::size_type erase_if(multiset<Key, Compare, Allocator>& c, Predicate pred); \end{itemdecl} @@ -12124,31 +12167,31 @@ class unordered_multimap; template<class Key, class T, class Hash, class Pred, class Alloc> - bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a, - const unordered_map<Key, T, Hash, Pred, Alloc>& b); + constexpr bool operator==(const unordered_map<Key, T, Hash, Pred, Alloc>& a, + const unordered_map<Key, T, Hash, Pred, Alloc>& b); template<class Key, class T, class Hash, class Pred, class Alloc> - bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a, - const unordered_multimap<Key, T, Hash, Pred, Alloc>& b); + constexpr bool operator==(const unordered_multimap<Key, T, Hash, Pred, Alloc>& a, + const unordered_multimap<Key, T, Hash, Pred, Alloc>& b); template<class Key, class T, class Hash, class Pred, class Alloc> - void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, - unordered_map<Key, T, Hash, Pred, Alloc>& y) + constexpr void swap(unordered_map<Key, T, Hash, Pred, Alloc>& x, + unordered_map<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); template<class Key, class T, class Hash, class Pred, class Alloc> - void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, - unordered_multimap<Key, T, Hash, Pred, Alloc>& y) + constexpr void swap(unordered_multimap<Key, T, Hash, Pred, Alloc>& x, + unordered_multimap<Key, T, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); // \ref{unord.map.erasure}, erasure for \tcode{unordered_map} template<class K, class T, class H, class P, class A, class Predicate> - typename unordered_map<K, T, H, P, A>::size_type + constexpr typename unordered_map<K, T, H, P, A>::size_type erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred); // \ref{unord.multimap.erasure}, erasure for \tcode{unordered_multimap} template<class K, class T, class H, class P, class A, class Predicate> - typename unordered_multimap<K, T, H, P, A>::size_type + constexpr typename unordered_multimap<K, T, H, P, A>::size_type erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred); namespace pmr { @@ -12203,6 +12246,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_map}% \begin{codeblock} namespace std { @@ -12235,193 +12282,193 @@ using insert_return_type = @\placeholdernc{insert-return-type}@<iterator, node_type>; // \ref{unord.map.cnstr}, construct/copy/destroy - unordered_map(); - explicit unordered_map(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(); + constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<class InputIterator> - unordered_map(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_map(from_range_t, R&& rg, size_type n = @\seebelow@, + constexpr unordered_map(from_range_t, R&& rg, size_type n = @\seebelow@, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); - unordered_map(const unordered_map&); - unordered_map(unordered_map&&); - explicit unordered_map(const Allocator&); - unordered_map(const unordered_map&, const type_identity_t<Allocator>&); - unordered_map(unordered_map&&, const type_identity_t<Allocator>&); - unordered_map(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_map(size_type n, const allocator_type& a) + constexpr unordered_map(const unordered_map&); + constexpr unordered_map(unordered_map&&); + constexpr explicit unordered_map(const Allocator&); + constexpr unordered_map(const unordered_map&, const type_identity_t<Allocator>&); + constexpr unordered_map(unordered_map&&, const type_identity_t<Allocator>&); + constexpr unordered_map(initializer_list<value_type> il, size_type n = @\seebelow@, + const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_map(size_type n, const allocator_type& a) : unordered_map(n, hasher(), key_equal(), a) { } - unordered_map(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_map(size_type n, const hasher& hf, const allocator_type& a) : unordered_map(n, hf, key_equal(), a) { } template<class InputIterator> - unordered_map(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_map(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_map(f, l, n, hasher(), key_equal(), a) { } template<class InputIterator> - unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, + constexpr unordered_map(InputIterator f, InputIterator l, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_map(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_map(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_map(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_map(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } - unordered_map(initializer_list<value_type> il, size_type n, const allocator_type& a) + constexpr unordered_map(initializer_list<value_type> il, size_type n, + const allocator_type& a) : unordered_map(il, n, hasher(), key_equal(), a) { } - unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, + constexpr unordered_map(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a) : unordered_map(il, n, hf, key_equal(), a) { } - ~unordered_map(); - unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&) + constexpr ~unordered_map(); + constexpr unordered_map& operator=(const unordered_map&); + constexpr unordered_map& operator=(unordered_map&&) noexcept(allocator_traits<Allocator>::is_always_equal::value && is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>); - unordered_map& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + constexpr unordered_map& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.map.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& obj); - pair<iterator, bool> insert(value_type&& obj); - template<class P> pair<iterator, bool> insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template<class P> iterator insert(const_iterator hint, P&& obj); - template<class InputIterator> void insert(InputIterator first, InputIterator last); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair<iterator, bool> insert(const value_type& obj); + constexpr pair<iterator, bool> insert(value_type&& obj); + template<class P> constexpr pair<iterator, bool> insert(P&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template<class P> constexpr iterator insert(const_iterator hint, P&& obj); + template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_map&) + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_map&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_swappable_v<Hash> && - is_nothrow_swappable_v<Pred>); - void clear() noexcept; + is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>); + constexpr void clear() noexcept; template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>& source); + constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); + constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); + constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); + constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template<class K> - iterator find(const K& k); + constexpr iterator find(const K& k); template<class K> - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template<class K> - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template<class K> - bool contains(const K& k) const; - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair<iterator, iterator> equal_range(const key_type& k); + constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const; template<class K> - pair<iterator, iterator> equal_range(const K& k); + constexpr pair<iterator, iterator> equal_range(const K& k); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const; // \ref{unord.map.elem}, element access - mapped_type& operator[](const key_type& k); - mapped_type& operator[](key_type&& k); - template<class K> mapped_type& operator[](K&& k); - mapped_type& at(const key_type& k); - const mapped_type& at(const key_type& k) const; - template<class K> mapped_type& at(const K& k); - template<class K> const mapped_type& at(const K& k) const; + constexpr mapped_type& operator[](const key_type& k); + constexpr mapped_type& operator[](key_type&& k); + template<class K> constexpr mapped_type& operator[](K&& k); + constexpr mapped_type& at(const key_type& k); + constexpr const mapped_type& at(const key_type& k) const; + template<class K> constexpr mapped_type& at(const K& k); + template<class K> constexpr const mapped_type& at(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template<class K> size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template<class K> constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template<class InputIterator, @@ -12503,11 +12550,10 @@ \indexlibraryctor{unordered_map}% \begin{itemdecl} -unordered_map() : unordered_map(size_type(@\seebelow@)) { } -explicit unordered_map(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +constexpr unordered_map() : unordered_map(size_type(@\seebelow@)) { } +constexpr explicit unordered_map(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -12528,22 +12574,19 @@ \indexlibraryctor{unordered_map}% \begin{itemdecl} template<class InputIterator> - unordered_map(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_map(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_map(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_map(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_map(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -12568,7 +12611,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& operator[](const key_type& k); +constexpr mapped_type& operator[](const key_type& k); \end{itemdecl} \begin{itemdescr} @@ -12580,7 +12623,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& operator[](key_type&& k); +constexpr mapped_type& operator[](key_type&& k); \end{itemdecl} \begin{itemdescr} @@ -12592,7 +12635,7 @@ \indexlibrarymember{unordered_map}{operator[]}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -template<class K> mapped_type& operator[](K&& k); +template<class K> constexpr mapped_type& operator[](K&& k); \end{itemdecl} \begin{itemdescr} @@ -12609,8 +12652,8 @@ \indexlibrarymember{unordered_map}{at}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -mapped_type& at(const key_type& k); -const mapped_type& at(const key_type& k) const; +constexpr mapped_type& at(const key_type& k); +constexpr const mapped_type& at(const key_type& k) const; \end{itemdecl} \begin{itemdescr} @@ -12626,8 +12669,8 @@ \indexlibrarymember{unordered_map}{at}% \indextext{\idxcode{unordered_map}!element access}% \begin{itemdecl} -template<class K> mapped_type& at(const K& k); -template<class K> const mapped_type& at(const K& k) const; +template<class K> constexpr mapped_type& at(const K& k); +template<class K> constexpr const mapped_type& at(const K& k) const; \end{itemdecl} \begin{itemdescr} @@ -12655,7 +12698,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} template<class P> - pair<iterator, bool> insert(P&& obj); + constexpr pair<iterator, bool> insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12672,7 +12715,7 @@ \indexlibrarymember{unordered_map}{insert}% \begin{itemdecl} template<class P> - iterator insert(const_iterator hint, P&& obj); + constexpr iterator insert(const_iterator hint, P&& obj); \end{itemdecl} \begin{itemdescr} @@ -12689,9 +12732,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12727,9 +12770,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12765,9 +12808,9 @@ \indexlibrarymember{try_emplace}{unordered_map}% \begin{itemdecl} template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -12814,9 +12857,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12854,9 +12897,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12894,9 +12937,9 @@ \indexlibrarymember{insert_or_assign}{unordered_map}% \begin{itemdecl} template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -12945,7 +12988,7 @@ \indexlibrarymember{erase_if}{unordered_map}% \begin{itemdecl} template<class K, class T, class H, class P, class A, class Predicate> - typename unordered_map<K, T, H, P, A>::size_type + constexpr typename unordered_map<K, T, H, P, A>::size_type erase_if(unordered_map<K, T, H, P, A>& c, Predicate pred); \end{itemdecl} @@ -12998,6 +13041,10 @@ that are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multimap}% \begin{codeblock} namespace std { @@ -13029,162 +13076,159 @@ using node_type = @\unspec@; // \ref{unord.multimap.cnstr}, construct/copy/destroy - unordered_multimap(); - explicit unordered_multimap(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(); + constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multimap(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(const unordered_multimap&); - unordered_multimap(unordered_multimap&&); - explicit unordered_multimap(const Allocator&); - unordered_multimap(const unordered_multimap&, const type_identity_t<Allocator>&); - unordered_multimap(unordered_multimap&&, const type_identity_t<Allocator>&); - unordered_multimap(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multimap(size_type n, const allocator_type& a) + constexpr unordered_multimap(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multimap(const unordered_multimap&); + constexpr unordered_multimap(unordered_multimap&&); + constexpr explicit unordered_multimap(const Allocator&); + constexpr unordered_multimap(const unordered_multimap&, const type_identity_t<Allocator>&); + constexpr unordered_multimap(unordered_multimap&&, const type_identity_t<Allocator>&); + constexpr unordered_multimap(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multimap(size_type n, const allocator_type& a) : unordered_multimap(n, hasher(), key_equal(), a) { } - unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_multimap(size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(n, hf, key_equal(), a) { } template<class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_multimap(f, l, n, hasher(), key_equal(), a) { } template<class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multimap(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const allocator_type& a) : unordered_multimap(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multimap(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, + constexpr unordered_multimap(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } - unordered_multimap(initializer_list<value_type> il, size_type n, const allocator_type& a) + constexpr unordered_multimap(initializer_list<value_type> il, size_type n, + const allocator_type& a) : unordered_multimap(il, n, hasher(), key_equal(), a) { } - unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, + constexpr unordered_multimap(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multimap(il, n, hf, key_equal(), a) { } - ~unordered_multimap(); - unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&) + constexpr ~unordered_multimap(); + constexpr unordered_multimap& operator=(const unordered_multimap&); + constexpr unordered_multimap& operator=(unordered_multimap&&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_move_assignable_v<Hash> && - is_nothrow_move_assignable_v<Pred>); - unordered_multimap& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>); + constexpr unordered_multimap& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.multimap.modifiers}, modifiers - template<class... Args> iterator emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - iterator insert(value_type&& obj); - template<class P> iterator insert(P&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template<class P> iterator insert(const_iterator hint, P&& obj); - template<class InputIterator> void insert(InputIterator first, InputIterator last); + template<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& obj); + constexpr iterator insert(value_type&& obj); + template<class P> constexpr iterator insert(P&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template<class P> constexpr iterator insert(const_iterator hint, P&& obj); + template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); - - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); - - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_multimap&) + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); + + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); + + constexpr iterator erase(iterator position); + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_multimap&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_swappable_v<Hash> && - is_nothrow_swappable_v<Pred>); - void clear() noexcept; + is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>); + constexpr void clear() noexcept; template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); + constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); + constexpr void merge(unordered_multimap<Key, T, H2, P2, Allocator>&& source); template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>& source); + constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); + constexpr void merge(unordered_map<Key, T, H2, P2, Allocator>&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // map operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template<class K> - iterator find(const K& k); + constexpr iterator find(const K& k); template<class K> - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template<class K> - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template<class K> - bool contains(const K& k) const; - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair<iterator, iterator> equal_range(const key_type& k); + constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const; template<class K> - pair<iterator, iterator> equal_range(const K& k); + constexpr pair<iterator, iterator> equal_range(const K& k); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template<class K> size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template<class K> constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template<class InputIterator, @@ -13269,11 +13313,10 @@ \indexlibraryctor{unordered_multimap}% \begin{itemdecl} -unordered_multimap() : unordered_multimap(size_type(@\seebelow@)) { } -explicit unordered_multimap(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +constexpr unordered_multimap() : unordered_multimap(size_type(@\seebelow@)) { } +constexpr explicit unordered_multimap(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13294,22 +13337,19 @@ \indexlibraryctor{unordered_multimap}% \begin{itemdecl} template<class InputIterator> - unordered_multimap(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multimap(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_multimap(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multimap(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_multimap(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13334,7 +13374,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} template<class P> - iterator insert(P&& obj); + constexpr iterator insert(P&& obj); \end{itemdecl} \begin{itemdescr} @@ -13350,7 +13390,7 @@ \indexlibrarymember{unordered_multimap}{insert}% \begin{itemdecl} template<class P> - iterator insert(const_iterator hint, P&& obj); + constexpr iterator insert(const_iterator hint, P&& obj); \end{itemdecl} \begin{itemdescr} @@ -13369,7 +13409,7 @@ \indexlibrarymember{erase_if}{unordered_multimap}% \begin{itemdecl} template<class K, class T, class H, class P, class A, class Predicate> - typename unordered_multimap<K, T, H, P, A>::size_type + constexpr typename unordered_multimap<K, T, H, P, A>::size_type erase_if(unordered_multimap<K, T, H, P, A>& c, Predicate pred); \end{itemdecl} @@ -13415,31 +13455,31 @@ class unordered_multiset; template<class Key, class Hash, class Pred, class Alloc> - bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a, - const unordered_set<Key, Hash, Pred, Alloc>& b); + constexpr bool operator==(const unordered_set<Key, Hash, Pred, Alloc>& a, + const unordered_set<Key, Hash, Pred, Alloc>& b); template<class Key, class Hash, class Pred, class Alloc> - bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a, - const unordered_multiset<Key, Hash, Pred, Alloc>& b); + constexpr bool operator==(const unordered_multiset<Key, Hash, Pred, Alloc>& a, + const unordered_multiset<Key, Hash, Pred, Alloc>& b); template<class Key, class Hash, class Pred, class Alloc> - void swap(unordered_set<Key, Hash, Pred, Alloc>& x, - unordered_set<Key, Hash, Pred, Alloc>& y) + constexpr void swap(unordered_set<Key, Hash, Pred, Alloc>& x, + unordered_set<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); template<class Key, class Hash, class Pred, class Alloc> - void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x, - unordered_multiset<Key, Hash, Pred, Alloc>& y) + constexpr void swap(unordered_multiset<Key, Hash, Pred, Alloc>& x, + unordered_multiset<Key, Hash, Pred, Alloc>& y) noexcept(noexcept(x.swap(y))); // \ref{unord.set.erasure}, erasure for \tcode{unordered_set} template<class K, class H, class P, class A, class Predicate> - typename unordered_set<K, H, P, A>::size_type + constexpr typename unordered_set<K, H, P, A>::size_type erase_if(unordered_set<K, H, P, A>& c, Predicate pred); // \ref{unord.multiset.erasure}, erasure for \tcode{unordered_multiset} template<class K, class H, class P, class A, class Predicate> - typename unordered_multiset<K, H, P, A>::size_type + constexpr typename unordered_multiset<K, H, P, A>::size_type erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred); namespace pmr { @@ -13491,6 +13531,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_set}% \begin{codeblock} namespace std { @@ -13521,161 +13565,159 @@ using insert_return_type = @\placeholdernc{insert-return-type}@<iterator, node_type>; // \ref{unord.set.cnstr}, construct/copy/destroy - unordered_set(); - explicit unordered_set(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(); + constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<class InputIterator> - unordered_set(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_set(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_set(const unordered_set&); - unordered_set(unordered_set&&); - explicit unordered_set(const Allocator&); - unordered_set(const unordered_set&, const type_identity_t<Allocator>&); - unordered_set(unordered_set&&, const type_identity_t<Allocator>&); - unordered_set(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_set(size_type n, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_set(const unordered_set&); + constexpr unordered_set(unordered_set&&); + constexpr explicit unordered_set(const Allocator&); + constexpr unordered_set(const unordered_set&, const type_identity_t<Allocator>&); + constexpr unordered_set(unordered_set&&, const type_identity_t<Allocator>&); + constexpr unordered_set(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_set(size_type n, const allocator_type& a) : unordered_set(n, hasher(), key_equal(), a) { } - unordered_set(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_set(size_type n, const hasher& hf, const allocator_type& a) : unordered_set(n, hf, key_equal(), a) { } template<class InputIterator> - unordered_set(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_set(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_set(f, l, n, hasher(), key_equal(), a) { } template<class InputIterator> - unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_set(InputIterator f, InputIterator l, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(f, l, n, hf, key_equal(), a) { } - unordered_set(initializer_list<value_type> il, size_type n, const allocator_type& a) + constexpr unordered_set(initializer_list<value_type> il, size_type n, + const allocator_type& a) : unordered_set(il, n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_set(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_set(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } - unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_set(initializer_list<value_type> il, size_type n, const hasher& hf, + const allocator_type& a) : unordered_set(il, n, hf, key_equal(), a) { } - ~unordered_set(); - unordered_set& operator=(const unordered_set&); - unordered_set& operator=(unordered_set&&) + constexpr ~unordered_set(); + constexpr unordered_set& operator=(const unordered_set&); + constexpr unordered_set& operator=(unordered_set&&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_move_assignable_v<Hash> && - is_nothrow_move_assignable_v<Pred>); - unordered_set& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>); + constexpr unordered_set& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{unord.set.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& obj); - pair<iterator, bool> insert(value_type&& obj); - template<class K> pair<iterator, bool> insert(K&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template<class K> iterator insert(const_iterator hint, K&& obj); - template<class InputIterator> void insert(InputIterator first, InputIterator last); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); + template<class... Args> + constexpr iterator emplace_hint(const_iterator position, Args&&... args); + constexpr pair<iterator, bool> insert(const value_type& obj); + constexpr pair<iterator, bool> insert(value_type&& obj); + template<class K> constexpr pair<iterator, bool> insert(K&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template<class K> constexpr iterator insert(const_iterator hint, K&& obj); + template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - insert_return_type insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr insert_return_type insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@<iterator, const_iterator>); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_set&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_set&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_swappable_v<Hash> && - is_nothrow_swappable_v<Pred>); - void clear() noexcept; + is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>); + constexpr void clear() noexcept; template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>& source); + constexpr void merge(unordered_set<Key, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>&& source); + constexpr void merge(unordered_set<Key, H2, P2, Allocator>&& source); template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>& source); + constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); + constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template<class K> - iterator find(const K& k); + constexpr iterator find(const K& k); template<class K> - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template<class K> - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template<class K> - bool contains(const K& k) const; - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair<iterator, iterator> equal_range(const key_type& k); + constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const; template<class K> - pair<iterator, iterator> equal_range(const K& k); + constexpr pair<iterator, iterator> equal_range(const K& k); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template<class K> size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template<class K> constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template<class InputIterator, @@ -13749,11 +13791,10 @@ \indexlibraryctor{unordered_set}% \begin{itemdecl} -unordered_set() : unordered_set(size_type(@\seebelow@)) { } -explicit unordered_set(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +constexpr unordered_set() : unordered_set(size_type(@\seebelow@)) { } +constexpr explicit unordered_set(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13774,22 +13815,19 @@ \indexlibraryctor{unordered_set}% \begin{itemdecl} template<class InputIterator> - unordered_set(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_set(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_set(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_set(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -13814,7 +13852,7 @@ \indexlibrarymember{erase_if}{unordered_set}% \begin{itemdecl} template<class K, class H, class P, class A, class Predicate> - typename unordered_set<K, H, P, A>::size_type + constexpr typename unordered_set<K, H, P, A>::size_type erase_if(unordered_set<K, H, P, A>& c, Predicate pred); \end{itemdecl} @@ -13839,8 +13877,8 @@ \indexlibrarymember{insert}{unordered_set}% \begin{itemdecl} -template<class K> pair<iterator, bool> insert(K&& obj); -template<class K> iterator insert(const_iterator hint, K&& obj); +template<class K> constexpr pair<iterator, bool> insert(K&& obj); +template<class K> constexpr iterator insert(const_iterator hint, K&& obj); \end{itemdecl} \begin{itemdescr} @@ -13913,6 +13951,10 @@ are not described in one of the requirement tables, or for which there is additional semantic information. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \indexlibraryglobal{unordered_multiset}% \begin{codeblock} namespace std { @@ -13942,161 +13984,158 @@ using node_type = @\unspec@; // \ref{unord.multiset.cnstr}, construct/copy/destroy - unordered_multiset(); - explicit unordered_multiset(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(); + constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multiset(const unordered_multiset&); - unordered_multiset(unordered_multiset&&); - explicit unordered_multiset(const Allocator&); - unordered_multiset(const unordered_multiset&, const type_identity_t<Allocator>&); - unordered_multiset(unordered_multiset&&, const type_identity_t<Allocator>&); - unordered_multiset(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); - unordered_multiset(size_type n, const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multiset(const unordered_multiset&); + constexpr unordered_multiset(unordered_multiset&&); + constexpr explicit unordered_multiset(const Allocator&); + constexpr unordered_multiset(const unordered_multiset&, const type_identity_t<Allocator>&); + constexpr unordered_multiset(unordered_multiset&&, const type_identity_t<Allocator>&); + constexpr unordered_multiset(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); + constexpr unordered_multiset(size_type n, const allocator_type& a) : unordered_multiset(n, hasher(), key_equal(), a) { } - unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) + constexpr unordered_multiset(size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(n, hf, key_equal(), a) { } template<class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, size_type n, const allocator_type& a) + constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n, + const allocator_type& a) : unordered_multiset(f, l, n, hasher(), key_equal(), a) { } template<class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multiset(InputIterator f, InputIterator l, size_type n, + const hasher& hf, const allocator_type& a) : unordered_multiset(f, l, n, hf, key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const allocator_type& a) : unordered_multiset(from_range, std::forward<R>(rg), n, hasher(), key_equal(), a) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, - const allocator_type& a) + constexpr unordered_multiset(from_range_t, R&& rg, size_type n, const hasher& hf, + const allocator_type& a) : unordered_multiset(from_range, std::forward<R>(rg), n, hf, key_equal(), a) { } - unordered_multiset(initializer_list<value_type> il, size_type n, const allocator_type& a) + constexpr unordered_multiset(initializer_list<value_type> il, size_type n, + const allocator_type& a) : unordered_multiset(il, n, hasher(), key_equal(), a) { } - unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf, + constexpr unordered_multiset(initializer_list<value_type> il, size_type n, const hasher& hf, const allocator_type& a) : unordered_multiset(il, n, hf, key_equal(), a) { } - ~unordered_multiset(); - unordered_multiset& operator=(const unordered_multiset&); - unordered_multiset& operator=(unordered_multiset&&) + constexpr ~unordered_multiset(); + constexpr unordered_multiset& operator=(const unordered_multiset&); + constexpr unordered_multiset& operator=(unordered_multiset&&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_move_assignable_v<Hash> && - is_nothrow_move_assignable_v<Pred>); - unordered_multiset& operator=(initializer_list<value_type>); - allocator_type get_allocator() const noexcept; + is_nothrow_move_assignable_v<Hash> && is_nothrow_move_assignable_v<Pred>); + constexpr unordered_multiset& operator=(initializer_list<value_type>); + constexpr allocator_type get_allocator() const noexcept; // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; + constexpr const_iterator cbegin() const noexcept; + constexpr const_iterator cend() const noexcept; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template<class... Args> iterator emplace(Args&&... args); - template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& obj); - iterator insert(value_type&& obj); - iterator insert(const_iterator hint, const value_type& obj); - iterator insert(const_iterator hint, value_type&& obj); - template<class InputIterator> void insert(InputIterator first, InputIterator last); + template<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& obj); + constexpr iterator insert(value_type&& obj); + constexpr iterator insert(const_iterator hint, const value_type& obj); + constexpr iterator insert(const_iterator hint, value_type&& obj); + template<class InputIterator> constexpr void insert(InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); - void insert(initializer_list<value_type>); + constexpr void insert_range(R&& rg); + constexpr void insert(initializer_list<value_type>); - node_type extract(const_iterator position); - node_type extract(const key_type& x); - template<class K> node_type extract(K&& x); - iterator insert(node_type&& nh); - iterator insert(const_iterator hint, node_type&& nh); + constexpr node_type extract(const_iterator position); + constexpr node_type extract(const key_type& x); + template<class K> constexpr node_type extract(K&& x); + constexpr iterator insert(node_type&& nh); + constexpr iterator insert(const_iterator hint, node_type&& nh); - iterator erase(iterator position) + constexpr iterator erase(iterator position) requires (!@\libconcept{same_as}@<iterator, const_iterator>); - iterator erase(const_iterator position); - size_type erase(const key_type& k); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); - void swap(unordered_multiset&) + constexpr iterator erase(const_iterator position); + constexpr size_type erase(const key_type& k); + template<class K> constexpr size_type erase(K&& x); + constexpr iterator erase(const_iterator first, const_iterator last); + constexpr void swap(unordered_multiset&) noexcept(allocator_traits<Allocator>::is_always_equal::value && - is_nothrow_swappable_v<Hash> && - is_nothrow_swappable_v<Pred>); - void clear() noexcept; + is_nothrow_swappable_v<Hash> && is_nothrow_swappable_v<Pred>); + constexpr void clear() noexcept; template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>& source); + constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); + constexpr void merge(unordered_multiset<Key, H2, P2, Allocator>&& source); template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>& source); + constexpr void merge(unordered_set<Key, H2, P2, Allocator>& source); template<class H2, class P2> - void merge(unordered_set<Key, H2, P2, Allocator>&& source); + constexpr void merge(unordered_set<Key, H2, P2, Allocator>&& source); // observers - hasher hash_function() const; - key_equal key_eq() const; + constexpr hasher hash_function() const; + constexpr key_equal key_eq() const; // set operations - iterator find(const key_type& k); - const_iterator find(const key_type& k) const; + constexpr iterator find(const key_type& k); + constexpr const_iterator find(const key_type& k) const; template<class K> - iterator find(const K& k); + constexpr iterator find(const K& k); template<class K> - const_iterator find(const K& k) const; - size_type count(const key_type& k) const; + constexpr const_iterator find(const K& k) const; + constexpr size_type count(const key_type& k) const; template<class K> - size_type count(const K& k) const; - bool contains(const key_type& k) const; + constexpr size_type count(const K& k) const; + constexpr bool contains(const key_type& k) const; template<class K> - bool contains(const K& k) const; - pair<iterator, iterator> equal_range(const key_type& k); - pair<const_iterator, const_iterator> equal_range(const key_type& k) const; + constexpr bool contains(const K& k) const; + constexpr pair<iterator, iterator> equal_range(const key_type& k); + constexpr pair<const_iterator, const_iterator> equal_range(const key_type& k) const; template<class K> - pair<iterator, iterator> equal_range(const K& k); + constexpr pair<iterator, iterator> equal_range(const K& k); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& k) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& k) const; // bucket interface - size_type bucket_count() const noexcept; - size_type max_bucket_count() const noexcept; - size_type bucket_size(size_type n) const; - size_type bucket(const key_type& k) const; - template<class K> size_type bucket(const K& k) const; - local_iterator begin(size_type n); - const_local_iterator begin(size_type n) const; - local_iterator end(size_type n); - const_local_iterator end(size_type n) const; - const_local_iterator cbegin(size_type n) const; - const_local_iterator cend(size_type n) const; + constexpr size_type bucket_count() const noexcept; + constexpr size_type max_bucket_count() const noexcept; + constexpr size_type bucket_size(size_type n) const; + constexpr size_type bucket(const key_type& k) const; + template<class K> constexpr size_type bucket(const K& k) const; + constexpr local_iterator begin(size_type n); + constexpr const_local_iterator begin(size_type n) const; + constexpr local_iterator end(size_type n); + constexpr const_local_iterator end(size_type n) const; + constexpr const_local_iterator cbegin(size_type n) const; + constexpr const_local_iterator cend(size_type n) const; // hash policy - float load_factor() const noexcept; - float max_load_factor() const noexcept; - void max_load_factor(float z); - void rehash(size_type n); - void reserve(size_type n); + constexpr float load_factor() const noexcept; + constexpr float max_load_factor() const noexcept; + constexpr void max_load_factor(float z); + constexpr void rehash(size_type n); + constexpr void reserve(size_type n); }; template<class InputIterator, @@ -14170,11 +14209,10 @@ \indexlibraryctor{unordered_multiset}% \begin{itemdecl} -unordered_multiset() : unordered_multiset(size_type(@\seebelow@)) { } -explicit unordered_multiset(size_type n, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); +constexpr unordered_multiset() : unordered_multiset(size_type(@\seebelow@)) { } +constexpr explicit unordered_multiset(size_type n, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -14195,22 +14233,19 @@ \indexlibraryctor{unordered_multiset}% \begin{itemdecl} template<class InputIterator> - unordered_multiset(InputIterator f, InputIterator l, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(InputIterator f, InputIterator l, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); template<@\exposconcept{container-compatible-range}@<value_type> R> - unordered_multiset(from_range_t, R&& rg, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); -unordered_multiset(initializer_list<value_type> il, - size_type n = @\seebelow@, - const hasher& hf = hasher(), - const key_equal& eql = key_equal(), - const allocator_type& a = allocator_type()); + constexpr unordered_multiset(from_range_t, R&& rg, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); +constexpr unordered_multiset(initializer_list<value_type> il, + size_type n = @\seebelow@, const hasher& hf = hasher(), + const key_equal& eql = key_equal(), + const allocator_type& a = allocator_type()); \end{itemdecl} \begin{itemdescr} @@ -14235,7 +14270,7 @@ \indexlibrarymember{erase_if}{unordered_multiset}% \begin{itemdecl} template<class K, class H, class P, class A, class Predicate> - typename unordered_multiset<K, H, P, A>::size_type + constexpr typename unordered_multiset<K, H, P, A>::size_type erase_if(unordered_multiset<K, H, P, A>& c, Predicate pred); \end{itemdecl} @@ -14366,23 +14401,24 @@ template<class T, class Container = deque<T>> class queue; template<class T, class Container> - bool operator==(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator==(const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - bool operator< (const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator< (const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - bool operator> (const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator> (const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y); template<class T, @\libconcept{three_way_comparable}@ Container> - compare_three_way_result_t<Container> + constexpr compare_three_way_result_t<Container> operator<=>(const queue<T, Container>& x, const queue<T, Container>& y); template<class T, class Container> - void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(queue<T, Container>& x, queue<T, Container>& y) + noexcept(noexcept(x.swap(y))); template<class T, class Container, class Alloc> struct uses_allocator<queue<T, Container>, Alloc>; @@ -14396,8 +14432,8 @@ class priority_queue; template<class T, class Container, class Compare> - void swap(priority_queue<T, Container, Compare>& x, - priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(priority_queue<T, Container, Compare>& x, + priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y))); template<class T, class Container, class Compare, class Alloc> struct uses_allocator<priority_queue<T, Container, Compare>, Alloc>; @@ -14442,35 +14478,35 @@ Container c; public: - queue() : queue(Container()) {} - explicit queue(const Container&); - explicit queue(Container&&); - template<class InputIterator> queue(InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@<T> R> queue(from_range_t, R&& rg); - template<class Alloc> explicit queue(const Alloc&); - template<class Alloc> queue(const Container&, const Alloc&); - template<class Alloc> queue(Container&&, const Alloc&); - template<class Alloc> queue(const queue&, const Alloc&); - template<class Alloc> queue(queue&&, const Alloc&); + constexpr queue() : queue(Container()) {} + constexpr explicit queue(const Container&); + constexpr explicit queue(Container&&); + template<class InputIterator> constexpr queue(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@<T> R> constexpr queue(from_range_t, R&& rg); + template<class Alloc> constexpr explicit queue(const Alloc&); + template<class Alloc> constexpr queue(const Container&, const Alloc&); + template<class Alloc> constexpr queue(Container&&, const Alloc&); + template<class Alloc> constexpr queue(const queue&, const Alloc&); + template<class Alloc> constexpr queue(queue&&, const Alloc&); template<class InputIterator, class Alloc> - queue(InputIterator first, InputIterator last, const Alloc&); + constexpr queue(InputIterator first, InputIterator last, const Alloc&); template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - queue(from_range_t, R&& rg, const Alloc&); - - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference front() { return c.front(); } - const_reference front() const { return c.front(); } - reference back() { return c.back(); } - const_reference back() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void push(value_type&& x) { c.push_back(std::move(x)); } - template<@\exposconcept{container-compatible-range}@<T> R> void push_range(R&& rg); + constexpr queue(from_range_t, R&& rg, const Alloc&); + + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr reference front() { return c.front(); } + constexpr const_reference front() const { return c.front(); } + constexpr reference back() { return c.back(); } + constexpr const_reference back() const { return c.back(); } + constexpr void push(const value_type& x) { c.push_back(x); } + constexpr void push(value_type&& x) { c.push_back(std::move(x)); } + template<@\exposconcept{container-compatible-range}@<T> R> constexpr void push_range(R&& rg); template<class... Args> - decltype(auto) emplace(Args&&... args) + constexpr decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); } - void pop() { c.pop_front(); } - void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) + constexpr void pop() { c.pop_front(); } + constexpr void swap(queue& q) noexcept(is_nothrow_swappable_v<Container>) { using std::swap; swap(c, q.c); } }; @@ -14505,7 +14541,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(const Container& cont); +constexpr explicit queue(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -14516,7 +14552,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -explicit queue(Container&& cont); +constexpr explicit queue(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -14528,7 +14564,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<class InputIterator> - queue(InputIterator first, InputIterator last); + constexpr queue(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -14541,7 +14577,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - queue(from_range_t, R&& rg); + constexpr queue(from_range_t, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14558,7 +14594,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template<class Alloc> explicit queue(const Alloc& a); +template<class Alloc> constexpr explicit queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14569,7 +14605,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template<class Alloc> queue(const container_type& cont, const Alloc& a); +template<class Alloc> constexpr queue(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14581,7 +14617,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template<class Alloc> queue(container_type&& cont, const Alloc& a); +template<class Alloc> constexpr queue(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14593,7 +14629,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template<class Alloc> queue(const queue& q, const Alloc& a); +template<class Alloc> constexpr queue(const queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14605,7 +14641,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} -template<class Alloc> queue(queue&& q, const Alloc& a); +template<class Alloc> constexpr queue(queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14618,7 +14654,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<class InputIterator, class Alloc> - queue(InputIterator first, InputIterator last, const Alloc& alloc); + constexpr queue(InputIterator first, InputIterator last, const Alloc& alloc); \end{itemdecl} \begin{itemdescr} @@ -14633,7 +14669,7 @@ \indexlibraryctor{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - queue(from_range_t, R&& rg, const Alloc& a); + constexpr queue(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -14648,7 +14684,7 @@ \indexlibrarymember{push_range}{queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -14664,7 +14700,7 @@ \indexlibrarymember{operator==}{queue}% \begin{itemdecl} template<class T, class Container> - bool operator==(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator==(const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14676,7 +14712,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{queue}}% \begin{itemdecl} template<class T, class Container> - bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator!=(const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14688,7 +14724,7 @@ \indexlibrarymember{operator<}{queue}% \begin{itemdecl} template<class T, class Container> - bool operator< (const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator< (const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14700,7 +14736,7 @@ \indexlibrarymember{operator>}{queue}% \begin{itemdecl} template<class T, class Container> - bool operator> (const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator> (const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14712,7 +14748,7 @@ \indexlibrarymember{operator<=}{queue}% \begin{itemdecl} template<class T, class Container> - bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y); + constexpr bool operator<=(const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14724,8 +14760,7 @@ \indexlibrarymember{operator>=}{queue}% \begin{itemdecl} template<class T, class Container> - bool operator>=(const queue<T, Container>& x, - const queue<T, Container>& y); + constexpr bool operator>=(const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -14737,7 +14772,7 @@ \indexlibrarymember{operator<=>}{queue}% \begin{itemdecl} template<class T, @\libconcept{three_way_comparable}@ Container> - compare_three_way_result_t<Container> + constexpr compare_three_way_result_t<Container> operator<=>(const queue<T, Container>& x, const queue<T, Container>& y); \end{itemdecl} @@ -14752,7 +14787,8 @@ \indexlibrarymember{swap}{queue}% \begin{itemdecl} template<class T, class Container> - void swap(queue<T, Container>& x, queue<T, Container>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(queue<T, Container>& x, queue<T, Container>& y) + noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -14807,51 +14843,54 @@ Compare comp; public: - priority_queue() : priority_queue(Compare()) {} - explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} - priority_queue(const Compare& x, const Container&); - priority_queue(const Compare& x, Container&&); + constexpr priority_queue() : priority_queue(Compare()) {} + constexpr explicit priority_queue(const Compare& x) : priority_queue(x, Container()) {} + constexpr priority_queue(const Compare& x, const Container&); + constexpr priority_queue(const Compare& x, Container&&); template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& x = Compare()); template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x, - const Container&); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container&); template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x, - Container&&); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&&); template<@\exposconcept{container-compatible-range}@<T> R> - priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); - template<class Alloc> explicit priority_queue(const Alloc&); - template<class Alloc> priority_queue(const Compare&, const Alloc&); - template<class Alloc> priority_queue(const Compare&, const Container&, const Alloc&); - template<class Alloc> priority_queue(const Compare&, Container&&, const Alloc&); - template<class Alloc> priority_queue(const priority_queue&, const Alloc&); - template<class Alloc> priority_queue(priority_queue&&, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); + template<class Alloc> constexpr explicit priority_queue(const Alloc&); + template<class Alloc> constexpr priority_queue(const Compare&, const Alloc&); + template<class Alloc> + constexpr priority_queue(const Compare&, const Container&, const Alloc&); + template<class Alloc> constexpr priority_queue(const Compare&, Container&&, const Alloc&); + template<class Alloc> constexpr priority_queue(const priority_queue&, const Alloc&); + template<class Alloc> constexpr priority_queue(priority_queue&&, const Alloc&); template<class InputIterator, class Alloc> - priority_queue(InputIterator, InputIterator, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Alloc&); template<class InputIterator, class Alloc> - priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Alloc&); template<class InputIterator, class Alloc> - priority_queue(InputIterator, InputIterator, const Compare&, const Container&, - const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, const Container&, + const Alloc&); template<class InputIterator, class Alloc> - priority_queue(InputIterator, InputIterator, const Compare&, Container&&, const Alloc&); + constexpr priority_queue(InputIterator, InputIterator, const Compare&, Container&&, + const Alloc&); template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Compare&, const Alloc&); template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - priority_queue(from_range_t, R&& rg, const Alloc&); + constexpr priority_queue(from_range_t, R&& rg, const Alloc&); - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - const_reference top() const { return c.front(); } - void push(const value_type& x); - void push(value_type&& x); + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr const_reference top() const { return c.front(); } + constexpr void push(const value_type& x); + constexpr void push(value_type&& x); template<@\exposconcept{container-compatible-range}@<T> R> - void push_range(R&& rg); - template<class... Args> void emplace(Args&&... args); - void pop(); - void swap(priority_queue& q) noexcept(is_nothrow_swappable_v<Container> && - is_nothrow_swappable_v<Compare>) + constexpr void push_range(R&& rg); + template<class... Args> constexpr void emplace(Args&&... args); + constexpr void pop(); + constexpr void swap(priority_queue& q) + noexcept(is_nothrow_swappable_v<Container> && is_nothrow_swappable_v<Compare>) { using std::swap; swap(c, q.c); swap(comp, q.comp); } }; @@ -14909,8 +14948,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -priority_queue(const Compare& x, const Container& y); -priority_queue(const Compare& x, Container&& y); +constexpr priority_queue(const Compare& x, const Container& y); +constexpr priority_queue(const Compare& x, Container&& y); \end{itemdecl} \begin{itemdescr} @@ -14932,7 +14971,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x = Compare()); \end{itemdecl} \begin{itemdescr} @@ -14952,9 +14991,11 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x, const Container& y); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + const Container& y); template<class InputIterator> - priority_queue(InputIterator first, InputIterator last, const Compare& x, Container&& y); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& x, + Container&& y); \end{itemdecl} \begin{itemdescr} @@ -14978,7 +15019,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); + constexpr priority_queue(from_range_t, R&& rg, const Compare& x = Compare()); \end{itemdecl} \begin{itemdescr} @@ -15001,7 +15042,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template<class Alloc> explicit priority_queue(const Alloc& a); +template<class Alloc> constexpr explicit priority_queue(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15012,7 +15053,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template<class Alloc> priority_queue(const Compare& compare, const Alloc& a); +template<class Alloc> constexpr priority_queue(const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15024,7 +15065,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class Alloc> - priority_queue(const Compare& compare, const Container& cont, const Alloc& a); + constexpr priority_queue(const Compare& compare, const Container& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15038,7 +15079,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class Alloc> - priority_queue(const Compare& compare, Container&& cont, const Alloc& a); + constexpr priority_queue(const Compare& compare, Container&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15051,7 +15092,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template<class Alloc> priority_queue(const priority_queue& q, const Alloc& a); +template<class Alloc> constexpr priority_queue(const priority_queue& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15063,7 +15104,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} -template<class Alloc> priority_queue(priority_queue&& q, const Alloc& a); +template<class Alloc> constexpr priority_queue(priority_queue&& q, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15076,7 +15117,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator, class Alloc> - priority_queue(InputIterator first, InputIterator last, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15093,7 +15134,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator, class Alloc> - priority_queue(InputIterator first, InputIterator last, const Compare& compare, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, + const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15110,8 +15152,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator, class Alloc> - priority_queue(InputIterator first, InputIterator last, const Compare& compare, - const Container& cont, const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + const Container& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15127,8 +15169,8 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<class InputIterator, class Alloc> - priority_queue(InputIterator first, InputIterator last, const Compare& compare, Container&& cont, - const Alloc& a); + constexpr priority_queue(InputIterator first, InputIterator last, const Compare& compare, + Container&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15145,7 +15187,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a); + constexpr priority_queue(from_range_t, R&& rg, const Compare& compare, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15159,7 +15201,7 @@ \indexlibraryctor{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - priority_queue(from_range_t, R&& rg, const Alloc& a); + constexpr priority_queue(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15175,7 +15217,7 @@ \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(const value_type& x); +constexpr void push(const value_type& x); \end{itemdecl} \begin{itemdescr} @@ -15190,7 +15232,7 @@ \indexlibrarymember{push}{priority_queue}% \begin{itemdecl} -void push(value_type&& x); +constexpr void push(value_type&& x); \end{itemdecl} \begin{itemdescr} @@ -15206,7 +15248,7 @@ \indexlibrarymember{push_range}{priority_queue}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -15225,7 +15267,7 @@ \indexlibrarymember{emplace}{priority_queue}% \begin{itemdecl} -template<class... Args> void emplace(Args&&... args); +template<class... Args> constexpr void emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -15238,10 +15280,9 @@ \end{codeblock} \end{itemdescr} - \indexlibrarymember{pop}{priority_queue}% \begin{itemdecl} -void pop(); +constexpr void pop(); \end{itemdecl} \begin{itemdescr} @@ -15259,8 +15300,8 @@ \indexlibrarymember{swap}{priority_queue}% \begin{itemdecl} template<class T, class Container, class Compare> - void swap(priority_queue<T, Container, Compare>& x, - priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(priority_queue<T, Container, Compare>& x, + priority_queue<T, Container, Compare>& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -15286,23 +15327,24 @@ template<class T, class Container = deque<T>> class stack; template<class T, class Container> - bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - bool operator< (const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator< (const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - bool operator> (const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator> (const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); template<class T, @\libconcept{three_way_comparable}@ Container> - compare_three_way_result_t<Container> + constexpr compare_three_way_result_t<Container> operator<=>(const stack<T, Container>& x, const stack<T, Container>& y); template<class T, class Container> - void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(stack<T, Container>& x, stack<T, Container>& y) + noexcept(noexcept(x.swap(y))); template<class T, class Container, class Alloc> struct uses_allocator<stack<T, Container>, Alloc>; @@ -15349,34 +15391,35 @@ Container c; public: - stack() : stack(Container()) {} - explicit stack(const Container&); - explicit stack(Container&&); - template<class InputIterator> stack(InputIterator first, InputIterator last); - template<@\exposconcept{container-compatible-range}@<T> R> stack(from_range_t, R&& rg); - template<class Alloc> explicit stack(const Alloc&); - template<class Alloc> stack(const Container&, const Alloc&); - template<class Alloc> stack(Container&&, const Alloc&); - template<class Alloc> stack(const stack&, const Alloc&); - template<class Alloc> stack(stack&&, const Alloc&); + constexpr stack() : stack(Container()) {} + constexpr explicit stack(const Container&); + constexpr explicit stack(Container&&); + template<class InputIterator> constexpr stack(InputIterator first, InputIterator last); + template<@\exposconcept{container-compatible-range}@<T> R> + constexpr stack(from_range_t, R&& rg); + template<class Alloc> constexpr explicit stack(const Alloc&); + template<class Alloc> constexpr stack(const Container&, const Alloc&); + template<class Alloc> constexpr stack(Container&&, const Alloc&); + template<class Alloc> constexpr stack(const stack&, const Alloc&); + template<class Alloc> constexpr stack(stack&&, const Alloc&); template<class InputIterator, class Alloc> - stack(InputIterator first, InputIterator last, const Alloc&); + constexpr stack(InputIterator first, InputIterator last, const Alloc&); template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - stack(from_range_t, R&& rg, const Alloc&); - - bool empty() const { return c.empty(); } - size_type size() const { return c.size(); } - reference top() { return c.back(); } - const_reference top() const { return c.back(); } - void push(const value_type& x) { c.push_back(x); } - void push(value_type&& x) { c.push_back(std::move(x)); } + constexpr stack(from_range_t, R&& rg, const Alloc&); + + constexpr bool empty() const { return c.empty(); } + constexpr size_type size() const { return c.size(); } + constexpr reference top() { return c.back(); } + constexpr const_reference top() const { return c.back(); } + constexpr void push(const value_type& x) { c.push_back(x); } + constexpr void push(value_type&& x) { c.push_back(std::move(x)); } template<@\exposconcept{container-compatible-range}@<T> R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); template<class... Args> - decltype(auto) emplace(Args&&... args) + constexpr decltype(auto) emplace(Args&&... args) { return c.emplace_back(std::forward<Args>(args)...); } - void pop() { c.pop_back(); } - void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>) + constexpr void pop() { c.pop_back(); } + constexpr void swap(stack& s) noexcept(is_nothrow_swappable_v<Container>) { using std::swap; swap(c, s.c); } }; @@ -15411,7 +15454,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(const Container& cont); +constexpr explicit stack(const Container& cont); \end{itemdecl} \begin{itemdescr} @@ -15422,7 +15465,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -explicit stack(Container&& cont); +constexpr explicit stack(Container&& cont); \end{itemdecl} \begin{itemdescr} @@ -15434,7 +15477,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<class InputIterator> - stack(InputIterator first, InputIterator last); + constexpr stack(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -15447,7 +15490,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - stack(from_range_t, R&& rg); + constexpr stack(from_range_t, R&& rg); \end{itemdecl} \begin{itemdescr} @@ -15464,7 +15507,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template<class Alloc> explicit stack(const Alloc& a); +template<class Alloc> constexpr explicit stack(const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15475,7 +15518,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template<class Alloc> stack(const container_type& cont, const Alloc& a); +template<class Alloc> constexpr stack(const container_type& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15487,7 +15530,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template<class Alloc> stack(container_type&& cont, const Alloc& a); +template<class Alloc> constexpr stack(container_type&& cont, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15499,7 +15542,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template<class Alloc> stack(const stack& s, const Alloc& a); +template<class Alloc> constexpr stack(const stack& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15511,7 +15554,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} -template<class Alloc> stack(stack&& s, const Alloc& a); +template<class Alloc> constexpr stack(stack&& s, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15524,7 +15567,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<class InputIterator, class Alloc> - stack(InputIterator first, InputIterator last, const Alloc& alloc); + constexpr stack(InputIterator first, InputIterator last, const Alloc& alloc); \end{itemdecl} \begin{itemdescr} @@ -15539,7 +15582,7 @@ \indexlibraryctor{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R, class Alloc> - stack(from_range_t, R&& rg, const Alloc& a); + constexpr stack(from_range_t, R&& rg, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -15554,7 +15597,7 @@ \indexlibrarymember{push_range}{stack}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<T> R> - void push_range(R&& rg); + constexpr void push_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -15570,7 +15613,7 @@ \indexlibrarymember{operator==}{stack}% \begin{itemdecl} template<class T, class Container> - bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15582,7 +15625,7 @@ \indexlibrary{\idxcode{operator"!=}!\idxcode{stack}}% \begin{itemdecl} template<class T, class Container> - bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15594,7 +15637,7 @@ \indexlibrarymember{operator<}{stack}% \begin{itemdecl} template<class T, class Container> - bool operator< (const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator< (const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15606,7 +15649,7 @@ \indexlibrarymember{operator>}{stack}% \begin{itemdecl} template<class T, class Container> - bool operator> (const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator> (const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15618,7 +15661,7 @@ \indexlibrarymember{operator<=}{stack}% \begin{itemdecl} template<class T, class Container> - bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15630,7 +15673,7 @@ \indexlibrarymember{operator>=}{stack}% \begin{itemdecl} template<class T, class Container> - bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); + constexpr bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} \begin{itemdescr} @@ -15642,7 +15685,7 @@ \indexlibrarymember{operator<=>}{stack}% \begin{itemdecl} template<class T, @\libconcept{three_way_comparable}@ Container> - compare_three_way_result_t<Container> + constexpr compare_three_way_result_t<Container> operator<=>(const stack<T, Container>& x, const stack<T, Container>& y); \end{itemdecl} @@ -15657,7 +15700,8 @@ \indexlibrarymember{swap}{stack}% \begin{itemdecl} template<class T, class Container> - void swap(stack<T, Container>& x, stack<T, Container>& y) noexcept(noexcept(x.swap(y))); + constexpr void swap(stack<T, Container>& x, stack<T, Container>& y) + noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} @@ -15694,7 +15738,7 @@ // \ref{flat.map.erasure}, erasure for \tcode{flat_map} template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate> - typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type + constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred); // \ref{flat.multimap}, class template \tcode{flat_multimap} @@ -15713,7 +15757,7 @@ // \ref{flat.multimap.erasure}, erasure for \tcode{flat_multimap} template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate> - typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type + constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred); } \end{codeblock} @@ -15826,6 +15870,10 @@ that contains equal elements, is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.map.defn]{Definition} \begin{codeblock} @@ -15852,11 +15900,11 @@ class value_compare { private: - key_compare @\exposid{comp}@; // \expos - value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos public: - bool operator()(const_reference x, const_reference y) const { + constexpr bool operator()(const_reference x, const_reference y) const { return @\exposid{comp}@(x.first, y.first); } }; @@ -15867,225 +15915,232 @@ }; // \ref{flat.map.cons}, constructors - flat_map() : flat_map(key_compare()) { } + constexpr flat_map() : flat_map(key_compare()) { } - explicit flat_map(const key_compare& comp) + constexpr explicit flat_map(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } - flat_map(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); + constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); - flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); + constexpr flat_map(sorted_unique_t, key_container_type key_cont, + mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); template<class InputIterator> - flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template<class InputIterator> - flat_map(sorted_unique_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_map(sorted_unique_t s, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(s, first, last); } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_map(from_range_t, R&& rg) + constexpr flat_map(from_range_t, R&& rg) : flat_map(from_range, std::forward<R>(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_map(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp) : flat_map(comp) { insert_range(std::forward<R>(rg)); } - flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare()) + constexpr flat_map(initializer_list<value_type> il, const key_compare& comp = key_compare()) : flat_map(il.begin(), il.end(), comp) { } - flat_map(sorted_unique_t s, initializer_list<value_type> il, - const key_compare& comp = key_compare()) + constexpr flat_map(sorted_unique_t s, initializer_list<value_type> il, + const key_compare& comp = key_compare()) : flat_map(s, il.begin(), il.end(), comp) { } // \ref{flat.map.cons.alloc}, constructors with allocators template<class Alloc> - explicit flat_map(const Alloc& a); + constexpr explicit flat_map(const Alloc& a); template<class Alloc> - flat_map(const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const Alloc& a); template<class Alloc> - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Alloc& a); + constexpr flat_map(sorted_unique_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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); template<class Alloc> - flat_map(const flat_map&, const Alloc& a); + constexpr flat_map(const flat_map&, const Alloc& a); template<class Alloc> - flat_map(flat_map&&, const Alloc& a); + constexpr flat_map(flat_map&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_map(from_range_t, R&& rg, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(initializer_list<value_type> il, const Alloc& a); + constexpr flat_map(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_map(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_map(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); - flat_map& operator=(initializer_list<value_type>); + constexpr flat_map& operator=(initializer_list<value_type>); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // \ref{flat.map.capacity}, capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.map.access}, element access - mapped_type& operator[](const key_type& x); - mapped_type& operator[](key_type&& x); - template<class K> mapped_type& operator[](K&& x); - mapped_type& at(const key_type& x); - const mapped_type& at(const key_type& x) const; - template<class K> mapped_type& at(const K& x); - template<class K> const mapped_type& at(const K& x) const; + constexpr mapped_type& operator[](const key_type& x); + constexpr mapped_type& operator[](key_type&& x); + template<class K> constexpr mapped_type& operator[](K&& x); + constexpr mapped_type& at(const key_type& x); + constexpr const mapped_type& at(const key_type& x) const; + template<class K> constexpr mapped_type& at(const K& x); + template<class K> constexpr const mapped_type& at(const K& x) const; // \ref{flat.map.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& x) + constexpr pair<iterator, bool> insert(const value_type& x) { return emplace(x); } - pair<iterator, bool> insert(value_type&& x) + constexpr pair<iterator, bool> insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template<class P> pair<iterator, bool> insert(P&& x); + template<class P> constexpr pair<iterator, bool> insert(P&& x); template<class P> - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator> - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list<value_type> il) + constexpr void insert(initializer_list<value_type> il) { insert(il.begin(), il.end()); } - void insert(sorted_unique_t s, initializer_list<value_type> il) + constexpr void insert(sorted_unique_t s, initializer_list<value_type> il) { insert(s, il.begin(), il.end()); } - containers extract() &&; - void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + 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); - void swap(flat_map& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_map& y) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; - const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } - const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; - - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; - - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; - - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(const K& x) const; - - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_bound(const K& x) const; - - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& x) const; - template<class K> pair<iterator, iterator> equal_range(const K& x); - template<class K> pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr 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 bool operator==(const flat_map& x, const flat_map& y); + constexpr friend bool operator==(const flat_map& x, const flat_map& y); - friend @\exposid{synth-three-way-result}@<value_type> + constexpr friend @\exposid{synth-three-way-result}@<value_type> operator<=>(const flat_map& x, const flat_map& y); - friend void swap(flat_map& x, flat_map& y) noexcept + constexpr friend void swap(flat_map& x, flat_map& y) noexcept { x.swap(y); } private: @@ -16093,8 +16148,8 @@ key_compare @\exposid{compare}@; // \expos struct @\exposid{key-equiv}@ { // \expos - @\exposid{key-equiv}@(key_compare c) : comp(c) { } - bool operator()(const_reference x, const_reference y) const { + constexpr @\exposid{key-equiv}@(key_compare c) : comp(c) { } + constexpr bool operator()(const_reference x, const_reference y) const { return !comp(x.first, y.first) && !comp(y.first, x.first); } key_compare comp; @@ -16177,8 +16232,8 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -flat_map(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +constexpr flat_map(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -16207,8 +16262,8 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} -flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +constexpr flat_map(sorted_unique_t, key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -16234,11 +16289,11 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} template<class Alloc> - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const Alloc& a); template<class Alloc> - flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_container_type& key_cont, const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -16258,12 +16313,12 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} template<class Alloc> - flat_map(sorted_unique_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Alloc& a); + constexpr flat_map(sorted_unique_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t s, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const key_compare& comp, - const Alloc& a); + constexpr flat_map(sorted_unique_t s, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const key_compare& comp, + const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -16282,35 +16337,36 @@ \indexlibraryctor{flat_map}% \begin{itemdecl} template<class Alloc> - explicit flat_map(const Alloc& a); + constexpr explicit flat_map(const Alloc& a); template<class Alloc> - flat_map(const key_compare& comp, const Alloc& a); + constexpr flat_map(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(const flat_map&, const Alloc& a); + constexpr flat_map(const flat_map&, const Alloc& a); template<class Alloc> - flat_map(flat_map&&, const Alloc& a); + constexpr flat_map(flat_map&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); + constexpr flat_map(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template<class InputIterator, class Alloc> - flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_map(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_map(from_range_t, R&& rg, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_map(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(initializer_list<value_type> il, const Alloc& a); + constexpr flat_map(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_map(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_map(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_map(sorted_unique_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_map(sorted_unique_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -16325,7 +16381,7 @@ \indexlibrarymember{size}{flat_map}% \begin{itemdecl} -size_type size() const noexcept; +constexpr size_type size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16336,7 +16392,7 @@ \indexlibrarymember{max_size}{flat_map}% \begin{itemdecl} -size_type max_size() const noexcept; +constexpr size_type max_size() const noexcept; \end{itemdecl} \begin{itemdescr} @@ -16349,7 +16405,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -mapped_type& operator[](const key_type& x); +constexpr mapped_type& operator[](const key_type& x); \end{itemdecl} \begin{itemdescr} @@ -16360,7 +16416,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -mapped_type& operator[](key_type&& x); +constexpr mapped_type& operator[](key_type&& x); \end{itemdecl} \begin{itemdescr} @@ -16371,7 +16427,7 @@ \indexlibrarymember{operator[]}{flat_map}% \begin{itemdecl} -template<class K> mapped_type& operator[](K&& x); +template<class K> constexpr mapped_type& operator[](K&& x); \end{itemdecl} \begin{itemdescr} @@ -16387,8 +16443,8 @@ \indexlibrarymember{at}{flat_map}% \begin{itemdecl} -mapped_type& at(const key_type& x); -const mapped_type& at(const key_type& x) const; +constexpr mapped_type& at(const key_type& x); +constexpr const mapped_type& at(const key_type& x) const; \end{itemdecl} \begin{itemdescr} @@ -16409,8 +16465,8 @@ \indexlibrarymember{at}{flat_map}% \begin{itemdecl} -template<class K> mapped_type& at(const K& x); -template<class K> const mapped_type& at(const K& x) const; +template<class K> constexpr mapped_type& at(const K& x); +template<class K> constexpr const mapped_type& at(const K& x) const; \end{itemdecl} \begin{itemdescr} @@ -16442,7 +16498,7 @@ \indexlibrarymember{emplace}{flat_map}% \begin{itemdecl} -template<class... Args> pair<iterator, bool> emplace(Args&&... args); +template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -16475,8 +16531,8 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} -template<class P> pair<iterator, bool> insert(P&& x); -template<class P> iterator insert(const_iterator position, P&& x); +template<class P> constexpr pair<iterator, bool> insert(P&& x); +template<class P> constexpr iterator insert(const_iterator position, P&& x); \end{itemdecl} \begin{itemdescr} @@ -16494,7 +16550,7 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -16535,7 +16591,7 @@ \indexlibrarymember{insert}{flat_map}% \begin{itemdecl} template<class InputIterator> - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -16572,7 +16628,7 @@ \indexlibrarymember{insert_range}{flat_map}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -16612,13 +16668,13 @@ \indexlibrarymember{try_emplace}{flat_map}% \begin{itemdecl} template<class... Args> - pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); template<class... Args> - pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); template<class... Args> - iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -16655,9 +16711,9 @@ \indexlibrarymember{try_emplace}{flat_map}% \begin{itemdecl} template<class K, class... Args> - pair<iterator, bool> try_emplace(K&& k, Args&&... args); + constexpr pair<iterator, bool> try_emplace(K&& k, Args&&... args); template<class K, class... Args> - iterator try_emplace(const_iterator hint, K&& k, Args&&... args); + constexpr iterator try_emplace(const_iterator hint, K&& k, Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -16711,13 +16767,13 @@ \indexlibrarymember{insert_or_assign}{flat_map}% \begin{itemdecl} template<class M> - pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); template<class M> - pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); template<class M> - iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -16756,9 +16812,9 @@ \indexlibrarymember{insert_or_assign}{flat_map}% \begin{itemdecl} template<class K, class M> - pair<iterator, bool> insert_or_assign(K&& k, M&& obj); + constexpr pair<iterator, bool> insert_or_assign(K&& k, M&& obj); template<class K, class M> - iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); + constexpr iterator insert_or_assign(const_iterator hint, K&& k, M&& obj); \end{itemdecl} \begin{itemdescr} @@ -16811,7 +16867,7 @@ \indexlibrarymember{swap}{flat_map}% \begin{itemdecl} -void swap(flat_map& y) noexcept; +constexpr void swap(flat_map& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -16827,7 +16883,7 @@ \indexlibrarymember{extract}{flat_map}% \begin{itemdecl} -containers extract() &&; +constexpr containers extract() &&; \end{itemdecl} \begin{itemdescr} @@ -16842,7 +16898,7 @@ \indexlibrarymember{replace}{flat_map}% \begin{itemdecl} -void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); +constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); \end{itemdecl} \begin{itemdescr} @@ -16867,7 +16923,7 @@ \begin{itemdecl} template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate> - typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type + constexpr typename flat_map<Key, T, Compare, KeyContainer, MappedContainer>::size_type erase_if(flat_map<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred); \end{itemdecl} @@ -17009,6 +17065,10 @@ with a container, containers, or range that are not sorted with respect to \tcode{key_comp()} is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.multimap.defn]{Definition} \begin{codeblock} @@ -17035,11 +17095,11 @@ class value_compare { private: - key_compare @\exposid{comp}@; // \expos - value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos + key_compare @\exposid{comp}@; // \expos + constexpr value_compare(key_compare c) : @\exposid{comp}@(c) { } // \expos public: - bool operator()(const_reference x, const_reference y) const { + constexpr bool operator()(const_reference x, const_reference y) const { return @\exposid{comp}@(x.first, y.first); } }; @@ -17050,198 +17110,201 @@ }; // \ref{flat.multimap.cons}, constructors - flat_multimap() : flat_multimap(key_compare()) { } + constexpr flat_multimap() : flat_multimap(key_compare()) { } - explicit flat_multimap(const key_compare& comp) + constexpr explicit flat_multimap(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } - flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); + constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); - flat_multimap(sorted_equivalent_t, - key_container_type key_cont, mapped_container_type mapped_cont, + 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> - flat_multimap(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template<class InputIterator> - flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multimap(sorted_equivalent_t s, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(s, first, last); } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_multimap(from_range_t, R&& rg) + constexpr flat_multimap(from_range_t, R&& rg) : flat_multimap(from_range, std::forward<R>(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_multimap(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp) : flat_multimap(comp) { insert_range(std::forward<R>(rg)); } - flat_multimap(initializer_list<value_type> il, const key_compare& comp = key_compare()) + constexpr flat_multimap(initializer_list<value_type> il, + const key_compare& comp = key_compare()) : flat_multimap(il.begin(), il.end(), comp) { } - flat_multimap(sorted_equivalent_t s, initializer_list<value_type> il, - const key_compare& comp = key_compare()) + constexpr flat_multimap(sorted_equivalent_t s, initializer_list<value_type> il, + const key_compare& comp = key_compare()) : flat_multimap(s, il.begin(), il.end(), comp) { } // \ref{flat.multimap.cons.alloc}, constructors with allocators template<class Alloc> - explicit flat_multimap(const Alloc& a); + constexpr explicit flat_multimap(const Alloc& a); template<class Alloc> - flat_multimap(const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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> - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t, const key_container_type& key_cont, - const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + 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> - flat_multimap(const flat_multimap&, const Alloc& a); + constexpr flat_multimap(const flat_multimap&, const Alloc& a); template<class Alloc> - flat_multimap(flat_multimap&&, const Alloc& a); + constexpr flat_multimap(flat_multimap&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multimap(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multimap(initializer_list<value_type> il, const Alloc& a); + constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multimap(initializer_list<value_type> il, const key_compare& comp, - const Alloc& a); + constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, + const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + 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>); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // modifiers - template<class... Args> iterator emplace(Args&&... args); + template<class... Args> constexpr iterator emplace(Args&&... args); template<class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x) + constexpr iterator insert(const value_type& x) { return emplace(x); } - iterator insert(value_type&& x) + constexpr iterator insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template<class P> iterator insert(P&& x); + template<class P> constexpr iterator insert(P&& x); template<class P> - iterator insert(const_iterator position, P&&); + constexpr iterator insert(const_iterator position, P&&); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator> - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list<value_type> il) + constexpr void insert(initializer_list<value_type> il) { insert(il.begin(), il.end()); } - void insert(sorted_equivalent_t s, initializer_list<value_type> il) + constexpr void insert(sorted_equivalent_t s, initializer_list<value_type> il) { insert(s, il.begin(), il.end()); } - containers extract() &&; - void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); + constexpr containers extract() &&; + constexpr void replace(key_container_type&& key_cont, mapped_container_type&& mapped_cont); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + 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); - void swap(flat_multimap&) noexcept; - void clear() noexcept; + constexpr void swap(flat_multimap&) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; - const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } - const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } + constexpr const key_container_type& keys() const noexcept { return @\exposid{c}@.keys; } + constexpr const mapped_container_type& values() const noexcept { return @\exposid{c}@.values; } // map operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; - friend bool operator==(const flat_multimap& x, const flat_multimap& y); + constexpr friend bool operator==(const flat_multimap& x, const flat_multimap& y); - friend @\exposid{synth-three-way-result}@<value_type> + constexpr friend @\exposid{synth-three-way-result}@<value_type> operator<=>(const flat_multimap& x, const flat_multimap& y); - friend void swap(flat_multimap& x, flat_multimap& y) noexcept + constexpr friend void swap(flat_multimap& x, flat_multimap& y) noexcept { x.swap(y); } private: @@ -17330,8 +17393,8 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} -flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, - const key_compare& comp = key_compare()); +constexpr flat_multimap(key_container_type key_cont, mapped_container_type mapped_cont, + const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -17352,8 +17415,9 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} -flat_multimap(sorted_equivalent_t, 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()); \end{itemdecl} \begin{itemdescr} @@ -17379,11 +17443,12 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} template<class Alloc> - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_multimap(const key_container_type& key_cont, const mapped_container_type& mapped_cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_container_type& key_cont, + const mapped_container_type& mapped_cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17403,10 +17468,10 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} template<class Alloc> - flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, + constexpr flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, + constexpr flat_multimap(sorted_equivalent_t s, const key_container_type& key_cont, const mapped_container_type& mapped_cont, const key_compare& comp, const Alloc& a); \end{itemdecl} @@ -17427,37 +17492,38 @@ \indexlibraryctor{flat_multimap}% \begin{itemdecl} template<class Alloc> - explicit flat_multimap(const Alloc& a); + constexpr explicit flat_multimap(const Alloc& a); template<class Alloc> - flat_multimap(const key_compare& comp, const Alloc& a); + constexpr flat_multimap(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multimap(const flat_multimap&, const Alloc& a); + constexpr flat_multimap(const flat_multimap&, const Alloc& a); template<class Alloc> - flat_multimap(flat_multimap&&, const Alloc& a); + constexpr flat_multimap(flat_multimap&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, - const Alloc& a); + constexpr flat_multimap(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multimap(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multimap(initializer_list<value_type> il, const Alloc& a); + constexpr flat_multimap(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multimap(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_multimap(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_multimap(sorted_equivalent_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17474,7 +17540,7 @@ \begin{itemdecl} template<class Key, class T, class Compare, class KeyContainer, class MappedContainer, class Predicate> - typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type + constexpr typename flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>::size_type erase_if(flat_multimap<Key, T, Compare, KeyContainer, MappedContainer>& c, Predicate pred); \end{itemdecl} @@ -17527,7 +17593,7 @@ // \ref{flat.set.erasure}, erasure for \tcode{flat_set} template<class Key, class Compare, class KeyContainer, class Predicate> - typename flat_set<Key, Compare, KeyContainer>::size_type + constexpr typename flat_set<Key, Compare, KeyContainer>::size_type erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred); // \ref{flat.multiset}, class template \tcode{flat_multiset} @@ -17542,7 +17608,7 @@ // \ref{flat.multiset.erasure}, erasure for \tcode{flat_multiset} template<class Key, class Compare, class KeyContainer, class Predicate> - typename flat_multiset<Key, Compare, KeyContainer>::size_type + constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred); } \end{codeblock} @@ -17631,6 +17697,10 @@ with a range that is not sorted with respect to \tcode{key_comp()}, or that contains equal elements, is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.set.defn]{Definition} \begin{codeblock} @@ -17654,186 +17724,190 @@ using container_type = KeyContainer; // \ref{flat.set.cons}, constructors - flat_set() : flat_set(key_compare()) { } + constexpr flat_set() : flat_set(key_compare()) { } - explicit flat_set(const key_compare& comp) + constexpr explicit flat_set(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } - explicit flat_set(container_type cont, const key_compare& comp = key_compare()); + constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare()); - flat_set(sorted_unique_t, container_type cont, const key_compare& comp = key_compare()) + constexpr flat_set(sorted_unique_t, container_type cont, + const key_compare& comp = key_compare()) : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } template<class InputIterator> - flat_set(InputIterator first, InputIterator last, const key_compare& comp = key_compare()) + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template<class InputIterator> - flat_set(sorted_unique_t, InputIterator first, InputIterator last, + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const key_compare& comp = key_compare()) : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_set(from_range_t, R&& rg) + constexpr flat_set(from_range_t, R&& rg) : flat_set(from_range, std::forward<R>(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_set(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp) : flat_set(comp) { insert_range(std::forward<R>(rg)); } - flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare()) + constexpr flat_set(initializer_list<value_type> il, const key_compare& comp = key_compare()) : flat_set(il.begin(), il.end(), comp) { } - flat_set(sorted_unique_t s, initializer_list<value_type> il, + constexpr flat_set(sorted_unique_t s, initializer_list<value_type> il, const key_compare& comp = key_compare()) : flat_set(s, il.begin(), il.end(), comp) { } // \ref{flat.set.cons.alloc}, constructors with allocators template<class Alloc> - explicit flat_set(const Alloc& a); + constexpr explicit flat_set(const Alloc& a); template<class Alloc> - flat_set(const key_compare& comp, const Alloc& a); + constexpr flat_set(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(const container_type& cont, const Alloc& a); + constexpr flat_set(const container_type& cont, const Alloc& a); template<class Alloc> - flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, const container_type& cont, + const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(const flat_set&, const Alloc& a); + constexpr flat_set(const flat_set&, const Alloc& a); template<class Alloc> - flat_set(flat_set&&, const Alloc& a); + constexpr flat_set(flat_set&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_set(from_range_t, R&& rg, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(initializer_list<value_type> il, const Alloc& a); + constexpr flat_set(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_set(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_set(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); - flat_set& operator=(initializer_list<value_type>); + constexpr flat_set& operator=(initializer_list<value_type>); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.set.modifiers}, modifiers - template<class... Args> pair<iterator, bool> emplace(Args&&... args); + template<class... Args> constexpr pair<iterator, bool> emplace(Args&&... args); template<class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - pair<iterator, bool> insert(const value_type& x) + constexpr pair<iterator, bool> insert(const value_type& x) { return emplace(x); } - pair<iterator, bool> insert(value_type&& x) + constexpr pair<iterator, bool> insert(value_type&& x) { return emplace(std::move(x)); } - template<class K> pair<iterator, bool> insert(K&& x); - iterator insert(const_iterator position, const value_type& x) + template<class K> constexpr pair<iterator, bool> insert(K&& x); + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } - template<class K> iterator insert(const_iterator hint, K&& x); + template<class K> constexpr iterator insert(const_iterator hint, K&& x); template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator> - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list<value_type> il) + constexpr void insert(initializer_list<value_type> il) { insert(il.begin(), il.end()); } - void insert(sorted_unique_t s, initializer_list<value_type> il) + constexpr void insert(sorted_unique_t s, initializer_list<value_type> il) { insert(s, il.begin(), il.end()); } - container_type extract() &&; - void replace(container_type&&); + constexpr container_type extract() &&; + constexpr void replace(container_type&&); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + 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); - void swap(flat_set& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_set& y) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; - friend bool operator==(const flat_set& x, const flat_set& y); + constexpr friend bool operator==(const flat_set& x, const flat_set& y); - friend @\placeholder{synth-three-way-result}@<value_type> + constexpr friend @\placeholder{synth-three-way-result}@<value_type> operator<=>(const flat_set& x, const flat_set& y); - friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } + constexpr friend void swap(flat_set& x, flat_set& y) noexcept { x.swap(y); } private: container_type @\exposidnc{c}@; // \expos @@ -17901,7 +17975,7 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} -explicit flat_set(container_type cont, const key_compare& comp = key_compare()); +constexpr explicit flat_set(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -17928,9 +18002,9 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template<class Alloc> - flat_set(const container_type& cont, const Alloc& a); + constexpr flat_set(const container_type& cont, const Alloc& a); template<class Alloc> - flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_set(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17949,10 +18023,10 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template<class Alloc> - flat_set(sorted_unique_t s, const container_type& cont, const Alloc& a); + constexpr flat_set(sorted_unique_t s, const container_type& cont, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t s, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t s, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -17971,35 +18045,36 @@ \indexlibraryctor{flat_set}% \begin{itemdecl} template<class Alloc> - explicit flat_set(const Alloc& a); + constexpr explicit flat_set(const Alloc& a); template<class Alloc> - flat_set(const key_compare& comp, const Alloc& a); + constexpr flat_set(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(const flat_set&, const Alloc& a); + constexpr flat_set(const flat_set&, const Alloc& a); template<class Alloc> - flat_set(flat_set&&, const Alloc& a); + constexpr flat_set(flat_set&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(InputIterator first, InputIterator last, const key_compare& comp, const Alloc& a); + constexpr flat_set(InputIterator first, InputIterator last, const key_compare& comp, + const Alloc& a); template<class InputIterator, class Alloc> - flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_set(sorted_unique_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_set(from_range_t, R&& rg, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_set(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(initializer_list<value_type> il, const Alloc& a); + constexpr flat_set(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_set(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_set(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_set(sorted_unique_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_set(sorted_unique_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18014,8 +18089,8 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} -template<class K> pair<iterator, bool> insert(K&& x); -template<class K> iterator insert(const_iterator hint, K&& x); +template<class K> constexpr pair<iterator, bool> insert(K&& x); +template<class K> constexpr iterator insert(const_iterator hint, K&& x); \end{itemdecl} \begin{itemdescr} @@ -18049,7 +18124,7 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18079,7 +18154,7 @@ \indexlibrarymember{insert}{flat_set}% \begin{itemdecl} template<class InputIterator> - void insert(sorted_unique_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_unique_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18095,7 +18170,7 @@ \indexlibrarymember{insert_range}{flat_set}% \begin{itemdecl} template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); \end{itemdecl} \begin{itemdescr} @@ -18126,7 +18201,7 @@ \indexlibrarymember{swap}{flat_set}% \begin{itemdecl} -void swap(flat_set& y) noexcept; +constexpr void swap(flat_set& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -18141,7 +18216,7 @@ \indexlibrarymember{extract}{flat_set}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -18156,7 +18231,7 @@ \indexlibrarymember{replace}{flat_set}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -18175,7 +18250,7 @@ \indexlibrarymember{erase_if}{flat_set}% \begin{itemdecl} template<class Key, class Compare, class KeyContainer, class Predicate> - typename flat_set<Key, Compare, KeyContainer>::size_type + constexpr typename flat_set<Key, Compare, KeyContainer>::size_type erase_if(flat_set<Key, Compare, KeyContainer>& c, Predicate pred); \end{itemdecl} @@ -18290,6 +18365,10 @@ that takes a \tcode{sorted_equivalent_t} argument with a range that is not sorted with respect to \tcode{key_comp()} is undefined. +\pnum +The types \tcode{iterator} and \tcode{const_iterator} meet +the constexpr iterator requirements\iref{iterator.requirements.general}. + \rSec3[flat.multiset.defn]{Definition} \begin{codeblock} @@ -18313,188 +18392,192 @@ using container_type = KeyContainer; // \ref{flat.multiset.cons}, constructors - flat_multiset() : flat_multiset(key_compare()) { } + constexpr flat_multiset() : flat_multiset(key_compare()) { } - explicit flat_multiset(const key_compare& comp) + constexpr explicit flat_multiset(const key_compare& comp) : @\exposid{c}@(), @\exposid{compare}@(comp) { } - explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); + constexpr explicit flat_multiset(container_type cont, + const key_compare& comp = key_compare()); - flat_multiset(sorted_equivalent_t, container_type cont, - const key_compare& comp = key_compare()) + constexpr flat_multiset(sorted_equivalent_t, container_type cont, + const key_compare& comp = key_compare()) : @\exposid{c}@(std::move(cont)), @\exposid{compare}@(comp) { } template<class InputIterator> - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(), @\exposid{compare}@(comp) { insert(first, last); } template<class InputIterator> - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp = key_compare()) + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp = key_compare()) : @\exposid{c}@(first, last), @\exposid{compare}@(comp) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_multiset(from_range_t, R&& rg) + constexpr flat_multiset(from_range_t, R&& rg) : flat_multiset(from_range, std::forward<R>(rg), key_compare()) { } template<@\exposconcept{container-compatible-range}@<value_type> R> - flat_multiset(from_range_t, R&& rg, const key_compare& comp) + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp) : flat_multiset(comp) { insert_range(std::forward<R>(rg)); } - flat_multiset(initializer_list<value_type> il, const key_compare& comp = key_compare()) + constexpr flat_multiset(initializer_list<value_type> il, + const key_compare& comp = key_compare()) : flat_multiset(il.begin(), il.end(), comp) { } - flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il, - const key_compare& comp = key_compare()) + constexpr flat_multiset(sorted_equivalent_t s, initializer_list<value_type> il, + const key_compare& comp = key_compare()) : flat_multiset(s, il.begin(), il.end(), comp) { } // \ref{flat.multiset.cons.alloc}, constructors with allocators template<class Alloc> - explicit flat_multiset(const Alloc& a); + constexpr explicit flat_multiset(const Alloc& a); template<class Alloc> - flat_multiset(const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multiset(const container_type& cont, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const Alloc& a); template<class Alloc> - flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, const container_type& cont, + const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multiset(const flat_multiset&, const Alloc& a); + constexpr flat_multiset(const flat_multiset&, const Alloc& a); template<class Alloc> - flat_multiset(flat_multiset&&, const Alloc& a); + constexpr flat_multiset(flat_multiset&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multiset(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multiset(initializer_list<value_type> il, const Alloc& a); + constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multiset(initializer_list<value_type> il, const key_compare& comp, - const Alloc& a); + constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, + const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); - flat_multiset& operator=(initializer_list<value_type>); + constexpr flat_multiset& operator=(initializer_list<value_type>); // iterators - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + constexpr iterator begin() noexcept; + constexpr const_iterator begin() const noexcept; + constexpr iterator end() noexcept; + constexpr const_iterator end() const noexcept; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() 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; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() 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; // capacity - bool empty() const noexcept; - size_type size() const noexcept; - size_type max_size() const noexcept; + constexpr bool empty() const noexcept; + constexpr size_type size() const noexcept; + constexpr size_type max_size() const noexcept; // \ref{flat.multiset.modifiers}, modifiers - template<class... Args> iterator emplace(Args&&... args); + template<class... Args> constexpr iterator emplace(Args&&... args); template<class... Args> - iterator emplace_hint(const_iterator position, Args&&... args); + constexpr iterator emplace_hint(const_iterator position, Args&&... args); - iterator insert(const value_type& x) + constexpr iterator insert(const value_type& x) { return emplace(x); } - iterator insert(value_type&& x) + constexpr iterator insert(value_type&& x) { return emplace(std::move(x)); } - iterator insert(const_iterator position, const value_type& x) + constexpr iterator insert(const_iterator position, const value_type& x) { return emplace_hint(position, x); } - iterator insert(const_iterator position, value_type&& x) + constexpr iterator insert(const_iterator position, value_type&& x) { return emplace_hint(position, std::move(x)); } template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); template<class InputIterator> - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); template<@\exposconcept{container-compatible-range}@<value_type> R> - void insert_range(R&& rg); + constexpr void insert_range(R&& rg); - void insert(initializer_list<value_type> il) + constexpr void insert(initializer_list<value_type> il) { insert(il.begin(), il.end()); } - void insert(sorted_equivalent_t s, initializer_list<value_type> il) + constexpr void insert(sorted_equivalent_t s, initializer_list<value_type> il) { insert(s, il.begin(), il.end()); } - container_type extract() &&; - void replace(container_type&&); + constexpr container_type extract() &&; + constexpr void replace(container_type&&); - iterator erase(iterator position); - iterator erase(const_iterator position); - size_type erase(const key_type& x); - template<class K> size_type erase(K&& x); - iterator erase(const_iterator first, const_iterator last); + 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); - void swap(flat_multiset& y) noexcept; - void clear() noexcept; + constexpr void swap(flat_multiset& y) noexcept; + constexpr void clear() noexcept; // observers - key_compare key_comp() const; - value_compare value_comp() const; + constexpr key_compare key_comp() const; + constexpr value_compare value_comp() const; // set operations - iterator find(const key_type& x); - const_iterator find(const key_type& x) const; - template<class K> iterator find(const K& x); - template<class K> const_iterator find(const K& x) const; + constexpr 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; - size_type count(const key_type& x) const; - template<class K> size_type count(const K& x) const; + constexpr size_type count(const key_type& x) const; + template<class K> constexpr size_type count(const K& x) const; - bool contains(const key_type& x) const; - template<class K> bool contains(const K& x) const; + constexpr bool contains(const key_type& x) const; + template<class K> constexpr bool contains(const K& x) const; - iterator lower_bound(const key_type& x); - const_iterator lower_bound(const key_type& x) const; - template<class K> iterator lower_bound(const K& x); - template<class K> const_iterator lower_bound(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; - iterator upper_bound(const key_type& x); - const_iterator upper_bound(const key_type& x) const; - template<class K> iterator upper_bound(const K& x); - template<class K> const_iterator upper_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; - pair<iterator, iterator> equal_range(const key_type& x); - pair<const_iterator, const_iterator> equal_range(const key_type& 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> - pair<iterator, iterator> equal_range(const K& x); + constexpr pair<iterator, iterator> equal_range(const K& x); template<class K> - pair<const_iterator, const_iterator> equal_range(const K& x) const; + constexpr pair<const_iterator, const_iterator> equal_range(const K& x) const; - friend bool operator==(const flat_multiset& x, const flat_multiset& y); + constexpr friend bool operator==(const flat_multiset& x, const flat_multiset& y); friend @\placeholder{synth-three-way-result}@<value_type> - operator<=>(const flat_multiset& x, const flat_multiset& y); + constexpr operator<=>(const flat_multiset& x, const flat_multiset& y); - friend void swap(flat_multiset& x, flat_multiset& y) noexcept + constexpr friend void swap(flat_multiset& x, flat_multiset& y) noexcept { x.swap(y); } private: @@ -18563,7 +18646,7 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} -explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); +constexpr explicit flat_multiset(container_type cont, const key_compare& comp = key_compare()); \end{itemdecl} \begin{itemdescr} @@ -18588,9 +18671,9 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template<class Alloc> - flat_multiset(const container_type& cont, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const Alloc& a); template<class Alloc> - flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const container_type& cont, const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18610,10 +18693,10 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template<class Alloc> - flat_multiset(sorted_equivalent_t s, const container_type& cont, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t s, const container_type& cont, const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t s, const container_type& cont, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t s, const container_type& cont, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18632,36 +18715,38 @@ \indexlibraryctor{flat_multiset}% \begin{itemdecl} template<class Alloc> - explicit flat_multiset(const Alloc& a); + constexpr explicit flat_multiset(const Alloc& a); template<class Alloc> - flat_multiset(const key_compare& comp, const Alloc& a); + constexpr flat_multiset(const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multiset(const flat_multiset&, const Alloc& a); + constexpr flat_multiset(const flat_multiset&, const Alloc& a); template<class Alloc> - flat_multiset(flat_multiset&&, const Alloc& a); + constexpr flat_multiset(flat_multiset&&, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const Alloc& a); template<class InputIterator, class Alloc> - flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, InputIterator first, InputIterator last, + const key_compare& comp, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multiset(from_range_t, R&& rg, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const Alloc& a); template<@\exposconcept{container-compatible-range}@<value_type> R, class Alloc> - flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(from_range_t, R&& rg, const key_compare& comp, const Alloc& a); template<class Alloc> - flat_multiset(initializer_list<value_type> il, const Alloc& a); + constexpr flat_multiset(initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multiset(initializer_list<value_type> il, const key_compare& comp, const Alloc& a); + constexpr flat_multiset(initializer_list<value_type> il, const key_compare& comp, + const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, const Alloc& a); template<class Alloc> - flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, - const key_compare& comp, const Alloc& a); + constexpr flat_multiset(sorted_equivalent_t, initializer_list<value_type> il, + const key_compare& comp, const Alloc& a); \end{itemdecl} \begin{itemdescr} @@ -18676,7 +18761,7 @@ \indexlibrarymember{emplace}{flat_multiset}% \begin{itemdecl} -template<class... Args> iterator emplace(Args&&... args); +template<class... Args> constexpr iterator emplace(Args&&... args); \end{itemdecl} \begin{itemdescr} @@ -18702,7 +18787,7 @@ \indexlibrarymember{insert}{flat_multiset}% \begin{itemdecl} template<class InputIterator> - void insert(InputIterator first, InputIterator last); + constexpr void insert(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18729,7 +18814,7 @@ \indexlibrarymember{insert}{flat_multiset}% \begin{itemdecl} template<class InputIterator> - void insert(sorted_equivalent_t, InputIterator first, InputIterator last); + constexpr void insert(sorted_equivalent_t, InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} @@ -18744,7 +18829,7 @@ \indexlibrarymember{swap}{flat_multiset}% \begin{itemdecl} -void swap(flat_multiset& y) noexcept; +constexpr void swap(flat_multiset& y) noexcept; \end{itemdecl} \begin{itemdescr} @@ -18759,7 +18844,7 @@ \indexlibrarymember{extract}{flat_multiset}% \begin{itemdecl} -container_type extract() &&; +constexpr container_type extract() &&; \end{itemdecl} \begin{itemdescr} @@ -18774,7 +18859,7 @@ \indexlibrarymember{replace}{flat_multiset}% \begin{itemdecl} -void replace(container_type&& cont); +constexpr void replace(container_type&& cont); \end{itemdecl} \begin{itemdescr} @@ -18792,7 +18877,7 @@ \indexlibrarymember{erase_if}{flat_multiset}% \begin{itemdecl} template<class Key, class Compare, class KeyContainer, class Predicate> - typename flat_multiset<Key, Compare, KeyContainer>::size_type + constexpr typename flat_multiset<Key, Compare, KeyContainer>::size_type erase_if(flat_multiset<Key, Compare, KeyContainer>& c, Predicate pred); \end{itemdecl} diff --git a/source/support.tex b/source/support.tex index 73b9ba467d..38c5226cb3 100644 --- a/source/support.tex +++ b/source/support.tex @@ -611,18 +611,29 @@ #define @\defnlibxname{cpp_lib_constexpr_charconv}@ 202207L // freestanding, also in \libheader{charconv} #define @\defnlibxname{cpp_lib_constexpr_cmath}@ 202306L // also in \libheader{cmath}, \libheader{cstdlib} #define @\defnlibxname{cpp_lib_constexpr_complex}@ 202306L // also in \libheader{complex} +#define @\defnlibxname{cpp_lib_constexpr_deque}@ 202502L // also in \libheader{deque} #define @\defnlibxname{cpp_lib_constexpr_dynamic_alloc}@ 201907L // also in \libheader{memory} #define @\defnlibxname{cpp_lib_constexpr_exceptions}@ 202411L // also in \libheader{exception} +#define @\defnlibxname{cpp_lib_constexpr_flat_map}@ 202502L // also in \libheader{flat_map} +#define @\defnlibxname{cpp_lib_constexpr_flat_set}@ 202502L // also in \libheader{flat_set} +#define @\defnlibxname{cpp_lib_constexpr_forward_list}@ 202502L // also in \libheader{forward_list} #define @\defnlibxname{cpp_lib_constexpr_functional}@ 201907L // freestanding, also in \libheader{functional} #define @\defnlibxname{cpp_lib_constexpr_inplace_vector}@ 202502L // also in \libheader{inplace_vector} #define @\defnlibxname{cpp_lib_constexpr_iterator}@ 201811L // freestanding, also in \libheader{iterator} +#define @\defnlibxname{cpp_lib_constexpr_list}@ 202502L // also in \libheader{list} +#define @\defnlibxname{cpp_lib_constexpr_map}@ 202502L // also in \libheader{map} #define @\defnlibxname{cpp_lib_constexpr_memory}@ 202202L // freestanding, also in \libheader{memory} #define @\defnlibxname{cpp_lib_constexpr_new}@ 202406L // freestanding, also in \libheader{new} #define @\defnlibxname{cpp_lib_constexpr_numeric}@ 201911L // also in \libheader{numeric} +#define @\defnlibxname{cpp_lib_constexpr_queue}@ 202502L // also in \libheader{queue} +#define @\defnlibxname{cpp_lib_constexpr_set}@ 202502L // also in \libheader{set} +#define @\defnlibxname{cpp_lib_constexpr_stack}@ 202502L // also in \libheader{stack} #define @\defnlibxname{cpp_lib_constexpr_string}@ 201907L // also in \libheader{string} #define @\defnlibxname{cpp_lib_constexpr_string_view}@ 201811L // also in \libheader{string_view} #define @\defnlibxname{cpp_lib_constexpr_tuple}@ 201811L // freestanding, also in \libheader{tuple} #define @\defnlibxname{cpp_lib_constexpr_typeinfo}@ 202106L // freestanding, also in \libheader{typeinfo} +#define @\defnlibxname{cpp_lib_constexpr_unordered_map}@ 202502L // also in \libheader{unordered_map} +#define @\defnlibxname{cpp_lib_constexpr_unordered_set}@ 202502L // also in \libheader{unordered_set} #define @\defnlibxname{cpp_lib_constexpr_utility}@ 201811L // freestanding, also in \libheader{utility} #define @\defnlibxname{cpp_lib_constexpr_vector}@ 201907L // also in \libheader{vector} #define @\defnlibxname{cpp_lib_constrained_equality}@ 202411L // freestanding,