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