1// -*- C++ -*- 2//===----------------------------- map ------------------------------------===// 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-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_MAP 11#define _LIBCPP_MAP 12 13/* 14 15 map synopsis 16 17namespace std 18{ 19 20template <class Key, class T, class Compare = less<Key>, 21 class Allocator = allocator<pair<const Key, T>>> 22class map 23{ 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++17 43 typedef INSERT_RETURN_TYPE<iterator, node_type> insert_return_type; // C++17 44 45 class value_compare 46 : public binary_function<value_type, value_type, bool> 47 { 48 friend class map; 49 protected: 50 key_compare comp; 51 52 value_compare(key_compare c); 53 public: 54 bool operator()(const value_type& x, const value_type& y) const; 55 }; 56 57 // construct/copy/destroy: 58 map() 59 noexcept( 60 is_nothrow_default_constructible<allocator_type>::value && 61 is_nothrow_default_constructible<key_compare>::value && 62 is_nothrow_copy_constructible<key_compare>::value); 63 explicit map(const key_compare& comp); 64 map(const key_compare& comp, const allocator_type& a); 65 template <class InputIterator> 66 map(InputIterator first, InputIterator last, 67 const key_compare& comp = key_compare()); 68 template <class InputIterator> 69 map(InputIterator first, InputIterator last, 70 const key_compare& comp, const allocator_type& a); 71 map(const map& m); 72 map(map&& m) 73 noexcept( 74 is_nothrow_move_constructible<allocator_type>::value && 75 is_nothrow_move_constructible<key_compare>::value); 76 explicit map(const allocator_type& a); 77 map(const map& m, const allocator_type& a); 78 map(map&& m, const allocator_type& a); 79 map(initializer_list<value_type> il, const key_compare& comp = key_compare()); 80 map(initializer_list<value_type> il, const key_compare& comp, const allocator_type& a); 81 template <class InputIterator> 82 map(InputIterator first, InputIterator last, const allocator_type& a) 83 : map(first, last, Compare(), a) {} // C++14 84 map(initializer_list<value_type> il, const allocator_type& a) 85 : map(il, Compare(), a) {} // C++14 86 ~map(); 87 88 map& operator=(const map& m); 89 map& operator=(map&& m) 90 noexcept( 91 allocator_type::propagate_on_container_move_assignment::value && 92 is_nothrow_move_assignable<allocator_type>::value && 93 is_nothrow_move_assignable<key_compare>::value); 94 map& operator=(initializer_list<value_type> il); 95 96 // iterators: 97 iterator begin() noexcept; 98 const_iterator begin() const noexcept; 99 iterator end() noexcept; 100 const_iterator end() const noexcept; 101 102 reverse_iterator rbegin() noexcept; 103 const_reverse_iterator rbegin() const noexcept; 104 reverse_iterator rend() noexcept; 105 const_reverse_iterator rend() const noexcept; 106 107 const_iterator cbegin() const noexcept; 108 const_iterator cend() const noexcept; 109 const_reverse_iterator crbegin() const noexcept; 110 const_reverse_iterator crend() const noexcept; 111 112 // capacity: 113 bool empty() const noexcept; 114 size_type size() const noexcept; 115 size_type max_size() const noexcept; 116 117 // element access: 118 mapped_type& operator[](const key_type& k); 119 mapped_type& operator[](key_type&& k); 120 121 mapped_type& at(const key_type& k); 122 const mapped_type& at(const key_type& k) const; 123 124 // modifiers: 125 template <class... Args> 126 pair<iterator, bool> emplace(Args&&... args); 127 template <class... Args> 128 iterator emplace_hint(const_iterator position, Args&&... args); 129 pair<iterator, bool> insert(const value_type& v); 130 pair<iterator, bool> insert( value_type&& v); // C++17 131 template <class P> 132 pair<iterator, bool> insert(P&& p); 133 iterator insert(const_iterator position, const value_type& v); 134 iterator insert(const_iterator position, value_type&& v); // C++17 135 template <class P> 136 iterator insert(const_iterator position, P&& p); 137 template <class InputIterator> 138 void insert(InputIterator first, InputIterator last); 139 void insert(initializer_list<value_type> il); 140 141 node_type extract(const_iterator position); // C++17 142 node_type extract(const key_type& x); // C++17 143 insert_return_type insert(node_type&& nh); // C++17 144 iterator insert(const_iterator hint, node_type&& nh); // C++17 145 146 template <class... Args> 147 pair<iterator, bool> try_emplace(const key_type& k, Args&&... args); // C++17 148 template <class... Args> 149 pair<iterator, bool> try_emplace(key_type&& k, Args&&... args); // C++17 150 template <class... Args> 151 iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args); // C++17 152 template <class... Args> 153 iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args); // C++17 154 template <class M> 155 pair<iterator, bool> insert_or_assign(const key_type& k, M&& obj); // C++17 156 template <class M> 157 pair<iterator, bool> insert_or_assign(key_type&& k, M&& obj); // C++17 158 template <class M> 159 iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj); // C++17 160 template <class M> 161 iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj); // C++17 162 163 iterator erase(const_iterator position); 164 iterator erase(iterator position); // C++14 165 size_type erase(const key_type& k); 166 iterator erase(const_iterator first, const_iterator last); 167 void clear() noexcept; 168 169 template<class C2> 170 void merge(map<Key, T, C2, Allocator>& source); // C++17 171 template<class C2> 172 void merge(map<Key, T, C2, Allocator>&& source); // C++17 173 template<class C2> 174 void merge(multimap<Key, T, C2, Allocator>& source); // C++17 175 template<class C2> 176 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17 177 178 void swap(map& m) 179 noexcept(allocator_traits<allocator_type>::is_always_equal::value && 180 is_nothrow_swappable<key_compare>::value); // C++17 181 182 // observers: 183 allocator_type get_allocator() const noexcept; 184 key_compare key_comp() const; 185 value_compare value_comp() const; 186 187 // map operations: 188 iterator find(const key_type& k); 189 const_iterator find(const key_type& k) const; 190 template<typename K> 191 iterator find(const K& x); // C++14 192 template<typename K> 193 const_iterator find(const K& x) const; // C++14 194 195 template<typename K> 196 size_type count(const K& x) const; // C++14 197 size_type count(const key_type& k) const; 198 199 bool contains(const key_type& x) const; // C++20 200 template<class K> bool contains(const K& x) const; // C++20 201 202 iterator lower_bound(const key_type& k); 203 const_iterator lower_bound(const key_type& k) const; 204 template<typename K> 205 iterator lower_bound(const K& x); // C++14 206 template<typename K> 207 const_iterator lower_bound(const K& x) const; // C++14 208 209 iterator upper_bound(const key_type& k); 210 const_iterator upper_bound(const key_type& k) const; 211 template<typename K> 212 iterator upper_bound(const K& x); // C++14 213 template<typename K> 214 const_iterator upper_bound(const K& x) const; // C++14 215 216 pair<iterator,iterator> equal_range(const key_type& k); 217 pair<const_iterator,const_iterator> equal_range(const key_type& k) const; 218 template<typename K> 219 pair<iterator,iterator> equal_range(const K& x); // C++14 220 template<typename K> 221 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14 222}; 223 224template <class Key, class T, class Compare, class Allocator> 225bool 226operator==(const map<Key, T, Compare, Allocator>& x, 227 const map<Key, T, Compare, Allocator>& y); 228 229template <class Key, class T, class Compare, class Allocator> 230bool 231operator< (const map<Key, T, Compare, Allocator>& x, 232 const map<Key, T, Compare, Allocator>& y); 233 234template <class Key, class T, class Compare, class Allocator> 235bool 236operator!=(const map<Key, T, Compare, Allocator>& x, 237 const map<Key, T, Compare, Allocator>& y); 238 239template <class Key, class T, class Compare, class Allocator> 240bool 241operator> (const map<Key, T, Compare, Allocator>& x, 242 const map<Key, T, Compare, Allocator>& y); 243 244template <class Key, class T, class Compare, class Allocator> 245bool 246operator>=(const map<Key, T, Compare, Allocator>& x, 247 const map<Key, T, Compare, Allocator>& y); 248 249template <class Key, class T, class Compare, class Allocator> 250bool 251operator<=(const map<Key, T, Compare, Allocator>& x, 252 const map<Key, T, Compare, Allocator>& y); 253 254// specialized algorithms: 255template <class Key, class T, class Compare, class Allocator> 256void 257swap(map<Key, T, Compare, Allocator>& x, map<Key, T, Compare, Allocator>& y) 258 noexcept(noexcept(x.swap(y))); 259 260template <class Key, class T, class Compare, class Allocator, class Predicate> 261typename map<Key, T, Compare, Allocator>::size_type 262erase_if(map<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 263 264 265template <class Key, class T, class Compare = less<Key>, 266 class Allocator = allocator<pair<const Key, T>>> 267class multimap 268{ 269public: 270 // types: 271 typedef Key key_type; 272 typedef T mapped_type; 273 typedef pair<const key_type,mapped_type> value_type; 274 typedef Compare key_compare; 275 typedef Allocator allocator_type; 276 typedef typename allocator_type::reference reference; 277 typedef typename allocator_type::const_reference const_reference; 278 typedef typename allocator_type::size_type size_type; 279 typedef typename allocator_type::difference_type difference_type; 280 typedef typename allocator_type::pointer pointer; 281 typedef typename allocator_type::const_pointer const_pointer; 282 283 typedef implementation-defined iterator; 284 typedef implementation-defined const_iterator; 285 typedef std::reverse_iterator<iterator> reverse_iterator; 286 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 287 typedef unspecified node_type; // C++17 288 289 class value_compare 290 : public binary_function<value_type,value_type,bool> 291 { 292 friend class multimap; 293 protected: 294 key_compare comp; 295 value_compare(key_compare c); 296 public: 297 bool operator()(const value_type& x, const value_type& y) const; 298 }; 299 300 // construct/copy/destroy: 301 multimap() 302 noexcept( 303 is_nothrow_default_constructible<allocator_type>::value && 304 is_nothrow_default_constructible<key_compare>::value && 305 is_nothrow_copy_constructible<key_compare>::value); 306 explicit multimap(const key_compare& comp); 307 multimap(const key_compare& comp, const allocator_type& a); 308 template <class InputIterator> 309 multimap(InputIterator first, InputIterator last, const key_compare& comp); 310 template <class InputIterator> 311 multimap(InputIterator first, InputIterator last, const key_compare& comp, 312 const allocator_type& a); 313 multimap(const multimap& m); 314 multimap(multimap&& m) 315 noexcept( 316 is_nothrow_move_constructible<allocator_type>::value && 317 is_nothrow_move_constructible<key_compare>::value); 318 explicit multimap(const allocator_type& a); 319 multimap(const multimap& m, const allocator_type& a); 320 multimap(multimap&& m, const allocator_type& a); 321 multimap(initializer_list<value_type> il, const key_compare& comp = key_compare()); 322 multimap(initializer_list<value_type> il, const key_compare& comp, 323 const allocator_type& a); 324 template <class InputIterator> 325 multimap(InputIterator first, InputIterator last, const allocator_type& a) 326 : multimap(first, last, Compare(), a) {} // C++14 327 multimap(initializer_list<value_type> il, const allocator_type& a) 328 : multimap(il, Compare(), a) {} // C++14 329 ~multimap(); 330 331 multimap& operator=(const multimap& m); 332 multimap& operator=(multimap&& m) 333 noexcept( 334 allocator_type::propagate_on_container_move_assignment::value && 335 is_nothrow_move_assignable<allocator_type>::value && 336 is_nothrow_move_assignable<key_compare>::value); 337 multimap& operator=(initializer_list<value_type> il); 338 339 // iterators: 340 iterator begin() noexcept; 341 const_iterator begin() const noexcept; 342 iterator end() noexcept; 343 const_iterator end() const noexcept; 344 345 reverse_iterator rbegin() noexcept; 346 const_reverse_iterator rbegin() const noexcept; 347 reverse_iterator rend() noexcept; 348 const_reverse_iterator rend() const noexcept; 349 350 const_iterator cbegin() const noexcept; 351 const_iterator cend() const noexcept; 352 const_reverse_iterator crbegin() const noexcept; 353 const_reverse_iterator crend() const noexcept; 354 355 // capacity: 356 bool empty() const noexcept; 357 size_type size() const noexcept; 358 size_type max_size() const noexcept; 359 360 // modifiers: 361 template <class... Args> 362 iterator emplace(Args&&... args); 363 template <class... Args> 364 iterator emplace_hint(const_iterator position, Args&&... args); 365 iterator insert(const value_type& v); 366 iterator insert( value_type&& v); // C++17 367 template <class P> 368 iterator insert(P&& p); 369 iterator insert(const_iterator position, const value_type& v); 370 iterator insert(const_iterator position, value_type&& v); // C++17 371 template <class P> 372 iterator insert(const_iterator position, P&& p); 373 template <class InputIterator> 374 void insert(InputIterator first, InputIterator last); 375 void insert(initializer_list<value_type> il); 376 377 node_type extract(const_iterator position); // C++17 378 node_type extract(const key_type& x); // C++17 379 iterator insert(node_type&& nh); // C++17 380 iterator insert(const_iterator hint, node_type&& nh); // C++17 381 382 iterator erase(const_iterator position); 383 iterator erase(iterator position); // C++14 384 size_type erase(const key_type& k); 385 iterator erase(const_iterator first, const_iterator last); 386 void clear() noexcept; 387 388 template<class C2> 389 void merge(multimap<Key, T, C2, Allocator>& source); // C++17 390 template<class C2> 391 void merge(multimap<Key, T, C2, Allocator>&& source); // C++17 392 template<class C2> 393 void merge(map<Key, T, C2, Allocator>& source); // C++17 394 template<class C2> 395 void merge(map<Key, T, C2, Allocator>&& source); // C++17 396 397 void swap(multimap& m) 398 noexcept(allocator_traits<allocator_type>::is_always_equal::value && 399 is_nothrow_swappable<key_compare>::value); // C++17 400 401 // observers: 402 allocator_type get_allocator() const noexcept; 403 key_compare key_comp() const; 404 value_compare value_comp() const; 405 406 // map operations: 407 iterator find(const key_type& k); 408 const_iterator find(const key_type& k) const; 409 template<typename K> 410 iterator find(const K& x); // C++14 411 template<typename K> 412 const_iterator find(const K& x) const; // C++14 413 414 template<typename K> 415 size_type count(const K& x) const; // C++14 416 size_type count(const key_type& k) const; 417 418 bool contains(const key_type& x) const; // C++20 419 template<class K> bool contains(const K& x) const; // C++20 420 421 iterator lower_bound(const key_type& k); 422 const_iterator lower_bound(const key_type& k) const; 423 template<typename K> 424 iterator lower_bound(const K& x); // C++14 425 template<typename K> 426 const_iterator lower_bound(const K& x) const; // C++14 427 428 iterator upper_bound(const key_type& k); 429 const_iterator upper_bound(const key_type& k) const; 430 template<typename K> 431 iterator upper_bound(const K& x); // C++14 432 template<typename K> 433 const_iterator upper_bound(const K& x) const; // C++14 434 435 pair<iterator,iterator> equal_range(const key_type& k); 436 pair<const_iterator,const_iterator> equal_range(const key_type& k) const; 437 template<typename K> 438 pair<iterator,iterator> equal_range(const K& x); // C++14 439 template<typename K> 440 pair<const_iterator,const_iterator> equal_range(const K& x) const; // C++14 441}; 442 443template <class Key, class T, class Compare, class Allocator> 444bool 445operator==(const multimap<Key, T, Compare, Allocator>& x, 446 const multimap<Key, T, Compare, Allocator>& y); 447 448template <class Key, class T, class Compare, class Allocator> 449bool 450operator< (const multimap<Key, T, Compare, Allocator>& x, 451 const multimap<Key, T, Compare, Allocator>& y); 452 453template <class Key, class T, class Compare, class Allocator> 454bool 455operator!=(const multimap<Key, T, Compare, Allocator>& x, 456 const multimap<Key, T, Compare, Allocator>& y); 457 458template <class Key, class T, class Compare, class Allocator> 459bool 460operator> (const multimap<Key, T, Compare, Allocator>& x, 461 const multimap<Key, T, Compare, Allocator>& y); 462 463template <class Key, class T, class Compare, class Allocator> 464bool 465operator>=(const multimap<Key, T, Compare, Allocator>& x, 466 const multimap<Key, T, Compare, Allocator>& y); 467 468template <class Key, class T, class Compare, class Allocator> 469bool 470operator<=(const multimap<Key, T, Compare, Allocator>& x, 471 const multimap<Key, T, Compare, Allocator>& y); 472 473// specialized algorithms: 474template <class Key, class T, class Compare, class Allocator> 475void 476swap(multimap<Key, T, Compare, Allocator>& x, 477 multimap<Key, T, Compare, Allocator>& y) 478 noexcept(noexcept(x.swap(y))); 479 480template <class Key, class T, class Compare, class Allocator, class Predicate> 481typename multimap<Key, T, Compare, Allocator>::size_type 482erase_if(multimap<Key, T, Compare, Allocator>& c, Predicate pred); // C++20 483 484} // std 485 486*/ 487 488#include <__config> 489#include <__debug> 490#include <__node_handle> 491#include <__tree> 492#include <compare> 493#include <initializer_list> 494#include <iterator> // __libcpp_erase_if_container 495#include <memory> 496#include <utility> 497#include <functional> 498#include <initializer_list> 499#include <type_traits> 500#include <version> 501 502#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 503#pragma GCC system_header 504#endif 505 506_LIBCPP_BEGIN_NAMESPACE_STD 507 508template <class _Key, class _CP, class _Compare, 509 bool = is_empty<_Compare>::value && !__libcpp_is_final<_Compare>::value> 510class __map_value_compare 511 : private _Compare 512{ 513public: 514 _LIBCPP_INLINE_VISIBILITY 515 __map_value_compare() 516 _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) 517 : _Compare() {} 518 _LIBCPP_INLINE_VISIBILITY 519 __map_value_compare(_Compare c) 520 _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) 521 : _Compare(c) {} 522 _LIBCPP_INLINE_VISIBILITY 523 const _Compare& key_comp() const _NOEXCEPT {return *this;} 524 _LIBCPP_INLINE_VISIBILITY 525 bool operator()(const _CP& __x, const _CP& __y) const 526 {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y.__get_value().first);} 527 _LIBCPP_INLINE_VISIBILITY 528 bool operator()(const _CP& __x, const _Key& __y) const 529 {return static_cast<const _Compare&>(*this)(__x.__get_value().first, __y);} 530 _LIBCPP_INLINE_VISIBILITY 531 bool operator()(const _Key& __x, const _CP& __y) const 532 {return static_cast<const _Compare&>(*this)(__x, __y.__get_value().first);} 533 void swap(__map_value_compare&__y) 534 _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) 535 { 536 using _VSTD::swap; 537 swap(static_cast<_Compare&>(*this), static_cast<_Compare&>(__y)); 538 } 539 540#if _LIBCPP_STD_VER > 11 541 template <typename _K2> 542 _LIBCPP_INLINE_VISIBILITY 543 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 544 operator () ( const _K2& __x, const _CP& __y ) const 545 {return static_cast<const _Compare&>(*this) (__x, __y.__get_value().first);} 546 547 template <typename _K2> 548 _LIBCPP_INLINE_VISIBILITY 549 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 550 operator () (const _CP& __x, const _K2& __y) const 551 {return static_cast<const _Compare&>(*this) (__x.__get_value().first, __y);} 552#endif 553}; 554 555template <class _Key, class _CP, class _Compare> 556class __map_value_compare<_Key, _CP, _Compare, false> 557{ 558 _Compare comp; 559 560public: 561 _LIBCPP_INLINE_VISIBILITY 562 __map_value_compare() 563 _NOEXCEPT_(is_nothrow_default_constructible<_Compare>::value) 564 : comp() {} 565 _LIBCPP_INLINE_VISIBILITY 566 __map_value_compare(_Compare c) 567 _NOEXCEPT_(is_nothrow_copy_constructible<_Compare>::value) 568 : comp(c) {} 569 _LIBCPP_INLINE_VISIBILITY 570 const _Compare& key_comp() const _NOEXCEPT {return comp;} 571 572 _LIBCPP_INLINE_VISIBILITY 573 bool operator()(const _CP& __x, const _CP& __y) const 574 {return comp(__x.__get_value().first, __y.__get_value().first);} 575 _LIBCPP_INLINE_VISIBILITY 576 bool operator()(const _CP& __x, const _Key& __y) const 577 {return comp(__x.__get_value().first, __y);} 578 _LIBCPP_INLINE_VISIBILITY 579 bool operator()(const _Key& __x, const _CP& __y) const 580 {return comp(__x, __y.__get_value().first);} 581 void swap(__map_value_compare&__y) 582 _NOEXCEPT_(__is_nothrow_swappable<_Compare>::value) 583 { 584 using _VSTD::swap; 585 swap(comp, __y.comp); 586 } 587 588#if _LIBCPP_STD_VER > 11 589 template <typename _K2> 590 _LIBCPP_INLINE_VISIBILITY 591 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 592 operator () ( const _K2& __x, const _CP& __y ) const 593 {return comp (__x, __y.__get_value().first);} 594 595 template <typename _K2> 596 _LIBCPP_INLINE_VISIBILITY 597 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 598 operator () (const _CP& __x, const _K2& __y) const 599 {return comp (__x.__get_value().first, __y);} 600#endif 601}; 602 603template <class _Key, class _CP, class _Compare, bool __b> 604inline _LIBCPP_INLINE_VISIBILITY 605void 606swap(__map_value_compare<_Key, _CP, _Compare, __b>& __x, 607 __map_value_compare<_Key, _CP, _Compare, __b>& __y) 608 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 609{ 610 __x.swap(__y); 611} 612 613template <class _Allocator> 614class __map_node_destructor 615{ 616 typedef _Allocator allocator_type; 617 typedef allocator_traits<allocator_type> __alloc_traits; 618 619public: 620 typedef typename __alloc_traits::pointer pointer; 621 622private: 623 allocator_type& __na_; 624 625 __map_node_destructor& operator=(const __map_node_destructor&); 626 627public: 628 bool __first_constructed; 629 bool __second_constructed; 630 631 _LIBCPP_INLINE_VISIBILITY 632 explicit __map_node_destructor(allocator_type& __na) _NOEXCEPT 633 : __na_(__na), 634 __first_constructed(false), 635 __second_constructed(false) 636 {} 637 638#ifndef _LIBCPP_CXX03_LANG 639 _LIBCPP_INLINE_VISIBILITY 640 __map_node_destructor(__tree_node_destructor<allocator_type>&& __x) _NOEXCEPT 641 : __na_(__x.__na_), 642 __first_constructed(__x.__value_constructed), 643 __second_constructed(__x.__value_constructed) 644 { 645 __x.__value_constructed = false; 646 } 647#endif // _LIBCPP_CXX03_LANG 648 649 _LIBCPP_INLINE_VISIBILITY 650 void operator()(pointer __p) _NOEXCEPT 651 { 652 if (__second_constructed) 653 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().second)); 654 if (__first_constructed) 655 __alloc_traits::destroy(__na_, _VSTD::addressof(__p->__value_.__get_value().first)); 656 if (__p) 657 __alloc_traits::deallocate(__na_, __p, 1); 658 } 659}; 660 661template <class _Key, class _Tp, class _Compare, class _Allocator> 662 class map; 663template <class _Key, class _Tp, class _Compare, class _Allocator> 664 class multimap; 665template <class _TreeIterator> class __map_const_iterator; 666 667#ifndef _LIBCPP_CXX03_LANG 668 669template <class _Key, class _Tp> 670struct _LIBCPP_STANDALONE_DEBUG __value_type 671{ 672 typedef _Key key_type; 673 typedef _Tp mapped_type; 674 typedef pair<const key_type, mapped_type> value_type; 675 typedef pair<key_type&, mapped_type&> __nc_ref_pair_type; 676 typedef pair<key_type&&, mapped_type&&> __nc_rref_pair_type; 677 678private: 679 value_type __cc; 680 681public: 682 _LIBCPP_INLINE_VISIBILITY 683 value_type& __get_value() 684 { 685#if _LIBCPP_STD_VER > 14 686 return *_VSTD::launder(_VSTD::addressof(__cc)); 687#else 688 return __cc; 689#endif 690 } 691 692 _LIBCPP_INLINE_VISIBILITY 693 const value_type& __get_value() const 694 { 695#if _LIBCPP_STD_VER > 14 696 return *_VSTD::launder(_VSTD::addressof(__cc)); 697#else 698 return __cc; 699#endif 700 } 701 702 _LIBCPP_INLINE_VISIBILITY 703 __nc_ref_pair_type __ref() 704 { 705 value_type& __v = __get_value(); 706 return __nc_ref_pair_type(const_cast<key_type&>(__v.first), __v.second); 707 } 708 709 _LIBCPP_INLINE_VISIBILITY 710 __nc_rref_pair_type __move() 711 { 712 value_type& __v = __get_value(); 713 return __nc_rref_pair_type( 714 _VSTD::move(const_cast<key_type&>(__v.first)), 715 _VSTD::move(__v.second)); 716 } 717 718 _LIBCPP_INLINE_VISIBILITY 719 __value_type& operator=(const __value_type& __v) 720 { 721 __ref() = __v.__get_value(); 722 return *this; 723 } 724 725 _LIBCPP_INLINE_VISIBILITY 726 __value_type& operator=(__value_type&& __v) 727 { 728 __ref() = __v.__move(); 729 return *this; 730 } 731 732 template <class _ValueTp, 733 class = typename enable_if< 734 __is_same_uncvref<_ValueTp, value_type>::value 735 >::type 736 > 737 _LIBCPP_INLINE_VISIBILITY 738 __value_type& operator=(_ValueTp&& __v) 739 { 740 __ref() = _VSTD::forward<_ValueTp>(__v); 741 return *this; 742 } 743 744private: 745 __value_type() _LIBCPP_EQUAL_DELETE; 746 ~__value_type() _LIBCPP_EQUAL_DELETE; 747 __value_type(const __value_type& __v) _LIBCPP_EQUAL_DELETE; 748 __value_type(__value_type&& __v) _LIBCPP_EQUAL_DELETE; 749}; 750 751#else 752 753template <class _Key, class _Tp> 754struct __value_type 755{ 756 typedef _Key key_type; 757 typedef _Tp mapped_type; 758 typedef pair<const key_type, mapped_type> value_type; 759 760private: 761 value_type __cc; 762 763public: 764 _LIBCPP_INLINE_VISIBILITY 765 value_type& __get_value() { return __cc; } 766 _LIBCPP_INLINE_VISIBILITY 767 const value_type& __get_value() const { return __cc; } 768 769private: 770 __value_type(); 771 __value_type(__value_type const&); 772 __value_type& operator=(__value_type const&); 773 ~__value_type(); 774}; 775 776#endif // _LIBCPP_CXX03_LANG 777 778template <class _Tp> 779struct __extract_key_value_types; 780 781template <class _Key, class _Tp> 782struct __extract_key_value_types<__value_type<_Key, _Tp> > 783{ 784 typedef _Key const __key_type; 785 typedef _Tp __mapped_type; 786}; 787 788template <class _TreeIterator> 789class _LIBCPP_TEMPLATE_VIS __map_iterator 790{ 791 typedef typename _TreeIterator::_NodeTypes _NodeTypes; 792 typedef typename _TreeIterator::__pointer_traits __pointer_traits; 793 794 _TreeIterator __i_; 795 796public: 797 typedef bidirectional_iterator_tag iterator_category; 798 typedef typename _NodeTypes::__map_value_type value_type; 799 typedef typename _TreeIterator::difference_type difference_type; 800 typedef value_type& reference; 801 typedef typename _NodeTypes::__map_value_type_pointer pointer; 802 803 _LIBCPP_INLINE_VISIBILITY 804 __map_iterator() _NOEXCEPT {} 805 806 _LIBCPP_INLINE_VISIBILITY 807 __map_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} 808 809 _LIBCPP_INLINE_VISIBILITY 810 reference operator*() const {return __i_->__get_value();} 811 _LIBCPP_INLINE_VISIBILITY 812 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} 813 814 _LIBCPP_INLINE_VISIBILITY 815 __map_iterator& operator++() {++__i_; return *this;} 816 _LIBCPP_INLINE_VISIBILITY 817 __map_iterator operator++(int) 818 { 819 __map_iterator __t(*this); 820 ++(*this); 821 return __t; 822 } 823 824 _LIBCPP_INLINE_VISIBILITY 825 __map_iterator& operator--() {--__i_; return *this;} 826 _LIBCPP_INLINE_VISIBILITY 827 __map_iterator operator--(int) 828 { 829 __map_iterator __t(*this); 830 --(*this); 831 return __t; 832 } 833 834 friend _LIBCPP_INLINE_VISIBILITY 835 bool operator==(const __map_iterator& __x, const __map_iterator& __y) 836 {return __x.__i_ == __y.__i_;} 837 friend 838 _LIBCPP_INLINE_VISIBILITY 839 bool operator!=(const __map_iterator& __x, const __map_iterator& __y) 840 {return __x.__i_ != __y.__i_;} 841 842 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 843 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 844 template <class> friend class _LIBCPP_TEMPLATE_VIS __map_const_iterator; 845}; 846 847template <class _TreeIterator> 848class _LIBCPP_TEMPLATE_VIS __map_const_iterator 849{ 850 typedef typename _TreeIterator::_NodeTypes _NodeTypes; 851 typedef typename _TreeIterator::__pointer_traits __pointer_traits; 852 853 _TreeIterator __i_; 854 855public: 856 typedef bidirectional_iterator_tag iterator_category; 857 typedef typename _NodeTypes::__map_value_type value_type; 858 typedef typename _TreeIterator::difference_type difference_type; 859 typedef const value_type& reference; 860 typedef typename _NodeTypes::__const_map_value_type_pointer pointer; 861 862 _LIBCPP_INLINE_VISIBILITY 863 __map_const_iterator() _NOEXCEPT {} 864 865 _LIBCPP_INLINE_VISIBILITY 866 __map_const_iterator(_TreeIterator __i) _NOEXCEPT : __i_(__i) {} 867 _LIBCPP_INLINE_VISIBILITY 868 __map_const_iterator(__map_iterator< 869 typename _TreeIterator::__non_const_iterator> __i) _NOEXCEPT 870 : __i_(__i.__i_) {} 871 872 _LIBCPP_INLINE_VISIBILITY 873 reference operator*() const {return __i_->__get_value();} 874 _LIBCPP_INLINE_VISIBILITY 875 pointer operator->() const {return pointer_traits<pointer>::pointer_to(__i_->__get_value());} 876 877 _LIBCPP_INLINE_VISIBILITY 878 __map_const_iterator& operator++() {++__i_; return *this;} 879 _LIBCPP_INLINE_VISIBILITY 880 __map_const_iterator operator++(int) 881 { 882 __map_const_iterator __t(*this); 883 ++(*this); 884 return __t; 885 } 886 887 _LIBCPP_INLINE_VISIBILITY 888 __map_const_iterator& operator--() {--__i_; return *this;} 889 _LIBCPP_INLINE_VISIBILITY 890 __map_const_iterator operator--(int) 891 { 892 __map_const_iterator __t(*this); 893 --(*this); 894 return __t; 895 } 896 897 friend _LIBCPP_INLINE_VISIBILITY 898 bool operator==(const __map_const_iterator& __x, const __map_const_iterator& __y) 899 {return __x.__i_ == __y.__i_;} 900 friend _LIBCPP_INLINE_VISIBILITY 901 bool operator!=(const __map_const_iterator& __x, const __map_const_iterator& __y) 902 {return __x.__i_ != __y.__i_;} 903 904 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS map; 905 template <class, class, class, class> friend class _LIBCPP_TEMPLATE_VIS multimap; 906 template <class, class, class> friend class _LIBCPP_TEMPLATE_VIS __tree_const_iterator; 907}; 908 909template <class _Key, class _Tp, class _Compare = less<_Key>, 910 class _Allocator = allocator<pair<const _Key, _Tp> > > 911class _LIBCPP_TEMPLATE_VIS map 912{ 913public: 914 // types: 915 typedef _Key key_type; 916 typedef _Tp mapped_type; 917 typedef pair<const key_type, mapped_type> value_type; 918 typedef __identity_t<_Compare> key_compare; 919 typedef __identity_t<_Allocator> allocator_type; 920 typedef value_type& reference; 921 typedef const value_type& const_reference; 922 923 static_assert((is_same<typename allocator_type::value_type, value_type>::value), 924 "Allocator::value_type must be same type as value_type"); 925 926 class _LIBCPP_TEMPLATE_VIS value_compare 927 : public binary_function<value_type, value_type, bool> 928 { 929 friend class map; 930 protected: 931 key_compare comp; 932 933 _LIBCPP_INLINE_VISIBILITY value_compare(key_compare c) : comp(c) {} 934 public: 935 _LIBCPP_INLINE_VISIBILITY 936 bool operator()(const value_type& __x, const value_type& __y) const 937 {return comp(__x.first, __y.first);} 938 }; 939 940private: 941 942 typedef _VSTD::__value_type<key_type, mapped_type> __value_type; 943 typedef __map_value_compare<key_type, __value_type, key_compare> __vc; 944 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, 945 __value_type>::type __allocator_type; 946 typedef __tree<__value_type, __vc, __allocator_type> __base; 947 typedef typename __base::__node_traits __node_traits; 948 typedef allocator_traits<allocator_type> __alloc_traits; 949 950 __base __tree_; 951 952public: 953 typedef typename __alloc_traits::pointer pointer; 954 typedef typename __alloc_traits::const_pointer const_pointer; 955 typedef typename __alloc_traits::size_type size_type; 956 typedef typename __alloc_traits::difference_type difference_type; 957 typedef __map_iterator<typename __base::iterator> iterator; 958 typedef __map_const_iterator<typename __base::const_iterator> const_iterator; 959 typedef _VSTD::reverse_iterator<iterator> reverse_iterator; 960 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 961 962#if _LIBCPP_STD_VER > 14 963 typedef __map_node_handle<typename __base::__node, allocator_type> node_type; 964 typedef __insert_return_type<iterator, node_type> insert_return_type; 965#endif 966 967 template <class _Key2, class _Value2, class _Comp2, class _Alloc2> 968 friend class _LIBCPP_TEMPLATE_VIS map; 969 template <class _Key2, class _Value2, class _Comp2, class _Alloc2> 970 friend class _LIBCPP_TEMPLATE_VIS multimap; 971 972 _LIBCPP_INLINE_VISIBILITY 973 map() 974 _NOEXCEPT_( 975 is_nothrow_default_constructible<allocator_type>::value && 976 is_nothrow_default_constructible<key_compare>::value && 977 is_nothrow_copy_constructible<key_compare>::value) 978 : __tree_(__vc(key_compare())) {} 979 980 _LIBCPP_INLINE_VISIBILITY 981 explicit map(const key_compare& __comp) 982 _NOEXCEPT_( 983 is_nothrow_default_constructible<allocator_type>::value && 984 is_nothrow_copy_constructible<key_compare>::value) 985 : __tree_(__vc(__comp)) {} 986 987 _LIBCPP_INLINE_VISIBILITY 988 explicit map(const key_compare& __comp, const allocator_type& __a) 989 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} 990 991 template <class _InputIterator> 992 _LIBCPP_INLINE_VISIBILITY 993 map(_InputIterator __f, _InputIterator __l, 994 const key_compare& __comp = key_compare()) 995 : __tree_(__vc(__comp)) 996 { 997 insert(__f, __l); 998 } 999 1000 template <class _InputIterator> 1001 _LIBCPP_INLINE_VISIBILITY 1002 map(_InputIterator __f, _InputIterator __l, 1003 const key_compare& __comp, const allocator_type& __a) 1004 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) 1005 { 1006 insert(__f, __l); 1007 } 1008 1009#if _LIBCPP_STD_VER > 11 1010 template <class _InputIterator> 1011 _LIBCPP_INLINE_VISIBILITY 1012 map(_InputIterator __f, _InputIterator __l, const allocator_type& __a) 1013 : map(__f, __l, key_compare(), __a) {} 1014#endif 1015 1016 _LIBCPP_INLINE_VISIBILITY 1017 map(const map& __m) 1018 : __tree_(__m.__tree_) 1019 { 1020 insert(__m.begin(), __m.end()); 1021 } 1022 1023 _LIBCPP_INLINE_VISIBILITY 1024 map& operator=(const map& __m) 1025 { 1026#ifndef _LIBCPP_CXX03_LANG 1027 __tree_ = __m.__tree_; 1028#else 1029 if (this != &__m) { 1030 __tree_.clear(); 1031 __tree_.value_comp() = __m.__tree_.value_comp(); 1032 __tree_.__copy_assign_alloc(__m.__tree_); 1033 insert(__m.begin(), __m.end()); 1034 } 1035#endif 1036 return *this; 1037 } 1038 1039#ifndef _LIBCPP_CXX03_LANG 1040 1041 _LIBCPP_INLINE_VISIBILITY 1042 map(map&& __m) 1043 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) 1044 : __tree_(_VSTD::move(__m.__tree_)) 1045 { 1046 } 1047 1048 map(map&& __m, const allocator_type& __a); 1049 1050 _LIBCPP_INLINE_VISIBILITY 1051 map& operator=(map&& __m) 1052 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) 1053 { 1054 __tree_ = _VSTD::move(__m.__tree_); 1055 return *this; 1056 } 1057 1058 _LIBCPP_INLINE_VISIBILITY 1059 map(initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 1060 : __tree_(__vc(__comp)) 1061 { 1062 insert(__il.begin(), __il.end()); 1063 } 1064 1065 _LIBCPP_INLINE_VISIBILITY 1066 map(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) 1067 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) 1068 { 1069 insert(__il.begin(), __il.end()); 1070 } 1071 1072#if _LIBCPP_STD_VER > 11 1073 _LIBCPP_INLINE_VISIBILITY 1074 map(initializer_list<value_type> __il, const allocator_type& __a) 1075 : map(__il, key_compare(), __a) {} 1076#endif 1077 1078 _LIBCPP_INLINE_VISIBILITY 1079 map& operator=(initializer_list<value_type> __il) 1080 { 1081 __tree_.__assign_unique(__il.begin(), __il.end()); 1082 return *this; 1083 } 1084 1085#endif // _LIBCPP_CXX03_LANG 1086 1087 _LIBCPP_INLINE_VISIBILITY 1088 explicit map(const allocator_type& __a) 1089 : __tree_(typename __base::allocator_type(__a)) 1090 { 1091 } 1092 1093 _LIBCPP_INLINE_VISIBILITY 1094 map(const map& __m, const allocator_type& __a) 1095 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) 1096 { 1097 insert(__m.begin(), __m.end()); 1098 } 1099 1100 _LIBCPP_INLINE_VISIBILITY 1101 ~map() { 1102 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); 1103 } 1104 1105 _LIBCPP_INLINE_VISIBILITY 1106 iterator begin() _NOEXCEPT {return __tree_.begin();} 1107 _LIBCPP_INLINE_VISIBILITY 1108 const_iterator begin() const _NOEXCEPT {return __tree_.begin();} 1109 _LIBCPP_INLINE_VISIBILITY 1110 iterator end() _NOEXCEPT {return __tree_.end();} 1111 _LIBCPP_INLINE_VISIBILITY 1112 const_iterator end() const _NOEXCEPT {return __tree_.end();} 1113 1114 _LIBCPP_INLINE_VISIBILITY 1115 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} 1116 _LIBCPP_INLINE_VISIBILITY 1117 const_reverse_iterator rbegin() const _NOEXCEPT 1118 {return const_reverse_iterator(end());} 1119 _LIBCPP_INLINE_VISIBILITY 1120 reverse_iterator rend() _NOEXCEPT 1121 {return reverse_iterator(begin());} 1122 _LIBCPP_INLINE_VISIBILITY 1123 const_reverse_iterator rend() const _NOEXCEPT 1124 {return const_reverse_iterator(begin());} 1125 1126 _LIBCPP_INLINE_VISIBILITY 1127 const_iterator cbegin() const _NOEXCEPT {return begin();} 1128 _LIBCPP_INLINE_VISIBILITY 1129 const_iterator cend() const _NOEXCEPT {return end();} 1130 _LIBCPP_INLINE_VISIBILITY 1131 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} 1132 _LIBCPP_INLINE_VISIBILITY 1133 const_reverse_iterator crend() const _NOEXCEPT {return rend();} 1134 1135 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 1136 bool empty() const _NOEXCEPT {return __tree_.size() == 0;} 1137 _LIBCPP_INLINE_VISIBILITY 1138 size_type size() const _NOEXCEPT {return __tree_.size();} 1139 _LIBCPP_INLINE_VISIBILITY 1140 size_type max_size() const _NOEXCEPT {return __tree_.max_size();} 1141 1142 mapped_type& operator[](const key_type& __k); 1143#ifndef _LIBCPP_CXX03_LANG 1144 mapped_type& operator[](key_type&& __k); 1145#endif 1146 1147 mapped_type& at(const key_type& __k); 1148 const mapped_type& at(const key_type& __k) const; 1149 1150 _LIBCPP_INLINE_VISIBILITY 1151 allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} 1152 _LIBCPP_INLINE_VISIBILITY 1153 key_compare key_comp() const {return __tree_.value_comp().key_comp();} 1154 _LIBCPP_INLINE_VISIBILITY 1155 value_compare value_comp() const {return value_compare(__tree_.value_comp().key_comp());} 1156 1157#ifndef _LIBCPP_CXX03_LANG 1158 template <class ..._Args> 1159 _LIBCPP_INLINE_VISIBILITY 1160 pair<iterator, bool> emplace(_Args&& ...__args) { 1161 return __tree_.__emplace_unique(_VSTD::forward<_Args>(__args)...); 1162 } 1163 1164 template <class ..._Args> 1165 _LIBCPP_INLINE_VISIBILITY 1166 iterator emplace_hint(const_iterator __p, _Args&& ...__args) { 1167 return __tree_.__emplace_hint_unique(__p.__i_, _VSTD::forward<_Args>(__args)...); 1168 } 1169 1170 template <class _Pp, 1171 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> 1172 _LIBCPP_INLINE_VISIBILITY 1173 pair<iterator, bool> insert(_Pp&& __p) 1174 {return __tree_.__insert_unique(_VSTD::forward<_Pp>(__p));} 1175 1176 template <class _Pp, 1177 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> 1178 _LIBCPP_INLINE_VISIBILITY 1179 iterator insert(const_iterator __pos, _Pp&& __p) 1180 {return __tree_.__insert_unique(__pos.__i_, _VSTD::forward<_Pp>(__p));} 1181 1182#endif // _LIBCPP_CXX03_LANG 1183 1184 _LIBCPP_INLINE_VISIBILITY 1185 pair<iterator, bool> 1186 insert(const value_type& __v) {return __tree_.__insert_unique(__v);} 1187 1188 _LIBCPP_INLINE_VISIBILITY 1189 iterator 1190 insert(const_iterator __p, const value_type& __v) 1191 {return __tree_.__insert_unique(__p.__i_, __v);} 1192 1193#ifndef _LIBCPP_CXX03_LANG 1194 _LIBCPP_INLINE_VISIBILITY 1195 pair<iterator, bool> 1196 insert(value_type&& __v) {return __tree_.__insert_unique(_VSTD::move(__v));} 1197 1198 _LIBCPP_INLINE_VISIBILITY 1199 iterator insert(const_iterator __p, value_type&& __v) 1200 {return __tree_.__insert_unique(__p.__i_, _VSTD::move(__v));} 1201 1202 _LIBCPP_INLINE_VISIBILITY 1203 void insert(initializer_list<value_type> __il) 1204 {insert(__il.begin(), __il.end());} 1205#endif 1206 1207 template <class _InputIterator> 1208 _LIBCPP_INLINE_VISIBILITY 1209 void insert(_InputIterator __f, _InputIterator __l) 1210 { 1211 for (const_iterator __e = cend(); __f != __l; ++__f) 1212 insert(__e.__i_, *__f); 1213 } 1214 1215#if _LIBCPP_STD_VER > 14 1216 1217 template <class... _Args> 1218 _LIBCPP_INLINE_VISIBILITY 1219 pair<iterator, bool> try_emplace(const key_type& __k, _Args&&... __args) 1220 { 1221 return __tree_.__emplace_unique_key_args(__k, 1222 _VSTD::piecewise_construct, 1223 _VSTD::forward_as_tuple(__k), 1224 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); 1225 } 1226 1227 template <class... _Args> 1228 _LIBCPP_INLINE_VISIBILITY 1229 pair<iterator, bool> try_emplace(key_type&& __k, _Args&&... __args) 1230 { 1231 return __tree_.__emplace_unique_key_args(__k, 1232 _VSTD::piecewise_construct, 1233 _VSTD::forward_as_tuple(_VSTD::move(__k)), 1234 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)); 1235 } 1236 1237 template <class... _Args> 1238 _LIBCPP_INLINE_VISIBILITY 1239 iterator try_emplace(const_iterator __h, const key_type& __k, _Args&&... __args) 1240 { 1241 return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, 1242 _VSTD::piecewise_construct, 1243 _VSTD::forward_as_tuple(__k), 1244 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first; 1245 } 1246 1247 template <class... _Args> 1248 _LIBCPP_INLINE_VISIBILITY 1249 iterator try_emplace(const_iterator __h, key_type&& __k, _Args&&... __args) 1250 { 1251 return __tree_.__emplace_hint_unique_key_args(__h.__i_, __k, 1252 _VSTD::piecewise_construct, 1253 _VSTD::forward_as_tuple(_VSTD::move(__k)), 1254 _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)).first; 1255 } 1256 1257 template <class _Vp> 1258 _LIBCPP_INLINE_VISIBILITY 1259 pair<iterator, bool> insert_or_assign(const key_type& __k, _Vp&& __v) 1260 { 1261 iterator __p = lower_bound(__k); 1262 if ( __p != end() && !key_comp()(__k, __p->first)) 1263 { 1264 __p->second = _VSTD::forward<_Vp>(__v); 1265 return _VSTD::make_pair(__p, false); 1266 } 1267 return _VSTD::make_pair(emplace_hint(__p, __k, _VSTD::forward<_Vp>(__v)), true); 1268 } 1269 1270 template <class _Vp> 1271 _LIBCPP_INLINE_VISIBILITY 1272 pair<iterator, bool> insert_or_assign(key_type&& __k, _Vp&& __v) 1273 { 1274 iterator __p = lower_bound(__k); 1275 if ( __p != end() && !key_comp()(__k, __p->first)) 1276 { 1277 __p->second = _VSTD::forward<_Vp>(__v); 1278 return _VSTD::make_pair(__p, false); 1279 } 1280 return _VSTD::make_pair(emplace_hint(__p, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)), true); 1281 } 1282 1283 template <class _Vp> 1284 _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, 1285 const key_type& __k, 1286 _Vp&& __v) { 1287 auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args( 1288 __h.__i_, __k, __k, _VSTD::forward<_Vp>(__v)); 1289 1290 if (!__inserted) 1291 __r->__get_value().second = _VSTD::forward<_Vp>(__v); 1292 1293 return __r; 1294 } 1295 1296 template <class _Vp> 1297 _LIBCPP_INLINE_VISIBILITY iterator insert_or_assign(const_iterator __h, 1298 key_type&& __k, 1299 _Vp&& __v) { 1300 auto [__r, __inserted] = __tree_.__emplace_hint_unique_key_args( 1301 __h.__i_, __k, _VSTD::move(__k), _VSTD::forward<_Vp>(__v)); 1302 1303 if (!__inserted) 1304 __r->__get_value().second = _VSTD::forward<_Vp>(__v); 1305 1306 return __r; 1307 } 1308 1309#endif // _LIBCPP_STD_VER > 14 1310 1311 _LIBCPP_INLINE_VISIBILITY 1312 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} 1313 _LIBCPP_INLINE_VISIBILITY 1314 iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} 1315 _LIBCPP_INLINE_VISIBILITY 1316 size_type erase(const key_type& __k) 1317 {return __tree_.__erase_unique(__k);} 1318 _LIBCPP_INLINE_VISIBILITY 1319 iterator erase(const_iterator __f, const_iterator __l) 1320 {return __tree_.erase(__f.__i_, __l.__i_);} 1321 _LIBCPP_INLINE_VISIBILITY 1322 void clear() _NOEXCEPT {__tree_.clear();} 1323 1324#if _LIBCPP_STD_VER > 14 1325 _LIBCPP_INLINE_VISIBILITY 1326 insert_return_type insert(node_type&& __nh) 1327 { 1328 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), 1329 "node_type with incompatible allocator passed to map::insert()"); 1330 return __tree_.template __node_handle_insert_unique< 1331 node_type, insert_return_type>(_VSTD::move(__nh)); 1332 } 1333 _LIBCPP_INLINE_VISIBILITY 1334 iterator insert(const_iterator __hint, node_type&& __nh) 1335 { 1336 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), 1337 "node_type with incompatible allocator passed to map::insert()"); 1338 return __tree_.template __node_handle_insert_unique<node_type>( 1339 __hint.__i_, _VSTD::move(__nh)); 1340 } 1341 _LIBCPP_INLINE_VISIBILITY 1342 node_type extract(key_type const& __key) 1343 { 1344 return __tree_.template __node_handle_extract<node_type>(__key); 1345 } 1346 _LIBCPP_INLINE_VISIBILITY 1347 node_type extract(const_iterator __it) 1348 { 1349 return __tree_.template __node_handle_extract<node_type>(__it.__i_); 1350 } 1351 template <class _Compare2> 1352 _LIBCPP_INLINE_VISIBILITY 1353 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) 1354 { 1355 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 1356 "merging container with incompatible allocator"); 1357 __tree_.__node_handle_merge_unique(__source.__tree_); 1358 } 1359 template <class _Compare2> 1360 _LIBCPP_INLINE_VISIBILITY 1361 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) 1362 { 1363 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 1364 "merging container with incompatible allocator"); 1365 __tree_.__node_handle_merge_unique(__source.__tree_); 1366 } 1367 template <class _Compare2> 1368 _LIBCPP_INLINE_VISIBILITY 1369 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) 1370 { 1371 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 1372 "merging container with incompatible allocator"); 1373 __tree_.__node_handle_merge_unique(__source.__tree_); 1374 } 1375 template <class _Compare2> 1376 _LIBCPP_INLINE_VISIBILITY 1377 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) 1378 { 1379 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 1380 "merging container with incompatible allocator"); 1381 __tree_.__node_handle_merge_unique(__source.__tree_); 1382 } 1383#endif 1384 1385 _LIBCPP_INLINE_VISIBILITY 1386 void swap(map& __m) 1387 _NOEXCEPT_(__is_nothrow_swappable<__base>::value) 1388 {__tree_.swap(__m.__tree_);} 1389 1390 _LIBCPP_INLINE_VISIBILITY 1391 iterator find(const key_type& __k) {return __tree_.find(__k);} 1392 _LIBCPP_INLINE_VISIBILITY 1393 const_iterator find(const key_type& __k) const {return __tree_.find(__k);} 1394#if _LIBCPP_STD_VER > 11 1395 template <typename _K2> 1396 _LIBCPP_INLINE_VISIBILITY 1397 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 1398 find(const _K2& __k) {return __tree_.find(__k);} 1399 template <typename _K2> 1400 _LIBCPP_INLINE_VISIBILITY 1401 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 1402 find(const _K2& __k) const {return __tree_.find(__k);} 1403#endif 1404 1405 _LIBCPP_INLINE_VISIBILITY 1406 size_type count(const key_type& __k) const 1407 {return __tree_.__count_unique(__k);} 1408#if _LIBCPP_STD_VER > 11 1409 template <typename _K2> 1410 _LIBCPP_INLINE_VISIBILITY 1411 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type 1412 count(const _K2& __k) const {return __tree_.__count_multi(__k);} 1413#endif 1414 1415#if _LIBCPP_STD_VER > 17 1416 _LIBCPP_INLINE_VISIBILITY 1417 bool contains(const key_type& __k) const {return find(__k) != end();} 1418 template <typename _K2> 1419 _LIBCPP_INLINE_VISIBILITY 1420 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 1421 contains(const _K2& __k) const { return find(__k) != end(); } 1422#endif // _LIBCPP_STD_VER > 17 1423 1424 _LIBCPP_INLINE_VISIBILITY 1425 iterator lower_bound(const key_type& __k) 1426 {return __tree_.lower_bound(__k);} 1427 _LIBCPP_INLINE_VISIBILITY 1428 const_iterator lower_bound(const key_type& __k) const 1429 {return __tree_.lower_bound(__k);} 1430#if _LIBCPP_STD_VER > 11 1431 template <typename _K2> 1432 _LIBCPP_INLINE_VISIBILITY 1433 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 1434 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} 1435 1436 template <typename _K2> 1437 _LIBCPP_INLINE_VISIBILITY 1438 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 1439 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} 1440#endif 1441 1442 _LIBCPP_INLINE_VISIBILITY 1443 iterator upper_bound(const key_type& __k) 1444 {return __tree_.upper_bound(__k);} 1445 _LIBCPP_INLINE_VISIBILITY 1446 const_iterator upper_bound(const key_type& __k) const 1447 {return __tree_.upper_bound(__k);} 1448#if _LIBCPP_STD_VER > 11 1449 template <typename _K2> 1450 _LIBCPP_INLINE_VISIBILITY 1451 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 1452 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} 1453 template <typename _K2> 1454 _LIBCPP_INLINE_VISIBILITY 1455 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 1456 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} 1457#endif 1458 1459 _LIBCPP_INLINE_VISIBILITY 1460 pair<iterator,iterator> equal_range(const key_type& __k) 1461 {return __tree_.__equal_range_unique(__k);} 1462 _LIBCPP_INLINE_VISIBILITY 1463 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const 1464 {return __tree_.__equal_range_unique(__k);} 1465#if _LIBCPP_STD_VER > 11 1466 template <typename _K2> 1467 _LIBCPP_INLINE_VISIBILITY 1468 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type 1469 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} 1470 template <typename _K2> 1471 _LIBCPP_INLINE_VISIBILITY 1472 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type 1473 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} 1474#endif 1475 1476private: 1477 typedef typename __base::__node __node; 1478 typedef typename __base::__node_allocator __node_allocator; 1479 typedef typename __base::__node_pointer __node_pointer; 1480 typedef typename __base::__node_base_pointer __node_base_pointer; 1481 typedef typename __base::__parent_pointer __parent_pointer; 1482 1483 typedef __map_node_destructor<__node_allocator> _Dp; 1484 typedef unique_ptr<__node, _Dp> __node_holder; 1485 1486#ifdef _LIBCPP_CXX03_LANG 1487 __node_holder __construct_node_with_key(const key_type& __k); 1488#endif 1489}; 1490 1491#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 1492template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, 1493 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, 1494 class = _EnableIf<!__is_allocator<_Compare>::value, void>, 1495 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 1496map(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) 1497 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; 1498 1499template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, 1500 class _Allocator = allocator<pair<const _Key, _Tp>>, 1501 class = _EnableIf<!__is_allocator<_Compare>::value, void>, 1502 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 1503map(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) 1504 -> map<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; 1505 1506template<class _InputIterator, class _Allocator, 1507 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 1508map(_InputIterator, _InputIterator, _Allocator) 1509 -> map<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, 1510 less<__iter_key_type<_InputIterator>>, _Allocator>; 1511 1512template<class _Key, class _Tp, class _Allocator, 1513 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 1514map(initializer_list<pair<_Key, _Tp>>, _Allocator) 1515 -> map<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>; 1516#endif 1517 1518#ifndef _LIBCPP_CXX03_LANG 1519template <class _Key, class _Tp, class _Compare, class _Allocator> 1520map<_Key, _Tp, _Compare, _Allocator>::map(map&& __m, const allocator_type& __a) 1521 : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) 1522{ 1523 if (__a != __m.get_allocator()) 1524 { 1525 const_iterator __e = cend(); 1526 while (!__m.empty()) 1527 __tree_.__insert_unique(__e.__i_, 1528 __m.__tree_.remove(__m.begin().__i_)->__value_.__move()); 1529 } 1530} 1531 1532template <class _Key, class _Tp, class _Compare, class _Allocator> 1533_Tp& 1534map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) 1535{ 1536 return __tree_.__emplace_unique_key_args(__k, 1537 _VSTD::piecewise_construct, 1538 _VSTD::forward_as_tuple(__k), 1539 _VSTD::forward_as_tuple()).first->__get_value().second; 1540} 1541 1542template <class _Key, class _Tp, class _Compare, class _Allocator> 1543_Tp& 1544map<_Key, _Tp, _Compare, _Allocator>::operator[](key_type&& __k) 1545{ 1546 return __tree_.__emplace_unique_key_args(__k, 1547 _VSTD::piecewise_construct, 1548 _VSTD::forward_as_tuple(_VSTD::move(__k)), 1549 _VSTD::forward_as_tuple()).first->__get_value().second; 1550} 1551 1552#else // _LIBCPP_CXX03_LANG 1553 1554template <class _Key, class _Tp, class _Compare, class _Allocator> 1555typename map<_Key, _Tp, _Compare, _Allocator>::__node_holder 1556map<_Key, _Tp, _Compare, _Allocator>::__construct_node_with_key(const key_type& __k) 1557{ 1558 __node_allocator& __na = __tree_.__node_alloc(); 1559 __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na)); 1560 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().first), __k); 1561 __h.get_deleter().__first_constructed = true; 1562 __node_traits::construct(__na, _VSTD::addressof(__h->__value_.__get_value().second)); 1563 __h.get_deleter().__second_constructed = true; 1564 return __h; 1565} 1566 1567template <class _Key, class _Tp, class _Compare, class _Allocator> 1568_Tp& 1569map<_Key, _Tp, _Compare, _Allocator>::operator[](const key_type& __k) 1570{ 1571 __parent_pointer __parent; 1572 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k); 1573 __node_pointer __r = static_cast<__node_pointer>(__child); 1574 if (__child == nullptr) 1575 { 1576 __node_holder __h = __construct_node_with_key(__k); 1577 __tree_.__insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get())); 1578 __r = __h.release(); 1579 } 1580 return __r->__value_.__get_value().second; 1581} 1582 1583#endif // _LIBCPP_CXX03_LANG 1584 1585template <class _Key, class _Tp, class _Compare, class _Allocator> 1586_Tp& 1587map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) 1588{ 1589 __parent_pointer __parent; 1590 __node_base_pointer& __child = __tree_.__find_equal(__parent, __k); 1591 if (__child == nullptr) 1592 __throw_out_of_range("map::at: key not found"); 1593 return static_cast<__node_pointer>(__child)->__value_.__get_value().second; 1594} 1595 1596template <class _Key, class _Tp, class _Compare, class _Allocator> 1597const _Tp& 1598map<_Key, _Tp, _Compare, _Allocator>::at(const key_type& __k) const 1599{ 1600 __parent_pointer __parent; 1601 __node_base_pointer __child = __tree_.__find_equal(__parent, __k); 1602 if (__child == nullptr) 1603 __throw_out_of_range("map::at: key not found"); 1604 return static_cast<__node_pointer>(__child)->__value_.__get_value().second; 1605} 1606 1607 1608template <class _Key, class _Tp, class _Compare, class _Allocator> 1609inline _LIBCPP_INLINE_VISIBILITY 1610bool 1611operator==(const map<_Key, _Tp, _Compare, _Allocator>& __x, 1612 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1613{ 1614 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); 1615} 1616 1617template <class _Key, class _Tp, class _Compare, class _Allocator> 1618inline _LIBCPP_INLINE_VISIBILITY 1619bool 1620operator< (const map<_Key, _Tp, _Compare, _Allocator>& __x, 1621 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1622{ 1623 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 1624} 1625 1626template <class _Key, class _Tp, class _Compare, class _Allocator> 1627inline _LIBCPP_INLINE_VISIBILITY 1628bool 1629operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __x, 1630 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1631{ 1632 return !(__x == __y); 1633} 1634 1635template <class _Key, class _Tp, class _Compare, class _Allocator> 1636inline _LIBCPP_INLINE_VISIBILITY 1637bool 1638operator> (const map<_Key, _Tp, _Compare, _Allocator>& __x, 1639 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1640{ 1641 return __y < __x; 1642} 1643 1644template <class _Key, class _Tp, class _Compare, class _Allocator> 1645inline _LIBCPP_INLINE_VISIBILITY 1646bool 1647operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __x, 1648 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1649{ 1650 return !(__x < __y); 1651} 1652 1653template <class _Key, class _Tp, class _Compare, class _Allocator> 1654inline _LIBCPP_INLINE_VISIBILITY 1655bool 1656operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __x, 1657 const map<_Key, _Tp, _Compare, _Allocator>& __y) 1658{ 1659 return !(__y < __x); 1660} 1661 1662template <class _Key, class _Tp, class _Compare, class _Allocator> 1663inline _LIBCPP_INLINE_VISIBILITY 1664void 1665swap(map<_Key, _Tp, _Compare, _Allocator>& __x, 1666 map<_Key, _Tp, _Compare, _Allocator>& __y) 1667 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 1668{ 1669 __x.swap(__y); 1670} 1671 1672#if _LIBCPP_STD_VER > 17 1673template <class _Key, class _Tp, class _Compare, class _Allocator, 1674 class _Predicate> 1675inline _LIBCPP_INLINE_VISIBILITY 1676 typename map<_Key, _Tp, _Compare, _Allocator>::size_type 1677 erase_if(map<_Key, _Tp, _Compare, _Allocator>& __c, _Predicate __pred) { 1678 return _VSTD::__libcpp_erase_if_container(__c, __pred); 1679} 1680#endif 1681 1682 1683template <class _Key, class _Tp, class _Compare = less<_Key>, 1684 class _Allocator = allocator<pair<const _Key, _Tp> > > 1685class _LIBCPP_TEMPLATE_VIS multimap 1686{ 1687public: 1688 // types: 1689 typedef _Key key_type; 1690 typedef _Tp mapped_type; 1691 typedef pair<const key_type, mapped_type> value_type; 1692 typedef __identity_t<_Compare> key_compare; 1693 typedef __identity_t<_Allocator> allocator_type; 1694 typedef value_type& reference; 1695 typedef const value_type& const_reference; 1696 1697 static_assert((is_same<typename allocator_type::value_type, value_type>::value), 1698 "Allocator::value_type must be same type as value_type"); 1699 1700 class _LIBCPP_TEMPLATE_VIS value_compare 1701 : public binary_function<value_type, value_type, bool> 1702 { 1703 friend class multimap; 1704 protected: 1705 key_compare comp; 1706 1707 _LIBCPP_INLINE_VISIBILITY 1708 value_compare(key_compare c) : comp(c) {} 1709 public: 1710 _LIBCPP_INLINE_VISIBILITY 1711 bool operator()(const value_type& __x, const value_type& __y) const 1712 {return comp(__x.first, __y.first);} 1713 }; 1714 1715private: 1716 1717 typedef _VSTD::__value_type<key_type, mapped_type> __value_type; 1718 typedef __map_value_compare<key_type, __value_type, key_compare> __vc; 1719 typedef typename __rebind_alloc_helper<allocator_traits<allocator_type>, 1720 __value_type>::type __allocator_type; 1721 typedef __tree<__value_type, __vc, __allocator_type> __base; 1722 typedef typename __base::__node_traits __node_traits; 1723 typedef allocator_traits<allocator_type> __alloc_traits; 1724 1725 __base __tree_; 1726 1727public: 1728 typedef typename __alloc_traits::pointer pointer; 1729 typedef typename __alloc_traits::const_pointer const_pointer; 1730 typedef typename __alloc_traits::size_type size_type; 1731 typedef typename __alloc_traits::difference_type difference_type; 1732 typedef __map_iterator<typename __base::iterator> iterator; 1733 typedef __map_const_iterator<typename __base::const_iterator> const_iterator; 1734 typedef _VSTD::reverse_iterator<iterator> reverse_iterator; 1735 typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator; 1736 1737#if _LIBCPP_STD_VER > 14 1738 typedef __map_node_handle<typename __base::__node, allocator_type> node_type; 1739#endif 1740 1741 template <class _Key2, class _Value2, class _Comp2, class _Alloc2> 1742 friend class _LIBCPP_TEMPLATE_VIS map; 1743 template <class _Key2, class _Value2, class _Comp2, class _Alloc2> 1744 friend class _LIBCPP_TEMPLATE_VIS multimap; 1745 1746 _LIBCPP_INLINE_VISIBILITY 1747 multimap() 1748 _NOEXCEPT_( 1749 is_nothrow_default_constructible<allocator_type>::value && 1750 is_nothrow_default_constructible<key_compare>::value && 1751 is_nothrow_copy_constructible<key_compare>::value) 1752 : __tree_(__vc(key_compare())) {} 1753 1754 _LIBCPP_INLINE_VISIBILITY 1755 explicit multimap(const key_compare& __comp) 1756 _NOEXCEPT_( 1757 is_nothrow_default_constructible<allocator_type>::value && 1758 is_nothrow_copy_constructible<key_compare>::value) 1759 : __tree_(__vc(__comp)) {} 1760 1761 _LIBCPP_INLINE_VISIBILITY 1762 explicit multimap(const key_compare& __comp, const allocator_type& __a) 1763 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) {} 1764 1765 template <class _InputIterator> 1766 _LIBCPP_INLINE_VISIBILITY 1767 multimap(_InputIterator __f, _InputIterator __l, 1768 const key_compare& __comp = key_compare()) 1769 : __tree_(__vc(__comp)) 1770 { 1771 insert(__f, __l); 1772 } 1773 1774 template <class _InputIterator> 1775 _LIBCPP_INLINE_VISIBILITY 1776 multimap(_InputIterator __f, _InputIterator __l, 1777 const key_compare& __comp, const allocator_type& __a) 1778 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) 1779 { 1780 insert(__f, __l); 1781 } 1782 1783#if _LIBCPP_STD_VER > 11 1784 template <class _InputIterator> 1785 _LIBCPP_INLINE_VISIBILITY 1786 multimap(_InputIterator __f, _InputIterator __l, const allocator_type& __a) 1787 : multimap(__f, __l, key_compare(), __a) {} 1788#endif 1789 1790 _LIBCPP_INLINE_VISIBILITY 1791 multimap(const multimap& __m) 1792 : __tree_(__m.__tree_.value_comp(), 1793 __alloc_traits::select_on_container_copy_construction(__m.__tree_.__alloc())) 1794 { 1795 insert(__m.begin(), __m.end()); 1796 } 1797 1798 _LIBCPP_INLINE_VISIBILITY 1799 multimap& operator=(const multimap& __m) 1800 { 1801#ifndef _LIBCPP_CXX03_LANG 1802 __tree_ = __m.__tree_; 1803#else 1804 if (this != &__m) { 1805 __tree_.clear(); 1806 __tree_.value_comp() = __m.__tree_.value_comp(); 1807 __tree_.__copy_assign_alloc(__m.__tree_); 1808 insert(__m.begin(), __m.end()); 1809 } 1810#endif 1811 return *this; 1812 } 1813 1814#ifndef _LIBCPP_CXX03_LANG 1815 1816 _LIBCPP_INLINE_VISIBILITY 1817 multimap(multimap&& __m) 1818 _NOEXCEPT_(is_nothrow_move_constructible<__base>::value) 1819 : __tree_(_VSTD::move(__m.__tree_)) 1820 { 1821 } 1822 1823 multimap(multimap&& __m, const allocator_type& __a); 1824 1825 _LIBCPP_INLINE_VISIBILITY 1826 multimap& operator=(multimap&& __m) 1827 _NOEXCEPT_(is_nothrow_move_assignable<__base>::value) 1828 { 1829 __tree_ = _VSTD::move(__m.__tree_); 1830 return *this; 1831 } 1832 1833 _LIBCPP_INLINE_VISIBILITY 1834 multimap(initializer_list<value_type> __il, const key_compare& __comp = key_compare()) 1835 : __tree_(__vc(__comp)) 1836 { 1837 insert(__il.begin(), __il.end()); 1838 } 1839 1840 _LIBCPP_INLINE_VISIBILITY 1841 multimap(initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a) 1842 : __tree_(__vc(__comp), typename __base::allocator_type(__a)) 1843 { 1844 insert(__il.begin(), __il.end()); 1845 } 1846 1847#if _LIBCPP_STD_VER > 11 1848 _LIBCPP_INLINE_VISIBILITY 1849 multimap(initializer_list<value_type> __il, const allocator_type& __a) 1850 : multimap(__il, key_compare(), __a) {} 1851#endif 1852 1853 _LIBCPP_INLINE_VISIBILITY 1854 multimap& operator=(initializer_list<value_type> __il) 1855 { 1856 __tree_.__assign_multi(__il.begin(), __il.end()); 1857 return *this; 1858 } 1859 1860#endif // _LIBCPP_CXX03_LANG 1861 1862 _LIBCPP_INLINE_VISIBILITY 1863 explicit multimap(const allocator_type& __a) 1864 : __tree_(typename __base::allocator_type(__a)) 1865 { 1866 } 1867 1868 _LIBCPP_INLINE_VISIBILITY 1869 multimap(const multimap& __m, const allocator_type& __a) 1870 : __tree_(__m.__tree_.value_comp(), typename __base::allocator_type(__a)) 1871 { 1872 insert(__m.begin(), __m.end()); 1873 } 1874 1875 _LIBCPP_INLINE_VISIBILITY 1876 ~multimap() { 1877 static_assert(sizeof(__diagnose_non_const_comparator<_Key, _Compare>()), ""); 1878 } 1879 1880 _LIBCPP_INLINE_VISIBILITY 1881 iterator begin() _NOEXCEPT {return __tree_.begin();} 1882 _LIBCPP_INLINE_VISIBILITY 1883 const_iterator begin() const _NOEXCEPT {return __tree_.begin();} 1884 _LIBCPP_INLINE_VISIBILITY 1885 iterator end() _NOEXCEPT {return __tree_.end();} 1886 _LIBCPP_INLINE_VISIBILITY 1887 const_iterator end() const _NOEXCEPT {return __tree_.end();} 1888 1889 _LIBCPP_INLINE_VISIBILITY 1890 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} 1891 _LIBCPP_INLINE_VISIBILITY 1892 const_reverse_iterator rbegin() const _NOEXCEPT 1893 {return const_reverse_iterator(end());} 1894 _LIBCPP_INLINE_VISIBILITY 1895 reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());} 1896 _LIBCPP_INLINE_VISIBILITY 1897 const_reverse_iterator rend() const _NOEXCEPT 1898 {return const_reverse_iterator(begin());} 1899 1900 _LIBCPP_INLINE_VISIBILITY 1901 const_iterator cbegin() const _NOEXCEPT {return begin();} 1902 _LIBCPP_INLINE_VISIBILITY 1903 const_iterator cend() const _NOEXCEPT {return end();} 1904 _LIBCPP_INLINE_VISIBILITY 1905 const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();} 1906 _LIBCPP_INLINE_VISIBILITY 1907 const_reverse_iterator crend() const _NOEXCEPT {return rend();} 1908 1909 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 1910 bool empty() const _NOEXCEPT {return __tree_.size() == 0;} 1911 _LIBCPP_INLINE_VISIBILITY 1912 size_type size() const _NOEXCEPT {return __tree_.size();} 1913 _LIBCPP_INLINE_VISIBILITY 1914 size_type max_size() const _NOEXCEPT {return __tree_.max_size();} 1915 1916 _LIBCPP_INLINE_VISIBILITY 1917 allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__tree_.__alloc());} 1918 _LIBCPP_INLINE_VISIBILITY 1919 key_compare key_comp() const {return __tree_.value_comp().key_comp();} 1920 _LIBCPP_INLINE_VISIBILITY 1921 value_compare value_comp() const 1922 {return value_compare(__tree_.value_comp().key_comp());} 1923 1924#ifndef _LIBCPP_CXX03_LANG 1925 1926 template <class ..._Args> 1927 _LIBCPP_INLINE_VISIBILITY 1928 iterator emplace(_Args&& ...__args) { 1929 return __tree_.__emplace_multi(_VSTD::forward<_Args>(__args)...); 1930 } 1931 1932 template <class ..._Args> 1933 _LIBCPP_INLINE_VISIBILITY 1934 iterator emplace_hint(const_iterator __p, _Args&& ...__args) { 1935 return __tree_.__emplace_hint_multi(__p.__i_, _VSTD::forward<_Args>(__args)...); 1936 } 1937 1938 template <class _Pp, 1939 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> 1940 _LIBCPP_INLINE_VISIBILITY 1941 iterator insert(_Pp&& __p) 1942 {return __tree_.__insert_multi(_VSTD::forward<_Pp>(__p));} 1943 1944 template <class _Pp, 1945 class = typename enable_if<is_constructible<value_type, _Pp>::value>::type> 1946 _LIBCPP_INLINE_VISIBILITY 1947 iterator insert(const_iterator __pos, _Pp&& __p) 1948 {return __tree_.__insert_multi(__pos.__i_, _VSTD::forward<_Pp>(__p));} 1949 1950 _LIBCPP_INLINE_VISIBILITY 1951 iterator insert(value_type&& __v) 1952 {return __tree_.__insert_multi(_VSTD::move(__v));} 1953 1954 _LIBCPP_INLINE_VISIBILITY 1955 iterator insert(const_iterator __p, value_type&& __v) 1956 {return __tree_.__insert_multi(__p.__i_, _VSTD::move(__v));} 1957 1958 1959 _LIBCPP_INLINE_VISIBILITY 1960 void insert(initializer_list<value_type> __il) 1961 {insert(__il.begin(), __il.end());} 1962 1963#endif // _LIBCPP_CXX03_LANG 1964 1965 _LIBCPP_INLINE_VISIBILITY 1966 iterator insert(const value_type& __v) {return __tree_.__insert_multi(__v);} 1967 1968 _LIBCPP_INLINE_VISIBILITY 1969 iterator insert(const_iterator __p, const value_type& __v) 1970 {return __tree_.__insert_multi(__p.__i_, __v);} 1971 1972 template <class _InputIterator> 1973 _LIBCPP_INLINE_VISIBILITY 1974 void insert(_InputIterator __f, _InputIterator __l) 1975 { 1976 for (const_iterator __e = cend(); __f != __l; ++__f) 1977 __tree_.__insert_multi(__e.__i_, *__f); 1978 } 1979 1980 _LIBCPP_INLINE_VISIBILITY 1981 iterator erase(const_iterator __p) {return __tree_.erase(__p.__i_);} 1982 _LIBCPP_INLINE_VISIBILITY 1983 iterator erase(iterator __p) {return __tree_.erase(__p.__i_);} 1984 _LIBCPP_INLINE_VISIBILITY 1985 size_type erase(const key_type& __k) {return __tree_.__erase_multi(__k);} 1986 _LIBCPP_INLINE_VISIBILITY 1987 iterator erase(const_iterator __f, const_iterator __l) 1988 {return __tree_.erase(__f.__i_, __l.__i_);} 1989 1990#if _LIBCPP_STD_VER > 14 1991 _LIBCPP_INLINE_VISIBILITY 1992 iterator insert(node_type&& __nh) 1993 { 1994 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), 1995 "node_type with incompatible allocator passed to multimap::insert()"); 1996 return __tree_.template __node_handle_insert_multi<node_type>( 1997 _VSTD::move(__nh)); 1998 } 1999 _LIBCPP_INLINE_VISIBILITY 2000 iterator insert(const_iterator __hint, node_type&& __nh) 2001 { 2002 _LIBCPP_ASSERT(__nh.empty() || __nh.get_allocator() == get_allocator(), 2003 "node_type with incompatible allocator passed to multimap::insert()"); 2004 return __tree_.template __node_handle_insert_multi<node_type>( 2005 __hint.__i_, _VSTD::move(__nh)); 2006 } 2007 _LIBCPP_INLINE_VISIBILITY 2008 node_type extract(key_type const& __key) 2009 { 2010 return __tree_.template __node_handle_extract<node_type>(__key); 2011 } 2012 _LIBCPP_INLINE_VISIBILITY 2013 node_type extract(const_iterator __it) 2014 { 2015 return __tree_.template __node_handle_extract<node_type>( 2016 __it.__i_); 2017 } 2018 template <class _Compare2> 2019 _LIBCPP_INLINE_VISIBILITY 2020 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>& __source) 2021 { 2022 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 2023 "merging container with incompatible allocator"); 2024 return __tree_.__node_handle_merge_multi(__source.__tree_); 2025 } 2026 template <class _Compare2> 2027 _LIBCPP_INLINE_VISIBILITY 2028 void merge(multimap<key_type, mapped_type, _Compare2, allocator_type>&& __source) 2029 { 2030 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 2031 "merging container with incompatible allocator"); 2032 return __tree_.__node_handle_merge_multi(__source.__tree_); 2033 } 2034 template <class _Compare2> 2035 _LIBCPP_INLINE_VISIBILITY 2036 void merge(map<key_type, mapped_type, _Compare2, allocator_type>& __source) 2037 { 2038 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 2039 "merging container with incompatible allocator"); 2040 return __tree_.__node_handle_merge_multi(__source.__tree_); 2041 } 2042 template <class _Compare2> 2043 _LIBCPP_INLINE_VISIBILITY 2044 void merge(map<key_type, mapped_type, _Compare2, allocator_type>&& __source) 2045 { 2046 _LIBCPP_ASSERT(__source.get_allocator() == get_allocator(), 2047 "merging container with incompatible allocator"); 2048 return __tree_.__node_handle_merge_multi(__source.__tree_); 2049 } 2050#endif 2051 2052 _LIBCPP_INLINE_VISIBILITY 2053 void clear() _NOEXCEPT {__tree_.clear();} 2054 2055 _LIBCPP_INLINE_VISIBILITY 2056 void swap(multimap& __m) 2057 _NOEXCEPT_(__is_nothrow_swappable<__base>::value) 2058 {__tree_.swap(__m.__tree_);} 2059 2060 _LIBCPP_INLINE_VISIBILITY 2061 iterator find(const key_type& __k) {return __tree_.find(__k);} 2062 _LIBCPP_INLINE_VISIBILITY 2063 const_iterator find(const key_type& __k) const {return __tree_.find(__k);} 2064#if _LIBCPP_STD_VER > 11 2065 template <typename _K2> 2066 _LIBCPP_INLINE_VISIBILITY 2067 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 2068 find(const _K2& __k) {return __tree_.find(__k);} 2069 template <typename _K2> 2070 _LIBCPP_INLINE_VISIBILITY 2071 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 2072 find(const _K2& __k) const {return __tree_.find(__k);} 2073#endif 2074 2075 _LIBCPP_INLINE_VISIBILITY 2076 size_type count(const key_type& __k) const 2077 {return __tree_.__count_multi(__k);} 2078#if _LIBCPP_STD_VER > 11 2079 template <typename _K2> 2080 _LIBCPP_INLINE_VISIBILITY 2081 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type 2082 count(const _K2& __k) const {return __tree_.__count_multi(__k);} 2083#endif 2084 2085#if _LIBCPP_STD_VER > 17 2086 _LIBCPP_INLINE_VISIBILITY 2087 bool contains(const key_type& __k) const {return find(__k) != end();} 2088 template <typename _K2> 2089 _LIBCPP_INLINE_VISIBILITY 2090 typename enable_if<__is_transparent<_Compare, _K2>::value, bool>::type 2091 contains(const _K2& __k) const { return find(__k) != end(); } 2092#endif // _LIBCPP_STD_VER > 17 2093 2094 _LIBCPP_INLINE_VISIBILITY 2095 iterator lower_bound(const key_type& __k) 2096 {return __tree_.lower_bound(__k);} 2097 _LIBCPP_INLINE_VISIBILITY 2098 const_iterator lower_bound(const key_type& __k) const 2099 {return __tree_.lower_bound(__k);} 2100#if _LIBCPP_STD_VER > 11 2101 template <typename _K2> 2102 _LIBCPP_INLINE_VISIBILITY 2103 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 2104 lower_bound(const _K2& __k) {return __tree_.lower_bound(__k);} 2105 2106 template <typename _K2> 2107 _LIBCPP_INLINE_VISIBILITY 2108 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 2109 lower_bound(const _K2& __k) const {return __tree_.lower_bound(__k);} 2110#endif 2111 2112 _LIBCPP_INLINE_VISIBILITY 2113 iterator upper_bound(const key_type& __k) 2114 {return __tree_.upper_bound(__k);} 2115 _LIBCPP_INLINE_VISIBILITY 2116 const_iterator upper_bound(const key_type& __k) const 2117 {return __tree_.upper_bound(__k);} 2118#if _LIBCPP_STD_VER > 11 2119 template <typename _K2> 2120 _LIBCPP_INLINE_VISIBILITY 2121 typename enable_if<__is_transparent<_Compare, _K2>::value,iterator>::type 2122 upper_bound(const _K2& __k) {return __tree_.upper_bound(__k);} 2123 template <typename _K2> 2124 _LIBCPP_INLINE_VISIBILITY 2125 typename enable_if<__is_transparent<_Compare, _K2>::value,const_iterator>::type 2126 upper_bound(const _K2& __k) const {return __tree_.upper_bound(__k);} 2127#endif 2128 2129 _LIBCPP_INLINE_VISIBILITY 2130 pair<iterator,iterator> equal_range(const key_type& __k) 2131 {return __tree_.__equal_range_multi(__k);} 2132 _LIBCPP_INLINE_VISIBILITY 2133 pair<const_iterator,const_iterator> equal_range(const key_type& __k) const 2134 {return __tree_.__equal_range_multi(__k);} 2135#if _LIBCPP_STD_VER > 11 2136 template <typename _K2> 2137 _LIBCPP_INLINE_VISIBILITY 2138 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<iterator,iterator>>::type 2139 equal_range(const _K2& __k) {return __tree_.__equal_range_multi(__k);} 2140 template <typename _K2> 2141 _LIBCPP_INLINE_VISIBILITY 2142 typename enable_if<__is_transparent<_Compare, _K2>::value,pair<const_iterator,const_iterator>>::type 2143 equal_range(const _K2& __k) const {return __tree_.__equal_range_multi(__k);} 2144#endif 2145 2146private: 2147 typedef typename __base::__node __node; 2148 typedef typename __base::__node_allocator __node_allocator; 2149 typedef typename __base::__node_pointer __node_pointer; 2150 2151 typedef __map_node_destructor<__node_allocator> _Dp; 2152 typedef unique_ptr<__node, _Dp> __node_holder; 2153}; 2154 2155#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 2156template<class _InputIterator, class _Compare = less<__iter_key_type<_InputIterator>>, 2157 class _Allocator = allocator<__iter_to_alloc_type<_InputIterator>>, 2158 class = _EnableIf<!__is_allocator<_Compare>::value, void>, 2159 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 2160multimap(_InputIterator, _InputIterator, _Compare = _Compare(), _Allocator = _Allocator()) 2161 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, _Compare, _Allocator>; 2162 2163template<class _Key, class _Tp, class _Compare = less<remove_const_t<_Key>>, 2164 class _Allocator = allocator<pair<const _Key, _Tp>>, 2165 class = _EnableIf<!__is_allocator<_Compare>::value, void>, 2166 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 2167multimap(initializer_list<pair<_Key, _Tp>>, _Compare = _Compare(), _Allocator = _Allocator()) 2168 -> multimap<remove_const_t<_Key>, _Tp, _Compare, _Allocator>; 2169 2170template<class _InputIterator, class _Allocator, 2171 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 2172multimap(_InputIterator, _InputIterator, _Allocator) 2173 -> multimap<__iter_key_type<_InputIterator>, __iter_mapped_type<_InputIterator>, 2174 less<__iter_key_type<_InputIterator>>, _Allocator>; 2175 2176template<class _Key, class _Tp, class _Allocator, 2177 class = _EnableIf<__is_allocator<_Allocator>::value, void>> 2178multimap(initializer_list<pair<_Key, _Tp>>, _Allocator) 2179 -> multimap<remove_const_t<_Key>, _Tp, less<remove_const_t<_Key>>, _Allocator>; 2180#endif 2181 2182#ifndef _LIBCPP_CXX03_LANG 2183template <class _Key, class _Tp, class _Compare, class _Allocator> 2184multimap<_Key, _Tp, _Compare, _Allocator>::multimap(multimap&& __m, const allocator_type& __a) 2185 : __tree_(_VSTD::move(__m.__tree_), typename __base::allocator_type(__a)) 2186{ 2187 if (__a != __m.get_allocator()) 2188 { 2189 const_iterator __e = cend(); 2190 while (!__m.empty()) 2191 __tree_.__insert_multi(__e.__i_, 2192 _VSTD::move(__m.__tree_.remove(__m.begin().__i_)->__value_.__move())); 2193 } 2194} 2195#endif 2196 2197template <class _Key, class _Tp, class _Compare, class _Allocator> 2198inline _LIBCPP_INLINE_VISIBILITY 2199bool 2200operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2201 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2202{ 2203 return __x.size() == __y.size() && _VSTD::equal(__x.begin(), __x.end(), __y.begin()); 2204} 2205 2206template <class _Key, class _Tp, class _Compare, class _Allocator> 2207inline _LIBCPP_INLINE_VISIBILITY 2208bool 2209operator< (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2210 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2211{ 2212 return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); 2213} 2214 2215template <class _Key, class _Tp, class _Compare, class _Allocator> 2216inline _LIBCPP_INLINE_VISIBILITY 2217bool 2218operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2219 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2220{ 2221 return !(__x == __y); 2222} 2223 2224template <class _Key, class _Tp, class _Compare, class _Allocator> 2225inline _LIBCPP_INLINE_VISIBILITY 2226bool 2227operator> (const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2228 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2229{ 2230 return __y < __x; 2231} 2232 2233template <class _Key, class _Tp, class _Compare, class _Allocator> 2234inline _LIBCPP_INLINE_VISIBILITY 2235bool 2236operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2237 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2238{ 2239 return !(__x < __y); 2240} 2241 2242template <class _Key, class _Tp, class _Compare, class _Allocator> 2243inline _LIBCPP_INLINE_VISIBILITY 2244bool 2245operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2246 const multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2247{ 2248 return !(__y < __x); 2249} 2250 2251template <class _Key, class _Tp, class _Compare, class _Allocator> 2252inline _LIBCPP_INLINE_VISIBILITY 2253void 2254swap(multimap<_Key, _Tp, _Compare, _Allocator>& __x, 2255 multimap<_Key, _Tp, _Compare, _Allocator>& __y) 2256 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 2257{ 2258 __x.swap(__y); 2259} 2260 2261#if _LIBCPP_STD_VER > 17 2262template <class _Key, class _Tp, class _Compare, class _Allocator, 2263 class _Predicate> 2264inline _LIBCPP_INLINE_VISIBILITY 2265 typename multimap<_Key, _Tp, _Compare, _Allocator>::size_type 2266 erase_if(multimap<_Key, _Tp, _Compare, _Allocator>& __c, 2267 _Predicate __pred) { 2268 return _VSTD::__libcpp_erase_if_container(__c, __pred); 2269} 2270#endif 2271 2272_LIBCPP_END_NAMESPACE_STD 2273 2274#endif // _LIBCPP_MAP 2275