2078 lines · plain
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_MAP11#define _LIBCPP_MAP12 13/*14 15 map synopsis16 17namespace std18{19 20template <class Key, class T, class Compare = less<Key>,21 class Allocator = allocator<pair<const Key, T>>>22class map23{24public:25 // types:26 typedef Key key_type;27 typedef T mapped_type;28 typedef pair<const key_type, mapped_type> value_type;29 typedef Compare key_compare;30 typedef Allocator allocator_type;31 typedef typename allocator_type::reference reference;32 typedef typename allocator_type::const_reference const_reference;33 typedef typename allocator_type::pointer pointer;34 typedef typename allocator_type::const_pointer const_pointer;35 typedef typename allocator_type::size_type size_type;36 typedef typename allocator_type::difference_type difference_type;37 38 typedef implementation-defined iterator;39 typedef implementation-defined const_iterator;40 typedef std::reverse_iterator<iterator> reverse_iterator;41 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;42 typedef unspecified node_type; // C++1743 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++1744 45 class value_compare46 {47 friend class map;48 protected:49 key_compare comp;50 51 value_compare(key_compare c);52 public:53 typedef bool result_type; // deprecated in C++17, removed in C++2054 typedef value_type first_argument_type; // deprecated in C++17, removed in C++2055 typedef value_type second_argument_type; // deprecated in C++17, removed in C++2056 bool operator()(const value_type& x, const value_type& y) const;57 };58 59 // construct/copy/destroy:60 map()61 noexcept(62 is_nothrow_default_constructible<allocator_type>::value &&63 is_nothrow_default_constructible<key_compare>::value &&64 is_nothrow_copy_constructible<key_compare>::value);65 explicit map(const key_compare& comp);66 map(const key_compare& comp, const allocator_type& a);67 template <class InputIterator>68 map(InputIterator first, InputIterator last,69 const key_compare& comp = key_compare());70 template <class InputIterator>71 map(InputIterator first, InputIterator last,72 const key_compare& comp, const allocator_type& a);73 template<container-compatible-range<value_type> R>74 map(from_range_t, R&& rg, const Compare& comp = Compare(), const Allocator& = Allocator()); // C++2375 map(const map& m);76 map(map&& m)77 noexcept(78 is_nothrow_move_constructible<allocator_type>::value &&79 is_nothrow_move_constructible<key_compare>::value);80 explicit map(const allocator_type& a);81 map(const map& m, const allocator_type& a);82 map(map&& m, const allocator_type& a);83 map(initializer_list<value_type> il, const key_compare& comp = key_compare());84 map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a);85 template <class InputIterator>86 map(InputIterator first, InputIterator last, const allocator_type& a)87 : map(first, last, Compare(), a) {} // C++1488 template<container-compatible-range<value_type> R>89 map(from_range_t, R&& rg, const Allocator& a))90 : map(from_range, std::forward<R>(rg), Compare(), a) { } // C++2391 map(initializer_list<value_type> il, const allocator_type& a)92 : map(il, Compare(), a) {} // C++1493 ~map();94 95 map& operator=(const map& m);96 map& operator=(map&& m)97 noexcept(98 allocator_type::propagate_on_container_move_assignment::value &&99 is_nothrow_move_assignable<allocator_type>::value &&100 is_nothrow_move_assignable<key_compare>::value);101 map& operator=(initializer_list<value_type> il);102 103 // iterators:104 iterator begin() noexcept;105 const_iterator begin() const noexcept;106 iterator end() noexcept;107 const_iterator end() const noexcept;108 109 reverse_iterator rbegin() noexcept;110 const_reverse_iterator rbegin() const noexcept;111 reverse_iterator rend() noexcept;112 const_reverse_iterator rend() const noexcept;113 114 const_iterator cbegin() const noexcept;115 const_iterator cend() const noexcept;116 const_reverse_iterator crbegin() const noexcept;117 const_reverse_iterator crend() const noexcept;118 119 // capacity:120 bool empty() const noexcept;121 size_type size() const noexcept;122 size_type max_size() const noexcept;123 124 // element access:125 mapped_type& operator[](const key_type& k);126 mapped_type& operator[](key_type&& k);127 128 mapped_type& at(const key_type& k);129 const mapped_type& at(const key_type& k) const;130 131 // modifiers:132 template <class... Args>133 pair<iterator, bool> emplace(Args&&... args);134 template <class... Args>135 iterator emplace_hint(const_iterator position, Args&&... args);136 pair<iterator, bool> insert(const value_type& v);137 pair<iterator, bool> insert( value_type&& v); // C++17138 template <class P>139 pair<iterator, bool> insert(P&& p);140 iterator insert(const_iterator position, const value_type& v);141 iterator insert(const_iterator position, value_type&& v); // C++17142 template <class P>143 iterator insert(const_iterator position, P&& p);144 template <class InputIterator>145 void insert(InputIterator first, InputIterator last);146 template<container-compatible-range<value_type> R>147 void insert_range(R&& rg); // C++23148 void insert(initializer_list<value_type> il);149 150 node_type extract(const_iterator position); // C++17151 node_type extract(const key_type& x); // C++17152 insert_return_type insert(node_type&& nh); // C++17153 iterator insert(const_iterator hint, node_type&& nh); // C++17154 155 template <class... Args>156 pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17157 template <class... Args>158 pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17159 template <class... Args>160 iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17161 template <class... Args>162 iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17163 template <class M>164 pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17165 template <class M>166 pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17167 template <class M>168 iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17169 template <class M>170 iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17171 172 iterator erase(const_iterator position);173 iterator erase(iterator position); // C++14174 size_type erase(const key_type& k);175 iterator erase(const_iterator first, const_iterator last);176 void clear() noexcept;177 178 template<class C2>179 void merge(map<Key, T, C2, Allocator>& source); // C++17180 template<class C2>181 void merge(map<Key, T, C2, Allocator>&& source); // C++17182 template<class C2>183 void merge(multimap<Key, T, C2, Allocator>& source); // C++17184 template<class C2>185 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17186 187 void swap(map& m)188 noexcept(allocator_traits<allocator_type>::is_always_equal::value &&189 is_nothrow_swappable<key_compare>::value); // C++17190 191 // observers:192 allocator_type get_allocator() const noexcept;193 key_compare key_comp() const;194 value_compare value_comp() const;195 196 // map operations:197 iterator find(const key_type& k);198 const_iterator find(const key_type& k) const;199 template<typename K>200 iterator find(const K& x); // C++14201 template<typename K>202 const_iterator find(const K& x) const; // C++14203 204 template<typename K>205 size_type count(const K& x) const; // C++14206 size_type count(const key_type& k) const;207 208 bool contains(const key_type& x) const; // C++20209 template<class K> bool contains(const K& x) const; // C++20210 211 iterator lower_bound(const key_type& k);212 const_iterator lower_bound(const key_type& k) const;213 template<typename K>214 iterator lower_bound(const K& x); // C++14215 template<typename K>216 const_iterator lower_bound(const K& x) const; // C++14217 218 iterator upper_bound(const key_type& k);219 const_iterator upper_bound(const key_type& k) const;220 template<typename K>221 iterator upper_bound(const K& x); // C++14222 template<typename K>223 const_iterator upper_bound(const K& x) const; // C++14224 225 pair<iterator,iterator> equal_range(const key_type& k);226 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;227 template<typename K>228 pair<iterator,iterator> equal_range(const K& x); // C++14229 template<typename K>230 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14231};232 233template <class InputIterator,234 class Compare = less<iter_key_t<InputIterator>>,235 class Allocator = allocator<iter_to_alloc_t<InputIterator>>>236map(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())237 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17238 239template<ranges::input_range R, class Compare = less<range-key-type<R>,240 class Allocator = allocator<range-to-alloc-type<R>>>241 map(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())242 -> map<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23243 244template<class Key, class T, class Compare = less<Key>,245 class Allocator = allocator<pair<const Key, T>>>246map(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())247 -> map<Key, T, Compare, Allocator>; // C++17248 249template <class InputIterator, class Allocator>250map(InputIterator, InputIterator, Allocator)251 -> map<iter_key_t<InputIterator>, iter_val_t<InputIterator>, less<iter_key_t<InputIterator>>,252 Allocator>; // C++17253 254template<ranges::input_range R, class Allocator>255 map(from_range_t, R&&, Allocator)256 -> map<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23257 258template<class Key, class T, class Allocator>259map(initializer_list<pair<const Key, T>>, Allocator) -> map<Key, T, less<Key>, Allocator>; // C++17260 261template <class Key, class T, class Compare, class Allocator>262bool263operator==(const map<Key, T, Compare, Allocator>& x,264 const map<Key, T, Compare, Allocator>& y);265 266template <class Key, class T, class Compare, class Allocator>267bool268operator< (const map<Key, T, Compare, Allocator>& x,269 const map<Key, T, Compare, Allocator>& y); // removed in C++20270 271template <class Key, class T, class Compare, class Allocator>272bool273operator!=(const map<Key, T, Compare, Allocator>& x,274 const map<Key, T, Compare, Allocator>& y); // removed in C++20275 276template <class Key, class T, class Compare, class Allocator>277bool278operator> (const map<Key, T, Compare, Allocator>& x,279 const map<Key, T, Compare, Allocator>& y); // removed in C++20280 281template <class Key, class T, class Compare, class Allocator>282bool283operator>=(const map<Key, T, Compare, Allocator>& x,284 const map<Key, T, Compare, Allocator>& y); // removed in C++20285 286template <class Key, class T, class Compare, class Allocator>287bool288operator<=(const map<Key, T, Compare, Allocator>& x,289 const map<Key, T, Compare, Allocator>& y); // removed in C++20290 291template<class Key, class T, class Compare, class Allocator>292 synth-three-way-result<pair<const Key, T>>293 operator<=>(const map<Key, T, Compare, Allocator>& x,294 const map<Key, T, Compare, Allocator>& y); // since C++20295 296// specialized algorithms:297template <class Key, class T, class Compare, class Allocator>298void299swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y)300 noexcept(noexcept(x.swap(y)));301 302template <class Key, class T, class Compare, class Allocator, class Predicate>303typename map<Key, T, Compare, Allocator>::size_type304erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20305 306 307template <class Key, class T, class Compare = less<Key>,308 class Allocator = allocator<pair<const Key, T>>>309class multimap310{311public:312 // types:313 typedef Key key_type;314 typedef T mapped_type;315 typedef pair<const key_type,mapped_type> value_type;316 typedef Compare key_compare;317 typedef Allocator allocator_type;318 typedef typename allocator_type::reference reference;319 typedef typename allocator_type::const_reference const_reference;320 typedef typename allocator_type::size_type size_type;321 typedef typename allocator_type::difference_type difference_type;322 typedef typename allocator_type::pointer pointer;323 typedef typename allocator_type::const_pointer const_pointer;324 325 typedef implementation-defined iterator;326 typedef implementation-defined const_iterator;327 typedef std::reverse_iterator<iterator> reverse_iterator;328 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;329 typedef unspecified node_type; // C++17330 331 class value_compare332 {333 friend class multimap;334 protected:335 key_compare comp;336 value_compare(key_compare c);337 public:338 typedef bool result_type; // deprecated in C++17, removed in C++20339 typedef value_type first_argument_type; // deprecated in C++17, removed in C++20340 typedef value_type second_argument_type; // deprecated in C++17, removed in C++20341 bool operator()(const value_type& x, const value_type& y) const;342 };343 344 // construct/copy/destroy:345 multimap()346 noexcept(347 is_nothrow_default_constructible<allocator_type>::value &&348 is_nothrow_default_constructible<key_compare>::value &&349 is_nothrow_copy_constructible<key_compare>::value);350 explicit multimap(const key_compare& comp);351 multimap(const key_compare& comp, const allocator_type& a);352 template <class InputIterator>353 multimap(InputIterator first, InputIterator last, const key_compare& comp);354 template <class InputIterator>355 multimap(InputIterator first, InputIterator last, const key_compare& comp,356 const allocator_type& a);357 template<container-compatible-range<value_type> R>358 multimap(from_range_t, R&& rg,359 const Compare& comp = Compare(), const Allocator& = Allocator()); // C++23360 multimap(const multimap& m);361 multimap(multimap&& m)362 noexcept(363 is_nothrow_move_constructible<allocator_type>::value &&364 is_nothrow_move_constructible<key_compare>::value);365 explicit multimap(const allocator_type& a);366 multimap(const multimap& m, const allocator_type& a);367 multimap(multimap&& m, const allocator_type& a);368 multimap(initializer_list<value_type> il, const key_compare& comp = key_compare());369 multimap(initializer_list<value_type> il, const key_compare& comp,370 const allocator_type& a);371 template <class InputIterator>372 multimap(InputIterator first, InputIterator last, const allocator_type& a)373 : multimap(first, last, Compare(), a) {} // C++14374 template<container-compatible-range<value_type> R>375 multimap(from_range_t, R&& rg, const Allocator& a))376 : multimap(from_range, std::forward<R>(rg), Compare(), a) { } // C++23377 multimap(initializer_list<value_type> il, const allocator_type& a)378 : multimap(il, Compare(), a) {} // C++14379 ~multimap();380 381 multimap& operator=(const multimap& m);382 multimap& operator=(multimap&& m)383 noexcept(384 allocator_type::propagate_on_container_move_assignment::value &&385 is_nothrow_move_assignable<allocator_type>::value &&386 is_nothrow_move_assignable<key_compare>::value);387 multimap& operator=(initializer_list<value_type> il);388 389 // iterators:390 iterator begin() noexcept;391 const_iterator begin() const noexcept;392 iterator end() noexcept;393 const_iterator end() const noexcept;394 395 reverse_iterator rbegin() noexcept;396 const_reverse_iterator rbegin() const noexcept;397 reverse_iterator rend() noexcept;398 const_reverse_iterator rend() const noexcept;399 400 const_iterator cbegin() const noexcept;401 const_iterator cend() const noexcept;402 const_reverse_iterator crbegin() const noexcept;403 const_reverse_iterator crend() const noexcept;404 405 // capacity:406 bool empty() const noexcept;407 size_type size() const noexcept;408 size_type max_size() const noexcept;409 410 // modifiers:411 template <class... Args>412 iterator emplace(Args&&... args);413 template <class... Args>414 iterator emplace_hint(const_iterator position, Args&&... args);415 iterator insert(const value_type& v);416 iterator insert( value_type&& v); // C++17417 template <class P>418 iterator insert(P&& p);419 iterator insert(const_iterator position, const value_type& v);420 iterator insert(const_iterator position, value_type&& v); // C++17421 template <class P>422 iterator insert(const_iterator position, P&& p);423 template <class InputIterator>424 void insert(InputIterator first, InputIterator last);425 template<container-compatible-range<value_type> R>426 void insert_range(R&& rg); // C++23427 void insert(initializer_list<value_type> il);428 429 node_type extract(const_iterator position); // C++17430 node_type extract(const key_type& x); // C++17431 iterator insert(node_type&& nh); // C++17432 iterator insert(const_iterator hint, node_type&& nh); // C++17433 434 iterator erase(const_iterator position);435 iterator erase(iterator position); // C++14436 size_type erase(const key_type& k);437 iterator erase(const_iterator first, const_iterator last);438 void clear() noexcept;439 440 template<class C2>441 void merge(multimap<Key, T, C2, Allocator>& source); // C++17442 template<class C2>443 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17444 template<class C2>445 void merge(map<Key, T, C2, Allocator>& source); // C++17446 template<class C2>447 void merge(map<Key, T, C2, Allocator>&& source); // C++17448 449 void swap(multimap& m)450 noexcept(allocator_traits<allocator_type>::is_always_equal::value &&451 is_nothrow_swappable<key_compare>::value); // C++17452 453 // observers:454 allocator_type get_allocator() const noexcept;455 key_compare key_comp() const;456 value_compare value_comp() const;457 458 // map operations:459 iterator find(const key_type& k);460 const_iterator find(const key_type& k) const;461 template<typename K>462 iterator find(const K& x); // C++14463 template<typename K>464 const_iterator find(const K& x) const; // C++14465 466 template<typename K>467 size_type count(const K& x) const; // C++14468 size_type count(const key_type& k) const;469 470 bool contains(const key_type& x) const; // C++20471 template<class K> bool contains(const K& x) const; // C++20472 473 iterator lower_bound(const key_type& k);474 const_iterator lower_bound(const key_type& k) const;475 template<typename K>476 iterator lower_bound(const K& x); // C++14477 template<typename K>478 const_iterator lower_bound(const K& x) const; // C++14479 480 iterator upper_bound(const key_type& k);481 const_iterator upper_bound(const key_type& k) const;482 template<typename K>483 iterator upper_bound(const K& x); // C++14484 template<typename K>485 const_iterator upper_bound(const K& x) const; // C++14486 487 pair<iterator,iterator> equal_range(const key_type& k);488 pair<const_iterator,const_iterator> equal_range(const key_type& k) const;489 template<typename K>490 pair<iterator,iterator> equal_range(const K& x); // C++14491 template<typename K>492 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14493};494 495template <class InputIterator,496 class Compare = less<iter_key_t<InputIterator>>,497 class Allocator = allocator<iter_to_alloc_t<InputIterator>>>498multimap(InputIterator, InputIterator, Compare = Compare(), Allocator = Allocator())499 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>, Compare, Allocator>; // C++17500 501template<ranges::input_range R, class Compare = less<range-key-type<R>>,502 class Allocator = allocator<range-to-alloc-type<R>>>503 multimap(from_range_t, R&&, Compare = Compare(), Allocator = Allocator())504 -> multimap<range-key-type<R>, range-mapped-type<R>, Compare, Allocator>; // C++23505 506template<class Key, class T, class Compare = less<Key>,507 class Allocator = allocator<pair<const Key, T>>>508multimap(initializer_list<pair<const Key, T>>, Compare = Compare(), Allocator = Allocator())509 -> multimap<Key, T, Compare, Allocator>; // C++17510 511template <class InputIterator, class Allocator>512multimap(InputIterator, InputIterator, Allocator)513 -> multimap<iter_key_t<InputIterator>, iter_val_t<InputIterator>,514 less<iter_key_t<InputIterator>>, Allocator>; // C++17515 516template<ranges::input_range R, class Allocator>517 multimap(from_range_t, R&&, Allocator)518 -> multimap<range-key-type<R>, range-mapped-type<R>, less<range-key-type<R>>, Allocator>; // C++23519 520template<class Key, class T, class Allocator>521multimap(initializer_list<pair<const Key, T>>, Allocator)522 -> multimap<Key, T, less<Key>, Allocator>; // C++17523 524template <class Key, class T, class Compare, class Allocator>525bool526operator==(const multimap<Key, T, Compare, Allocator>& x,527 const multimap<Key, T, Compare, Allocator>& y);528 529template <class Key, class T, class Compare, class Allocator>530bool531operator< (const multimap<Key, T, Compare, Allocator>& x,532 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20533 534template <class Key, class T, class Compare, class Allocator>535bool536operator!=(const multimap<Key, T, Compare, Allocator>& x,537 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20538 539template <class Key, class T, class Compare, class Allocator>540bool541operator> (const multimap<Key, T, Compare, Allocator>& x,542 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20543 544template <class Key, class T, class Compare, class Allocator>545bool546operator>=(const multimap<Key, T, Compare, Allocator>& x,547 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20548 549template <class Key, class T, class Compare, class Allocator>550bool551operator<=(const multimap<Key, T, Compare, Allocator>& x,552 const multimap<Key, T, Compare, Allocator>& y); // removed in C++20553 554template<class Key, class T, class Compare, class Allocator>555 synth-three-way-result<pair<const Key, T>>556 operator<=>(const multimap<Key, T, Compare, Allocator>& x,557 const multimap<Key, T, Compare, Allocator>& y); // since c++20558 559// specialized algorithms:560template <class Key, class T, class Compare, class Allocator>561void562swap(multimap<Key, T, Compare, Allocator>& x,563 multimap<Key, T, Compare, Allocator>& y)564 noexcept(noexcept(x.swap(y)));565 566template <class Key, class T, class Compare, class Allocator, class Predicate>567typename multimap<Key, T, Compare, Allocator>::size_type568erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20569 570} // std571 572*/573 574#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)575# include <__cxx03/map>576#else577# include <__algorithm/equal.h>578# include <__algorithm/lexicographical_compare.h>579# include <__algorithm/lexicographical_compare_three_way.h>580# include <__assert>581# include <__config>582# include <__functional/binary_function.h>583# include <__functional/is_transparent.h>584# include <__functional/operations.h>585# include <__iterator/erase_if_container.h>586# include <__iterator/iterator_traits.h>587# include <__iterator/ranges_iterator_traits.h>588# include <__iterator/reverse_iterator.h>589# include <__memory/addressof.h>590# include <__memory/allocator.h>591# include <__memory/allocator_traits.h>592# include <__memory/compressed_pair.h>593# include <__memory/pointer_traits.h>594# include <__memory/unique_ptr.h>595# include <__memory_resource/polymorphic_allocator.h>596# include <__node_handle>597# include <__ranges/access.h>598# include <__ranges/concepts.h>599# include <__ranges/container_compatible_range.h>600# include <__ranges/from_range.h>601# include <__tree>602# include <__type_traits/container_traits.h>603# include <__type_traits/is_allocator.h>604# include <__type_traits/make_transparent.h>605# include <__type_traits/remove_const.h>606# include <__type_traits/type_identity.h>607# include <__utility/forward.h>608# include <__utility/lazy_synth_three_way_comparator.h>609# include <__utility/pair.h>610# include <__utility/piecewise_construct.h>611# include <__utility/swap.h>612# include <stdexcept>613# include <tuple>614# include <version>615 616// standard-mandated includes617 618// [iterator.range]619# include <__iterator/access.h>620# include <__iterator/data.h>621# include <__iterator/empty.h>622# include <__iterator/reverse_access.h>623# include <__iterator/size.h>624 625// [associative.map.syn]626# include <compare>627# include <initializer_list>628 629# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)630# pragma GCC system_header631# endif632 633_LIBCPP_PUSH_MACROS634# include <__undef_macros>635 636_LIBCPP_BEGIN_NAMESPACE_STD637 638template <class _Key, class _CP, class _Compare>639class __map_value_compare {640 _LIBCPP_COMPRESSED_ELEMENT(_Compare, __comp_);641 642public:643 _LIBCPP_HIDE_FROM_ABI __map_value_compare() _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value)644 : __comp_() {}645 _LIBCPP_HIDE_FROM_ABI __map_value_compare(_Compare __c) _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value)646 : __comp_(__c) {}647 _LIBCPP_HIDE_FROM_ABI const _Compare& key_comp() const _NOEXCEPT { return __comp_; }648 649 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _CP& __y) const { return __comp_(__x.first, __y.first); }650 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _Key& __y) const { return __comp_(__x.first, __y); }651 _LIBCPP_HIDE_FROM_ABI bool operator()(const _Key& __x, const _CP& __y) const { return __comp_(__x, __y.first); }652 _LIBCPP_HIDE_FROM_ABI void swap(__map_value_compare& __y) _NOEXCEPT_(__is_nothrow_swappable_v<_Compare>) {653 using std::swap;654 swap(__comp_, __y.__comp_);655 }656 657# if _LIBCPP_STD_VER >= 14658 template <typename _K2>659 _LIBCPP_HIDE_FROM_ABI bool operator()(const _K2& __x, const _CP& __y) const {660 return __comp_(__x, __y.first);661 }662 663 template <typename _K2>664 _LIBCPP_HIDE_FROM_ABI bool operator()(const _CP& __x, const _K2& __y) const {665 return __comp_(__x.first, __y);666 }667# endif668};669 670template <class _Key, class _MapValueT, class _Compare>671struct __make_transparent<__map_value_compare<_Key, _MapValueT, _Compare> > {672 using type _LIBCPP_NODEBUG = __map_value_compare<_Key, _MapValueT, __make_transparent_t<_Compare> >;673};674 675# if _LIBCPP_STD_VER >= 14676template <class _MapValueT, class _Key, class _Compare>677struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _MapValueT, _MapValueT> {678 __lazy_synth_three_way_comparator<_Compare, _Key, _Key> __comp_;679 680 __lazy_synth_three_way_comparator(681 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)682 : __comp_(__comp.key_comp()) {}683 684 _LIBCPP_HIDE_FROM_ABI auto685 operator()(_LIBCPP_LIFETIMEBOUND const _MapValueT& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {686 return __comp_(__lhs.first, __rhs.first);687 }688};689 690template <class _MapValueT, class _Key, class _TransparentKey, class _Compare>691struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _TransparentKey, _MapValueT> {692 __lazy_synth_three_way_comparator<_Compare, _TransparentKey, _Key> __comp_;693 694 __lazy_synth_three_way_comparator(695 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)696 : __comp_(__comp.key_comp()) {}697 698 _LIBCPP_HIDE_FROM_ABI auto699 operator()(_LIBCPP_LIFETIMEBOUND const _TransparentKey& __lhs, _LIBCPP_LIFETIMEBOUND const _MapValueT& __rhs) const {700 return __comp_(__lhs, __rhs.first);701 }702};703 704template <class _MapValueT, class _Key, class _TransparentKey, class _Compare>705struct __lazy_synth_three_way_comparator<__map_value_compare<_Key, _MapValueT, _Compare>, _MapValueT, _TransparentKey> {706 __lazy_synth_three_way_comparator<_Compare, _Key, _TransparentKey> __comp_;707 708 __lazy_synth_three_way_comparator(709 _LIBCPP_CTOR_LIFETIMEBOUND const __map_value_compare<_Key, _MapValueT, _Compare>& __comp)710 : __comp_(__comp.key_comp()) {}711 712 _LIBCPP_HIDE_FROM_ABI auto713 operator()(_LIBCPP_LIFETIMEBOUND const _MapValueT& __lhs, _LIBCPP_LIFETIMEBOUND const _TransparentKey& __rhs) const {714 return __comp_(__lhs.first, __rhs);715 }716};717# endif // _LIBCPP_STD_VER >= 14718 719template <class _Key, class _CP, class _Compare>720inline _LIBCPP_HIDE_FROM_ABI void721swap(__map_value_compare<_Key, _CP, _Compare>& __x, __map_value_compare<_Key, _CP, _Compare>& __y)722 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {723 __x.swap(__y);724}725 726template <class _Allocator>727class __map_node_destructor {728 typedef _Allocator allocator_type;729 typedef allocator_traits<allocator_type> __alloc_traits;730 731public:732 typedef typename __alloc_traits::pointer pointer;733 734private:735 allocator_type& __na_;736 737public:738 bool __first_constructed;739 bool __second_constructed;740 741 _LIBCPP_HIDE_FROM_ABI explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT742 : __na_(__na),743 __first_constructed(false),744 __second_constructed(false) {}745 746# ifndef _LIBCPP_CXX03_LANG747 _LIBCPP_HIDE_FROM_ABI __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT748 : __na_(__x.__na_),749 __first_constructed(__x.__value_constructed),750 __second_constructed(__x.__value_constructed) {751 __x.__value_constructed = false;752 }753# endif // _LIBCPP_CXX03_LANG754 755 __map_node_destructor& operator=(const __map_node_destructor&) = delete;756 757 _LIBCPP_HIDE_FROM_ABI void operator()(pointer __p) _NOEXCEPT {758 if (__second_constructed)759 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().second));760 if (__first_constructed)761 __alloc_traits::destroy(__na_, std::addressof(__p->__get_value().first));762 if (__p)763 __alloc_traits::deallocate(__na_, __p, 1);764 }765};766 767template <class _Key, class _Tp>768struct __value_type;769 770template <class _TreeIterator>771class __map_iterator {772 _TreeIterator __i_;773 774public:775 using iterator_category = bidirectional_iterator_tag;776 using value_type = typename _TreeIterator::value_type;777 using difference_type = typename _TreeIterator::difference_type;778 using reference = value_type&;779 using pointer = typename _TreeIterator::pointer;780 781 _LIBCPP_HIDE_FROM_ABI __map_iterator() _NOEXCEPT {}782 783 _LIBCPP_HIDE_FROM_ABI __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}784 785 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; }786 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }787 788 _LIBCPP_HIDE_FROM_ABI __map_iterator& operator++() {789 ++__i_;790 return *this;791 }792 _LIBCPP_HIDE_FROM_ABI __map_iterator operator++(int) {793 __map_iterator __t(*this);794 ++(*this);795 return __t;796 }797 798 _LIBCPP_HIDE_FROM_ABI __map_iterator& operator--() {799 --__i_;800 return *this;801 }802 _LIBCPP_HIDE_FROM_ABI __map_iterator operator--(int) {803 __map_iterator __t(*this);804 --(*this);805 return __t;806 }807 808 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_iterator& __x, const __map_iterator& __y) {809 return __x.__i_ == __y.__i_;810 }811 friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_iterator& __x, const __map_iterator& __y) {812 return __x.__i_ != __y.__i_;813 }814 815 template <class, class, class, class>816 friend class map;817 template <class, class, class, class>818 friend class multimap;819 template <class>820 friend class __map_const_iterator;821};822 823template <class _TreeIterator>824class __map_const_iterator {825 _TreeIterator __i_;826 827public:828 using iterator_category = bidirectional_iterator_tag;829 using value_type = typename _TreeIterator::value_type;830 using difference_type = typename _TreeIterator::difference_type;831 using reference = const value_type&;832 using pointer = typename _TreeIterator::pointer;833 834 _LIBCPP_HIDE_FROM_ABI __map_const_iterator() _NOEXCEPT {}835 836 _LIBCPP_HIDE_FROM_ABI __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {}837 _LIBCPP_HIDE_FROM_ABI838 __map_const_iterator(__map_iterator< typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT : __i_(__i.__i_) {}839 840 _LIBCPP_HIDE_FROM_ABI reference operator*() const { return *__i_; }841 _LIBCPP_HIDE_FROM_ABI pointer operator->() const { return pointer_traits<pointer>::pointer_to(*__i_); }842 843 _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator++() {844 ++__i_;845 return *this;846 }847 _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator++(int) {848 __map_const_iterator __t(*this);849 ++(*this);850 return __t;851 }852 853 _LIBCPP_HIDE_FROM_ABI __map_const_iterator& operator--() {854 --__i_;855 return *this;856 }857 _LIBCPP_HIDE_FROM_ABI __map_const_iterator operator--(int) {858 __map_const_iterator __t(*this);859 --(*this);860 return __t;861 }862 863 friend _LIBCPP_HIDE_FROM_ABI bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) {864 return __x.__i_ == __y.__i_;865 }866 friend _LIBCPP_HIDE_FROM_ABI bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) {867 return __x.__i_ != __y.__i_;868 }869 870 template <class, class, class, class>871 friend class map;872 template <class, class, class, class>873 friend class multimap;874 template <class, class, class>875 friend class __tree_const_iterator;876};877 878template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >879class multimap;880 881template <class _Key, class _Tp, class _Compare = less<_Key>, class _Allocator = allocator<pair<const _Key, _Tp> > >882class map {883public:884 // types:885 typedef _Key key_type;886 typedef _Tp mapped_type;887 typedef pair<const key_type, mapped_type> value_type;888 typedef __type_identity_t<_Compare> key_compare;889 typedef __type_identity_t<_Allocator> allocator_type;890 typedef value_type& reference;891 typedef const value_type& const_reference;892 893 static_assert(is_same<typename allocator_type::value_type, value_type>::value,894 "Allocator::value_type must be same type as value_type");895 896 class value_compare : public __binary_function<value_type, value_type, bool> {897 friend class map;898 899 protected:900 key_compare comp;901 902 _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}903 904 public:905 _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {906 return comp(__x.first, __y.first);907 }908 };909 910private:911 typedef std::__value_type<key_type, mapped_type> __value_type;912 typedef __map_value_compare<key_type, value_type, key_compare> __vc;913 typedef __tree<__value_type, __vc, allocator_type> __base;914 typedef typename __base::__node_traits __node_traits;915 typedef allocator_traits<allocator_type> __alloc_traits;916 917 static_assert(__check_valid_allocator<allocator_type>::value, "");918 919 __base __tree_;920 921public:922 typedef typename __alloc_traits::pointer pointer;923 typedef typename __alloc_traits::const_pointer const_pointer;924 typedef typename __alloc_traits::size_type size_type;925 typedef typename __alloc_traits::difference_type difference_type;926 typedef __map_iterator<typename __base::iterator> iterator;927 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;928 typedef std::reverse_iterator<iterator> reverse_iterator;929 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;930 931# if _LIBCPP_STD_VER >= 17932 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;933 typedef __insert_return_type<iterator, node_type> insert_return_type;934# endif935 936 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>937 friend class map;938 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>939 friend class multimap;940 941 _LIBCPP_HIDE_FROM_ABI map() _NOEXCEPT_(942 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&943 is_nothrow_copy_constructible<key_compare>::value)944 : __tree_(__vc(key_compare())) {}945 946 _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp) _NOEXCEPT_(947 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)948 : __tree_(__vc(__comp)) {}949 950 _LIBCPP_HIDE_FROM_ABI explicit map(const key_compare& __comp, const allocator_type& __a)951 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}952 953 template <class _InputIterator>954 _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())955 : __tree_(__vc(__comp)) {956 insert(__f, __l);957 }958 959 template <class _InputIterator>960 _LIBCPP_HIDE_FROM_ABI961 map(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a)962 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {963 insert(__f, __l);964 }965 966# if _LIBCPP_STD_VER >= 23967 template <_ContainerCompatibleRange<value_type> _Range>968 _LIBCPP_HIDE_FROM_ABI969 map(from_range_t,970 _Range&& __range,971 const key_compare& __comp = key_compare(),972 const allocator_type& __a = allocator_type())973 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {974 insert_range(std::forward<_Range>(__range));975 }976# endif977 978# if _LIBCPP_STD_VER >= 14979 template <class _InputIterator>980 _LIBCPP_HIDE_FROM_ABI map(_InputIterator __f, _InputIterator __l, const allocator_type& __a)981 : map(__f, __l, key_compare(), __a) {}982# endif983 984# if _LIBCPP_STD_VER >= 23985 template <_ContainerCompatibleRange<value_type> _Range>986 _LIBCPP_HIDE_FROM_ABI map(from_range_t, _Range&& __range, const allocator_type& __a)987 : map(from_range, std::forward<_Range>(__range), key_compare(), __a) {}988# endif989 990 _LIBCPP_HIDE_FROM_ABI map(const map& __m) = default;991 992 _LIBCPP_HIDE_FROM_ABI map& operator=(const map& __m) = default;993 994# ifndef _LIBCPP_CXX03_LANG995 996 _LIBCPP_HIDE_FROM_ABI map(map&& __m) = default;997 998 _LIBCPP_HIDE_FROM_ABI map(map&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}999 1000 _LIBCPP_HIDE_FROM_ABI map& operator=(map&& __m) = default;1001 1002 _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp = key_compare())1003 : __tree_(__vc(__comp)) {1004 insert(__il.begin(), __il.end());1005 }1006 1007 _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)1008 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {1009 insert(__il.begin(), __il.end());1010 }1011 1012# if _LIBCPP_STD_VER >= 141013 _LIBCPP_HIDE_FROM_ABI map(initializer_list<value_type> __il, const allocator_type& __a)1014 : map(__il, key_compare(), __a) {}1015# endif1016 1017 _LIBCPP_HIDE_FROM_ABI map& operator=(initializer_list<value_type> __il) {1018 __tree_.__assign_unique(__il.begin(), __il.end());1019 return *this;1020 }1021 1022# endif // _LIBCPP_CXX03_LANG1023 1024 _LIBCPP_HIDE_FROM_ABI explicit map(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}1025 1026 _LIBCPP_HIDE_FROM_ABI map(const map& __m, const allocator_type& __alloc) : __tree_(__m.__tree_, __alloc) {}1027 1028 _LIBCPP_HIDE_FROM_ABI ~map() { static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), ""); }1029 1030 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }1031 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }1032 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }1033 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }1034 1035 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }1036 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }1037 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }1038 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }1039 1040 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }1041 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }1042 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }1043 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }1044 1045 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }1046 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }1047 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }1048 1049 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](const key_type& __k);1050# ifndef _LIBCPP_CXX03_LANG1051 _LIBCPP_HIDE_FROM_ABI mapped_type& operator[](key_type&& __k);1052# endif1053 1054 template <class _Arg,1055 __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>1056 _LIBCPP_HIDE_FROM_ABI mapped_type& at(_Arg&& __arg) {1057 auto [_, __child] = __tree_.__find_equal(__arg);1058 if (__child == nullptr)1059 std::__throw_out_of_range("map::at: key not found");1060 return static_cast<__node_pointer>(__child)->__get_value().second;1061 }1062 1063 template <class _Arg,1064 __enable_if_t<__is_transparently_comparable_v<_Compare, key_type, __remove_cvref_t<_Arg> >, int> = 0>1065 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(_Arg&& __arg) const {1066 auto [_, __child] = __tree_.__find_equal(__arg);1067 if (__child == nullptr)1068 std::__throw_out_of_range("map::at: key not found");1069 return static_cast<__node_pointer>(__child)->__get_value().second;1070 }1071 1072 _LIBCPP_HIDE_FROM_ABI mapped_type& at(const key_type& __k);1073 _LIBCPP_HIDE_FROM_ABI const mapped_type& at(const key_type& __k) const;1074 1075 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }1076 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }1077 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }1078 1079# ifndef _LIBCPP_CXX03_LANG1080 template <class... _Args>1081 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> emplace(_Args&&... __args) {1082 return __tree_.__emplace_unique(std::forward<_Args>(__args)...);1083 }1084 1085 template <class... _Args>1086 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {1087 return __tree_.__emplace_hint_unique(__p.__i_, std::forward<_Args>(__args)...).first;1088 }1089 1090 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>1091 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Pp&& __p) {1092 return __tree_.__emplace_unique(std::forward<_Pp>(__p));1093 }1094 1095 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>1096 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {1097 return __tree_.__emplace_hint_unique(__pos.__i_, std::forward<_Pp>(__p)).first;1098 }1099 1100# endif // _LIBCPP_CXX03_LANG1101 1102 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }1103 1104 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {1105 return __tree_.__emplace_hint_unique(__p.__i_, __v).first;1106 }1107 1108# ifndef _LIBCPP_CXX03_LANG1109 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {1110 return __tree_.__emplace_unique(std::move(__v));1111 }1112 1113 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {1114 return __tree_.__emplace_hint_unique(__p.__i_, std::move(__v)).first;1115 }1116 1117 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }1118# endif1119 1120 template <class _InputIterator>1121 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __first, _InputIterator __last) {1122 __tree_.__insert_range_unique(__first, __last);1123 }1124 1125# if _LIBCPP_STD_VER >= 231126 template <_ContainerCompatibleRange<value_type> _Range>1127 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {1128 __tree_.__insert_range_unique(ranges::begin(__range), ranges::end(__range));1129 }1130# endif1131 1132# if _LIBCPP_STD_VER >= 171133 1134 template <class... _Args>1135 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) {1136 return __tree_.__emplace_unique(1137 std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple(std::forward<_Args>(__args)...));1138 }1139 1140 template <class... _Args>1141 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) {1142 return __tree_.__emplace_unique(1143 std::piecewise_construct,1144 std::forward_as_tuple(std::move(__k)),1145 std::forward_as_tuple(std::forward<_Args>(__args)...));1146 }1147 1148 template <class... _Args>1149 _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) {1150 return __tree_1151 .__emplace_hint_unique(1152 __h.__i_,1153 std::piecewise_construct,1154 std::forward_as_tuple(__k),1155 std::forward_as_tuple(std::forward<_Args>(__args)...))1156 .first;1157 }1158 1159 template <class... _Args>1160 _LIBCPP_HIDE_FROM_ABI iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) {1161 return __tree_1162 .__emplace_hint_unique(1163 __h.__i_,1164 std::piecewise_construct,1165 std::forward_as_tuple(std::move(__k)),1166 std::forward_as_tuple(std::forward<_Args>(__args)...))1167 .first;1168 }1169 1170 template <class _Vp>1171 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) {1172 auto __result = __tree_.__emplace_unique(__k, std::forward<_Vp>(__v));1173 auto& [__iter, __inserted] = __result;1174 if (!__inserted)1175 __iter->second = std::forward<_Vp>(__v);1176 return __result;1177 }1178 1179 template <class _Vp>1180 _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) {1181 auto __result = __tree_.__emplace_unique(std::move(__k), std::forward<_Vp>(__v));1182 auto& [__iter, __inserted] = __result;1183 if (!__inserted)1184 __iter->second = std::forward<_Vp>(__v);1185 return __result;1186 }1187 1188 template <class _Vp>1189 _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, const key_type& __k, _Vp&& __v) {1190 auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, __k, std::forward<_Vp>(__v));1191 1192 if (!__inserted)1193 __r->second = std::forward<_Vp>(__v);1194 1195 return __r;1196 }1197 1198 template <class _Vp>1199 _LIBCPP_HIDE_FROM_ABI iterator insert_or_assign(const_iterator __h, key_type&& __k, _Vp&& __v) {1200 auto [__r, __inserted] = __tree_.__emplace_hint_unique(__h.__i_, std::move(__k), std::forward<_Vp>(__v));1201 1202 if (!__inserted)1203 __r->second = std::forward<_Vp>(__v);1204 1205 return __r;1206 }1207 1208# endif // _LIBCPP_STD_VER >= 171209 1210 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }1211 _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }1212 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_unique(__k); }1213 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {1214 return __tree_.erase(__f.__i_, __l.__i_);1215 }1216 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }1217 1218# if _LIBCPP_STD_VER >= 171219 _LIBCPP_HIDE_FROM_ABI insert_return_type insert(node_type&& __nh) {1220 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),1221 "node_type with incompatible allocator passed to map::insert()");1222 return __tree_.template __node_handle_insert_unique< node_type, insert_return_type>(std::move(__nh));1223 }1224 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {1225 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),1226 "node_type with incompatible allocator passed to map::insert()");1227 return __tree_.template __node_handle_insert_unique<node_type>(__hint.__i_, std::move(__nh));1228 }1229 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {1230 return __tree_.template __node_handle_extract<node_type>(__key);1231 }1232 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {1233 return __tree_.template __node_handle_extract<node_type>(__it.__i_);1234 }1235 template <class _Compare2>1236 _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {1237 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1238 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1239 __tree_.__node_handle_merge_unique(__source.__tree_);1240 }1241 template <class _Compare2>1242 _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {1243 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1244 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1245 __tree_.__node_handle_merge_unique(__source.__tree_);1246 }1247 template <class _Compare2>1248 _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {1249 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1250 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1251 __tree_.__node_handle_merge_unique(__source.__tree_);1252 }1253 template <class _Compare2>1254 _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {1255 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1256 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1257 __tree_.__node_handle_merge_unique(__source.__tree_);1258 }1259# endif1260 1261 _LIBCPP_HIDE_FROM_ABI void swap(map& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) { __tree_.swap(__m.__tree_); }1262 1263 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }1264 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }1265# if _LIBCPP_STD_VER >= 141266 template <typename _K2,1267 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1268 int> = 0>1269 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {1270 return __tree_.find(__k);1271 }1272 template <typename _K2,1273 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1274 int> = 0>1275 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {1276 return __tree_.find(__k);1277 }1278# endif1279 1280 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_unique(__k); }1281# if _LIBCPP_STD_VER >= 141282 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1283 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {1284 return __tree_.__count_multi(__k);1285 }1286# endif1287 1288# if _LIBCPP_STD_VER >= 201289 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }1290 template <typename _K2,1291 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1292 int> = 0>1293 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {1294 return find(__k) != end();1295 }1296# endif // _LIBCPP_STD_VER >= 201297 1298 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.__lower_bound_unique(__k); }1299 1300 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {1301 return __tree_.__lower_bound_unique(__k);1302 }1303 1304 // The transparent versions of the lookup functions use the _multi version, since a non-element key is allowed to1305 // match multiple elements.1306# if _LIBCPP_STD_VER >= 141307 template <typename _K2,1308 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1309 int> = 0>1310 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {1311 return __tree_.__lower_bound_multi(__k);1312 }1313 1314 template <typename _K2,1315 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1316 int> = 0>1317 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {1318 return __tree_.__lower_bound_multi(__k);1319 }1320# endif1321 1322 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.__upper_bound_unique(__k); }1323 1324 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {1325 return __tree_.__upper_bound_unique(__k);1326 }1327 1328# if _LIBCPP_STD_VER >= 141329 template <typename _K2,1330 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1331 int> = 0>1332 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {1333 return __tree_.__upper_bound_multi(__k);1334 }1335 template <typename _K2,1336 enable_if_t<__is_transparent_v<_Compare, _K2> || __is_transparently_comparable_v<_Compare, key_type, _K2>,1337 int> = 0>1338 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {1339 return __tree_.__upper_bound_multi(__k);1340 }1341# endif1342 1343 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {1344 return __tree_.__equal_range_unique(__k);1345 }1346 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {1347 return __tree_.__equal_range_unique(__k);1348 }1349# if _LIBCPP_STD_VER >= 141350 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1351 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {1352 return __tree_.__equal_range_multi(__k);1353 }1354 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1355 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {1356 return __tree_.__equal_range_multi(__k);1357 }1358# endif1359 1360private:1361 typedef typename __base::__node __node;1362 typedef typename __base::__node_allocator __node_allocator;1363 typedef typename __base::__node_pointer __node_pointer;1364 typedef typename __base::__node_base_pointer __node_base_pointer;1365 typedef typename __base::__parent_pointer __parent_pointer;1366 1367 typedef __map_node_destructor<__node_allocator> _Dp;1368 typedef unique_ptr<__node, _Dp> __node_holder;1369 1370# ifdef _LIBCPP_CXX03_LANG1371 _LIBCPP_HIDE_FROM_ABI __node_holder __construct_node_with_key(const key_type& __k);1372# endif1373};1374 1375# if _LIBCPP_STD_VER >= 171376template <class _InputIterator,1377 class _Compare = less<__iter_key_type<_InputIterator>>,1378 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,1379 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,1380 class = enable_if_t<!__is_allocator_v<_Compare>>,1381 class = enable_if_t<__is_allocator_v<_Allocator>>>1382map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())1383 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;1384 1385# if _LIBCPP_STD_VER >= 231386template <ranges::input_range _Range,1387 class _Compare = less<__range_key_type<_Range>>,1388 class _Allocator = allocator<__range_to_alloc_type<_Range>>,1389 class = enable_if_t<!__is_allocator_v<_Compare>>,1390 class = enable_if_t<__is_allocator_v<_Allocator>>>1391map(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())1392 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;1393# endif1394 1395template <class _Key,1396 class _Tp,1397 class _Compare = less<remove_const_t<_Key>>,1398 class _Allocator = allocator<pair<const _Key, _Tp>>,1399 class = enable_if_t<!__is_allocator_v<_Compare>>,1400 class = enable_if_t<__is_allocator_v<_Allocator>>>1401map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())1402 -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;1403 1404template <class _InputIterator,1405 class _Allocator,1406 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,1407 class = enable_if_t<__is_allocator_v<_Allocator>>>1408map(_InputIterator, _InputIterator, _Allocator)1409 -> map<__iter_key_type<_InputIterator>,1410 __iter_mapped_type<_InputIterator>,1411 less<__iter_key_type<_InputIterator>>,1412 _Allocator>;1413 1414# if _LIBCPP_STD_VER >= 231415template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>1416map(from_range_t, _Range&&, _Allocator)1417 -> map<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;1418# endif1419 1420template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>1421map(initializer_list<pair<_Key, _Tp>>, _Allocator)1422 -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;1423# endif1424 1425# ifndef _LIBCPP_CXX03_LANG1426template <class _Key, class _Tp, class _Compare, class _Allocator>1427_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {1428 return __tree_.__emplace_unique(std::piecewise_construct, std::forward_as_tuple(__k), std::forward_as_tuple())1429 .first->second;1430}1431 1432template <class _Key, class _Tp, class _Compare, class _Allocator>1433_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) {1434 return __tree_1435 .__emplace_unique(std::piecewise_construct, std::forward_as_tuple(std::move(__k)), std::forward_as_tuple())1436 .first->second;1437}1438 1439# else // _LIBCPP_CXX03_LANG1440 1441template <class _Key, class _Tp, class _Compare, class _Allocator>1442typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder1443map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) {1444 __node_allocator& __na = __tree_.__node_alloc();1445 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));1446 __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);1447 __h.get_deleter().__first_constructed = true;1448 __node_traits::construct(__na, std::addressof(__h->__get_value().second));1449 __h.get_deleter().__second_constructed = true;1450 return __h;1451}1452 1453template <class _Key, class _Tp, class _Compare, class _Allocator>1454_Tp& map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) {1455 auto [__parent, __child] = __tree_.__find_equal(__k);1456 __node_pointer __r = static_cast<__node_pointer>(__child);1457 if (__child == nullptr) {1458 __node_holder __h = __construct_node_with_key(__k);1459 __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));1460 __r = __h.release();1461 }1462 return __r->__get_value().second;1463}1464 1465# endif // _LIBCPP_CXX03_LANG1466 1467template <class _Key, class _Tp, class _Compare, class _Allocator>1468_Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) {1469 auto [_, __child] = __tree_.__find_equal(__k);1470 if (__child == nullptr)1471 std::__throw_out_of_range("map::at: key not found");1472 return static_cast<__node_pointer>(__child)->__get_value().second;1473}1474 1475template <class _Key, class _Tp, class _Compare, class _Allocator>1476const _Tp& map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const {1477 auto [_, __child] = __tree_.__find_equal(__k);1478 if (__child == nullptr)1479 std::__throw_out_of_range("map::at: key not found");1480 return static_cast<__node_pointer>(__child)->__get_value().second;1481}1482 1483template <class _Key, class _Tp, class _Compare, class _Allocator>1484inline _LIBCPP_HIDE_FROM_ABI bool1485operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1486 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());1487}1488 1489# if _LIBCPP_STD_VER <= 171490 1491template <class _Key, class _Tp, class _Compare, class _Allocator>1492inline _LIBCPP_HIDE_FROM_ABI bool1493operator<(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1494 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());1495}1496 1497template <class _Key, class _Tp, class _Compare, class _Allocator>1498inline _LIBCPP_HIDE_FROM_ABI bool1499operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1500 return !(__x == __y);1501}1502 1503template <class _Key, class _Tp, class _Compare, class _Allocator>1504inline _LIBCPP_HIDE_FROM_ABI bool1505operator>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1506 return __y < __x;1507}1508 1509template <class _Key, class _Tp, class _Compare, class _Allocator>1510inline _LIBCPP_HIDE_FROM_ABI bool1511operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1512 return !(__x < __y);1513}1514 1515template <class _Key, class _Tp, class _Compare, class _Allocator>1516inline _LIBCPP_HIDE_FROM_ABI bool1517operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1518 return !(__y < __x);1519}1520 1521# else // #if _LIBCPP_STD_VER <= 171522 1523template <class _Key, class _Tp, class _Compare, class _Allocator>1524_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>1525operator<=>(const map<_Key, _Tp, _Compare, _Allocator>& __x, const map<_Key, _Tp, _Compare, _Allocator>& __y) {1526 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way);1527}1528 1529# endif // #if _LIBCPP_STD_VER <= 171530 1531template <class _Key, class _Tp, class _Compare, class _Allocator>1532inline _LIBCPP_HIDE_FROM_ABI void1533swap(map<_Key, _Tp, _Compare, _Allocator>& __x, map<_Key, _Tp, _Compare, _Allocator>& __y)1534 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {1535 __x.swap(__y);1536}1537 1538# if _LIBCPP_STD_VER >= 201539template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>1540inline _LIBCPP_HIDE_FROM_ABI typename map<_Key, _Tp, _Compare, _Allocator>::size_type1541erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {1542 return std::__libcpp_erase_if_container(__c, __pred);1543}1544# endif1545 1546template <class _Key, class _Tp, class _Compare, class _Allocator>1547struct __container_traits<map<_Key, _Tp, _Compare, _Allocator> > {1548 // http://eel.is/c++draft/associative.reqmts.except#21549 // For associative containers, if an exception is thrown by any operation from within1550 // an insert or emplace function inserting a single element, the insertion has no effect.1551 static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;1552 1553 static _LIBCPP_CONSTEXPR const bool __reservable = false;1554};1555 1556template <class _Key, class _Tp, class _Compare, class _Allocator>1557class multimap {1558public:1559 // types:1560 typedef _Key key_type;1561 typedef _Tp mapped_type;1562 typedef pair<const key_type, mapped_type> value_type;1563 typedef __type_identity_t<_Compare> key_compare;1564 typedef __type_identity_t<_Allocator> allocator_type;1565 typedef value_type& reference;1566 typedef const value_type& const_reference;1567 1568 static_assert(__check_valid_allocator<allocator_type>::value, "");1569 static_assert(is_same<typename allocator_type::value_type, value_type>::value,1570 "Allocator::value_type must be same type as value_type");1571 1572 class value_compare : public __binary_function<value_type, value_type, bool> {1573 friend class multimap;1574 1575 protected:1576 key_compare comp;1577 1578 _LIBCPP_HIDE_FROM_ABI value_compare(key_compare __c) : comp(__c) {}1579 1580 public:1581 _LIBCPP_HIDE_FROM_ABI bool operator()(const value_type& __x, const value_type& __y) const {1582 return comp(__x.first, __y.first);1583 }1584 };1585 1586private:1587 typedef std::__value_type<key_type, mapped_type> __value_type;1588 typedef __map_value_compare<key_type, value_type, key_compare> __vc;1589 typedef __tree<__value_type, __vc, allocator_type> __base;1590 typedef typename __base::__node_traits __node_traits;1591 typedef allocator_traits<allocator_type> __alloc_traits;1592 1593 __base __tree_;1594 1595public:1596 typedef typename __alloc_traits::pointer pointer;1597 typedef typename __alloc_traits::const_pointer const_pointer;1598 typedef typename __alloc_traits::size_type size_type;1599 typedef typename __alloc_traits::difference_type difference_type;1600 typedef __map_iterator<typename __base::iterator> iterator;1601 typedef __map_const_iterator<typename __base::const_iterator> const_iterator;1602 typedef std::reverse_iterator<iterator> reverse_iterator;1603 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;1604 1605# if _LIBCPP_STD_VER >= 171606 typedef __map_node_handle<typename __base::__node, allocator_type> node_type;1607# endif1608 1609 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>1610 friend class map;1611 template <class _Key2, class _Value2, class _Comp2, class _Alloc2>1612 friend class multimap;1613 1614 _LIBCPP_HIDE_FROM_ABI multimap() _NOEXCEPT_(1615 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_default_constructible<key_compare>::value&&1616 is_nothrow_copy_constructible<key_compare>::value)1617 : __tree_(__vc(key_compare())) {}1618 1619 _LIBCPP_HIDE_FROM_ABI explicit multimap(const key_compare& __comp) _NOEXCEPT_(1620 is_nothrow_default_constructible<allocator_type>::value&& is_nothrow_copy_constructible<key_compare>::value)1621 : __tree_(__vc(__comp)) {}1622 1623 _LIBCPP_HIDE_FROM_ABI explicit multimap(const key_compare& __comp, const allocator_type& __a)1624 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {}1625 1626 template <class _InputIterator>1627 _LIBCPP_HIDE_FROM_ABI multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp = key_compare())1628 : __tree_(__vc(__comp)) {1629 insert(__f, __l);1630 }1631 1632 template <class _InputIterator>1633 _LIBCPP_HIDE_FROM_ABI1634 multimap(_InputIterator __f, _InputIterator __l, const key_compare& __comp, const allocator_type& __a)1635 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {1636 insert(__f, __l);1637 }1638 1639# if _LIBCPP_STD_VER >= 231640 template <_ContainerCompatibleRange<value_type> _Range>1641 _LIBCPP_HIDE_FROM_ABI1642 multimap(from_range_t,1643 _Range&& __range,1644 const key_compare& __comp = key_compare(),1645 const allocator_type& __a = allocator_type())1646 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {1647 insert_range(std::forward<_Range>(__range));1648 }1649# endif1650 1651# if _LIBCPP_STD_VER >= 141652 template <class _InputIterator>1653 _LIBCPP_HIDE_FROM_ABI multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a)1654 : multimap(__f, __l, key_compare(), __a) {}1655# endif1656 1657# if _LIBCPP_STD_VER >= 231658 template <_ContainerCompatibleRange<value_type> _Range>1659 _LIBCPP_HIDE_FROM_ABI multimap(from_range_t, _Range&& __range, const allocator_type& __a)1660 : multimap(from_range, std::forward<_Range>(__range), key_compare(), __a) {}1661# endif1662 1663 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m) = default;1664 1665 _LIBCPP_HIDE_FROM_ABI multimap& operator=(const multimap& __m) = default;1666 1667# ifndef _LIBCPP_CXX03_LANG1668 1669 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m) = default;1670 1671 _LIBCPP_HIDE_FROM_ABI multimap(multimap&& __m, const allocator_type& __a) : __tree_(std::move(__m.__tree_), __a) {}1672 1673 _LIBCPP_HIDE_FROM_ABI multimap& operator=(multimap&& __m) = default;1674 1675 _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare())1676 : __tree_(__vc(__comp)) {1677 insert(__il.begin(), __il.end());1678 }1679 1680 _LIBCPP_HIDE_FROM_ABI1681 multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)1682 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {1683 insert(__il.begin(), __il.end());1684 }1685 1686# if _LIBCPP_STD_VER >= 141687 _LIBCPP_HIDE_FROM_ABI multimap(initializer_list<value_type> __il, const allocator_type& __a)1688 : multimap(__il, key_compare(), __a) {}1689# endif1690 1691 _LIBCPP_HIDE_FROM_ABI multimap& operator=(initializer_list<value_type> __il) {1692 __tree_.__assign_multi(__il.begin(), __il.end());1693 return *this;1694 }1695 1696# endif // _LIBCPP_CXX03_LANG1697 1698 _LIBCPP_HIDE_FROM_ABI explicit multimap(const allocator_type& __a) : __tree_(typename __base::allocator_type(__a)) {}1699 1700 _LIBCPP_HIDE_FROM_ABI multimap(const multimap& __m, const allocator_type& __a) : __tree_(__m.__tree_, __a) {}1701 1702 _LIBCPP_HIDE_FROM_ABI ~multimap() {1703 static_assert(sizeof(std::__diagnose_non_const_comparator<_Key, _Compare>()), "");1704 }1705 1706 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __tree_.begin(); }1707 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __tree_.begin(); }1708 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __tree_.end(); }1709 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __tree_.end(); }1710 1711 _LIBCPP_HIDE_FROM_ABI reverse_iterator rbegin() _NOEXCEPT { return reverse_iterator(end()); }1712 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rbegin() const _NOEXCEPT { return const_reverse_iterator(end()); }1713 _LIBCPP_HIDE_FROM_ABI reverse_iterator rend() _NOEXCEPT { return reverse_iterator(begin()); }1714 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator rend() const _NOEXCEPT { return const_reverse_iterator(begin()); }1715 1716 _LIBCPP_HIDE_FROM_ABI const_iterator cbegin() const _NOEXCEPT { return begin(); }1717 _LIBCPP_HIDE_FROM_ABI const_iterator cend() const _NOEXCEPT { return end(); }1718 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crbegin() const _NOEXCEPT { return rbegin(); }1719 _LIBCPP_HIDE_FROM_ABI const_reverse_iterator crend() const _NOEXCEPT { return rend(); }1720 1721 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool empty() const _NOEXCEPT { return __tree_.size() == 0; }1722 _LIBCPP_HIDE_FROM_ABI size_type size() const _NOEXCEPT { return __tree_.size(); }1723 _LIBCPP_HIDE_FROM_ABI size_type max_size() const _NOEXCEPT { return __tree_.max_size(); }1724 1725 _LIBCPP_HIDE_FROM_ABI allocator_type get_allocator() const _NOEXCEPT { return allocator_type(__tree_.__alloc()); }1726 _LIBCPP_HIDE_FROM_ABI key_compare key_comp() const { return __tree_.value_comp().key_comp(); }1727 _LIBCPP_HIDE_FROM_ABI value_compare value_comp() const { return value_compare(__tree_.value_comp().key_comp()); }1728 1729# ifndef _LIBCPP_CXX03_LANG1730 1731 template <class... _Args>1732 _LIBCPP_HIDE_FROM_ABI iterator emplace(_Args&&... __args) {1733 return __tree_.__emplace_multi(std::forward<_Args>(__args)...);1734 }1735 1736 template <class... _Args>1737 _LIBCPP_HIDE_FROM_ABI iterator emplace_hint(const_iterator __p, _Args&&... __args) {1738 return __tree_.__emplace_hint_multi(__p.__i_, std::forward<_Args>(__args)...);1739 }1740 1741 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>1742 _LIBCPP_HIDE_FROM_ABI iterator insert(_Pp&& __p) {1743 return __tree_.__emplace_multi(std::forward<_Pp>(__p));1744 }1745 1746 template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>1747 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {1748 return __tree_.__emplace_hint_multi(__pos.__i_, std::forward<_Pp>(__p));1749 }1750 1751 _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__emplace_multi(std::move(__v)); }1752 1753 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {1754 return __tree_.__emplace_hint_multi(__p.__i_, std::move(__v));1755 }1756 1757 _LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }1758 1759# endif // _LIBCPP_CXX03_LANG1760 1761 _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__emplace_multi(__v); }1762 1763 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {1764 return __tree_.__emplace_hint_multi(__p.__i_, __v);1765 }1766 1767 template <class _InputIterator>1768 _LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {1769 __tree_.__insert_range_multi(__f, __l);1770 }1771 1772# if _LIBCPP_STD_VER >= 231773 template <_ContainerCompatibleRange<value_type> _Range>1774 _LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {1775 __tree_.__insert_range_multi(ranges::begin(__range), ranges::end(__range));1776 }1777# endif1778 1779 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __p) { return __tree_.erase(__p.__i_); }1780 _LIBCPP_HIDE_FROM_ABI iterator erase(iterator __p) { return __tree_.erase(__p.__i_); }1781 _LIBCPP_HIDE_FROM_ABI size_type erase(const key_type& __k) { return __tree_.__erase_multi(__k); }1782 _LIBCPP_HIDE_FROM_ABI iterator erase(const_iterator __f, const_iterator __l) {1783 return __tree_.erase(__f.__i_, __l.__i_);1784 }1785 1786# if _LIBCPP_STD_VER >= 171787 _LIBCPP_HIDE_FROM_ABI iterator insert(node_type&& __nh) {1788 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),1789 "node_type with incompatible allocator passed to multimap::insert()");1790 return __tree_.template __node_handle_insert_multi<node_type>(std::move(__nh));1791 }1792 _LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __hint, node_type&& __nh) {1793 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(__nh.empty() || __nh.get_allocator() == get_allocator(),1794 "node_type with incompatible allocator passed to multimap::insert()");1795 return __tree_.template __node_handle_insert_multi<node_type>(__hint.__i_, std::move(__nh));1796 }1797 _LIBCPP_HIDE_FROM_ABI node_type extract(key_type const& __key) {1798 return __tree_.template __node_handle_extract<node_type>(__key);1799 }1800 _LIBCPP_HIDE_FROM_ABI node_type extract(const_iterator __it) {1801 return __tree_.template __node_handle_extract<node_type>(__it.__i_);1802 }1803 template <class _Compare2>1804 _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) {1805 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1806 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1807 return __tree_.__node_handle_merge_multi(__source.__tree_);1808 }1809 template <class _Compare2>1810 _LIBCPP_HIDE_FROM_ABI void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) {1811 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1812 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1813 return __tree_.__node_handle_merge_multi(__source.__tree_);1814 }1815 template <class _Compare2>1816 _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) {1817 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1818 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1819 return __tree_.__node_handle_merge_multi(__source.__tree_);1820 }1821 template <class _Compare2>1822 _LIBCPP_HIDE_FROM_ABI void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) {1823 _LIBCPP_ASSERT_COMPATIBLE_ALLOCATOR(1824 __source.get_allocator() == get_allocator(), "merging container with incompatible allocator");1825 return __tree_.__node_handle_merge_multi(__source.__tree_);1826 }1827# endif1828 1829 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __tree_.clear(); }1830 1831 _LIBCPP_HIDE_FROM_ABI void swap(multimap& __m) _NOEXCEPT_(__is_nothrow_swappable_v<__base>) {1832 __tree_.swap(__m.__tree_);1833 }1834 1835 _LIBCPP_HIDE_FROM_ABI iterator find(const key_type& __k) { return __tree_.find(__k); }1836 _LIBCPP_HIDE_FROM_ABI const_iterator find(const key_type& __k) const { return __tree_.find(__k); }1837# if _LIBCPP_STD_VER >= 141838 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1839 _LIBCPP_HIDE_FROM_ABI iterator find(const _K2& __k) {1840 return __tree_.find(__k);1841 }1842 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1843 _LIBCPP_HIDE_FROM_ABI const_iterator find(const _K2& __k) const {1844 return __tree_.find(__k);1845 }1846# endif1847 1848 _LIBCPP_HIDE_FROM_ABI size_type count(const key_type& __k) const { return __tree_.__count_multi(__k); }1849# if _LIBCPP_STD_VER >= 141850 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1851 _LIBCPP_HIDE_FROM_ABI size_type count(const _K2& __k) const {1852 return __tree_.__count_multi(__k);1853 }1854# endif1855 1856# if _LIBCPP_STD_VER >= 201857 _LIBCPP_HIDE_FROM_ABI bool contains(const key_type& __k) const { return find(__k) != end(); }1858 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1859 _LIBCPP_HIDE_FROM_ABI bool contains(const _K2& __k) const {1860 return find(__k) != end();1861 }1862# endif // _LIBCPP_STD_VER >= 201863 1864 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const key_type& __k) { return __tree_.__lower_bound_multi(__k); }1865 1866 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const key_type& __k) const {1867 return __tree_.__lower_bound_multi(__k);1868 }1869 1870# if _LIBCPP_STD_VER >= 141871 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1872 _LIBCPP_HIDE_FROM_ABI iterator lower_bound(const _K2& __k) {1873 return __tree_.__lower_bound_multi(__k);1874 }1875 1876 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1877 _LIBCPP_HIDE_FROM_ABI const_iterator lower_bound(const _K2& __k) const {1878 return __tree_.__lower_bound_multi(__k);1879 }1880# endif1881 1882 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const key_type& __k) { return __tree_.__upper_bound_multi(__k); }1883 1884 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const key_type& __k) const {1885 return __tree_.__upper_bound_multi(__k);1886 }1887 1888# if _LIBCPP_STD_VER >= 141889 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1890 _LIBCPP_HIDE_FROM_ABI iterator upper_bound(const _K2& __k) {1891 return __tree_.__upper_bound_multi(__k);1892 }1893 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1894 _LIBCPP_HIDE_FROM_ABI const_iterator upper_bound(const _K2& __k) const {1895 return __tree_.__upper_bound_multi(__k);1896 }1897# endif1898 1899 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const key_type& __k) {1900 return __tree_.__equal_range_multi(__k);1901 }1902 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const key_type& __k) const {1903 return __tree_.__equal_range_multi(__k);1904 }1905# if _LIBCPP_STD_VER >= 141906 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1907 _LIBCPP_HIDE_FROM_ABI pair<iterator, iterator> equal_range(const _K2& __k) {1908 return __tree_.__equal_range_multi(__k);1909 }1910 template <typename _K2, enable_if_t<__is_transparent_v<_Compare, _K2>, int> = 0>1911 _LIBCPP_HIDE_FROM_ABI pair<const_iterator, const_iterator> equal_range(const _K2& __k) const {1912 return __tree_.__equal_range_multi(__k);1913 }1914# endif1915 1916private:1917 typedef typename __base::__node __node;1918 typedef typename __base::__node_allocator __node_allocator;1919 typedef typename __base::__node_pointer __node_pointer;1920 1921 typedef __map_node_destructor<__node_allocator> _Dp;1922 typedef unique_ptr<__node, _Dp> __node_holder;1923};1924 1925# if _LIBCPP_STD_VER >= 171926template <class _InputIterator,1927 class _Compare = less<__iter_key_type<_InputIterator>>,1928 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>,1929 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,1930 class = enable_if_t<!__is_allocator_v<_Compare>>,1931 class = enable_if_t<__is_allocator_v<_Allocator>>>1932multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator())1933 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>;1934 1935# if _LIBCPP_STD_VER >= 231936template <ranges::input_range _Range,1937 class _Compare = less<__range_key_type<_Range>>,1938 class _Allocator = allocator<__range_to_alloc_type<_Range>>,1939 class = enable_if_t<!__is_allocator_v<_Compare>>,1940 class = enable_if_t<__is_allocator_v<_Allocator>>>1941multimap(from_range_t, _Range&&, _Compare = _Compare(), _Allocator = _Allocator())1942 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, _Compare, _Allocator>;1943# endif1944 1945template <class _Key,1946 class _Tp,1947 class _Compare = less<remove_const_t<_Key>>,1948 class _Allocator = allocator<pair<const _Key, _Tp>>,1949 class = enable_if_t<!__is_allocator_v<_Compare>>,1950 class = enable_if_t<__is_allocator_v<_Allocator>>>1951multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator())1952 -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>;1953 1954template <class _InputIterator,1955 class _Allocator,1956 class = enable_if_t<__has_input_iterator_category<_InputIterator>::value, void>,1957 class = enable_if_t<__is_allocator_v<_Allocator>>>1958multimap(_InputIterator, _InputIterator, _Allocator)1959 -> multimap<__iter_key_type<_InputIterator>,1960 __iter_mapped_type<_InputIterator>,1961 less<__iter_key_type<_InputIterator>>,1962 _Allocator>;1963 1964# if _LIBCPP_STD_VER >= 231965template <ranges::input_range _Range, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>1966multimap(from_range_t, _Range&&, _Allocator)1967 -> multimap<__range_key_type<_Range>, __range_mapped_type<_Range>, less<__range_key_type<_Range>>, _Allocator>;1968# endif1969 1970template <class _Key, class _Tp, class _Allocator, class = enable_if_t<__is_allocator_v<_Allocator>>>1971multimap(initializer_list<pair<_Key, _Tp>>, _Allocator)1972 -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>;1973# endif1974 1975template <class _Key, class _Tp, class _Compare, class _Allocator>1976inline _LIBCPP_HIDE_FROM_ABI bool1977operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {1978 return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());1979}1980 1981# if _LIBCPP_STD_VER <= 171982 1983template <class _Key, class _Tp, class _Compare, class _Allocator>1984inline _LIBCPP_HIDE_FROM_ABI bool1985operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {1986 return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());1987}1988 1989template <class _Key, class _Tp, class _Compare, class _Allocator>1990inline _LIBCPP_HIDE_FROM_ABI bool1991operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {1992 return !(__x == __y);1993}1994 1995template <class _Key, class _Tp, class _Compare, class _Allocator>1996inline _LIBCPP_HIDE_FROM_ABI bool1997operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {1998 return __y < __x;1999}2000 2001template <class _Key, class _Tp, class _Compare, class _Allocator>2002inline _LIBCPP_HIDE_FROM_ABI bool2003operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {2004 return !(__x < __y);2005}2006 2007template <class _Key, class _Tp, class _Compare, class _Allocator>2008inline _LIBCPP_HIDE_FROM_ABI bool2009operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {2010 return !(__y < __x);2011}2012 2013# else // #if _LIBCPP_STD_VER <= 172014 2015template <class _Key, class _Tp, class _Compare, class _Allocator>2016_LIBCPP_HIDE_FROM_ABI __synth_three_way_result<pair<const _Key, _Tp>>2017operator<=>(const multimap<_Key, _Tp, _Compare, _Allocator>& __x,2018 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) {2019 return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), __synth_three_way);2020}2021 2022# endif // #if _LIBCPP_STD_VER <= 172023 2024template <class _Key, class _Tp, class _Compare, class _Allocator>2025inline _LIBCPP_HIDE_FROM_ABI void2026swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, multimap<_Key, _Tp, _Compare, _Allocator>& __y)2027 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {2028 __x.swap(__y);2029}2030 2031# if _LIBCPP_STD_VER >= 202032template <class _Key, class _Tp, class _Compare, class _Allocator, class _Predicate>2033inline _LIBCPP_HIDE_FROM_ABI typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type2034erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) {2035 return std::__libcpp_erase_if_container(__c, __pred);2036}2037# endif2038 2039template <class _Key, class _Tp, class _Compare, class _Allocator>2040struct __container_traits<multimap<_Key, _Tp, _Compare, _Allocator> > {2041 // http://eel.is/c++draft/associative.reqmts.except#22042 // For associative containers, if an exception is thrown by any operation from within2043 // an insert or emplace function inserting a single element, the insertion has no effect.2044 static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = true;2045 2046 static _LIBCPP_CONSTEXPR const bool __reservable = false;2047};2048 2049_LIBCPP_END_NAMESPACE_STD2050 2051# if _LIBCPP_STD_VER >= 172052_LIBCPP_BEGIN_NAMESPACE_STD2053namespace pmr {2054template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>2055using map _LIBCPP_AVAILABILITY_PMR =2056 std::map<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;2057 2058template <class _KeyT, class _ValueT, class _CompareT = std::less<_KeyT>>2059using multimap _LIBCPP_AVAILABILITY_PMR =2060 std::multimap<_KeyT, _ValueT, _CompareT, polymorphic_allocator<std::pair<const _KeyT, _ValueT>>>;2061} // namespace pmr2062_LIBCPP_END_NAMESPACE_STD2063# endif2064 2065_LIBCPP_POP_MACROS2066 2067# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 202068# include <concepts>2069# include <cstdlib>2070# include <functional>2071# include <iterator>2072# include <type_traits>2073# include <utility>2074# endif2075#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)2076 2077#endif // _LIBCPP_MAP2078