Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/debug/map.h
1 // Debugging map implementation -*- C++ -*- 2 3 // Copyright (C) 2003-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file debug/map.h 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29 #ifndef _GLIBCXX_DEBUG_MAP_H 30 #define _GLIBCXX_DEBUG_MAP_H 1 31 32 #include <debug/safe_sequence.h> 33 #include <debug/safe_container.h> 34 #include <debug/safe_iterator.h> 35 #include <bits/stl_pair.h> 36 37 namespace std _GLIBCXX_VISIBILITY(default) 38 { 39 namespace __debug 40 { 41 /// Class std::map with safety/checking/debug instrumentation. 42 template<typename _Key, typename _Tp, typename _Compare = std::less<_Key>, 43 typename _Allocator = std::allocator<std::pair<const _Key, _Tp> > > 44 class map 45 : public __gnu_debug::_Safe_container< 46 map<_Key, _Tp, _Compare, _Allocator>, _Allocator, 47 __gnu_debug::_Safe_node_sequence>, 48 public _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Allocator> 49 { 50 typedef _GLIBCXX_STD_C::map< 51 _Key, _Tp, _Compare, _Allocator> _Base; 52 typedef __gnu_debug::_Safe_container< 53 map, _Allocator, __gnu_debug::_Safe_node_sequence> _Safe; 54 55 typedef typename _Base::const_iterator _Base_const_iterator; 56 typedef typename _Base::iterator _Base_iterator; 57 typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal; 58 59 template<typename _ItT, typename _SeqT, typename _CatT> 60 friend class ::__gnu_debug::_Safe_iterator; 61 62 // Reference wrapper for base class. Disambiguates map(const _Base&) 63 // from copy constructor by requiring a user-defined conversion. 64 // See PR libstdc++/90102. 65 struct _Base_ref 66 { 67 _Base_ref(const _Base& __r) : _M_ref(__r) { } 68 69 const _Base& _M_ref; 70 }; 71 72 public: 73 // types: 74 typedef _Key key_type; 75 typedef _Tp mapped_type; 76 typedef std::pair<const _Key, _Tp> value_type; 77 typedef _Compare key_compare; 78 typedef _Allocator allocator_type; 79 typedef typename _Base::reference reference; 80 typedef typename _Base::const_reference const_reference; 81 82 typedef __gnu_debug::_Safe_iterator<_Base_iterator, map> 83 iterator; 84 typedef __gnu_debug::_Safe_iterator<_Base_const_iterator, map> 85 const_iterator; 86 87 typedef typename _Base::size_type size_type; 88 typedef typename _Base::difference_type difference_type; 89 typedef typename _Base::pointer pointer; 90 typedef typename _Base::const_pointer const_pointer; 91 typedef std::reverse_iterator<iterator> reverse_iterator; 92 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 93 94 // 23.3.1.1 construct/copy/destroy: 95 96 #if __cplusplus < 201103L 97 map() : _Base() { } 98 99 map(const map& __x) 100 : _Base(__x) { } 101 102 ~map() { } 103 #else 104 map() = default; 105 map(const map&) = default; 106 map(map&&) = default; 107 108 map(initializer_list<value_type> __l, 109 const _Compare& __c = _Compare(), 110 const allocator_type& __a = allocator_type()) 111 : _Base(__l, __c, __a) { } 112 113 explicit 114 map(const allocator_type& __a) 115 : _Base(__a) { } 116 117 map(const map& __m, const __type_identity_t<allocator_type>& __a) 118 : _Base(__m, __a) { } 119 120 map(map&& __m, const __type_identity_t<allocator_type>& __a) 121 noexcept( noexcept(_Base(std::move(__m), __a)) ) 122 : _Safe(std::move(__m), __a), 123 _Base(std::move(__m), __a) { } 124 125 map(initializer_list<value_type> __l, const allocator_type& __a) 126 : _Base(__l, __a) { } 127 128 template<typename _InputIterator> 129 map(_InputIterator __first, _InputIterator __last, 130 const allocator_type& __a) 131 : _Base(__gnu_debug::__base( 132 __glibcxx_check_valid_constructor_range(__first, __last)), 133 __gnu_debug::__base(__last), __a) 134 { } 135 136 #if __glibcxx_containers_ranges // C++ >= 23 137 /** 138 * @brief Construct a map from a range. 139 * @since C++23 140 */ 141 template<std::__detail::__container_compatible_range<value_type> _Rg> 142 map(std::from_range_t __t, _Rg&& __rg, 143 const _Compare& __c, 144 const allocator_type& __a = allocator_type()) 145 : _Base(__t, std::forward<_Rg>(__rg), __c, __a) 146 { } 147 148 template<std::__detail::__container_compatible_range<value_type> _Rg> 149 map(std::from_range_t __t, _Rg&& __rg, 150 const allocator_type& __a = allocator_type()) 151 : _Base(__t, std::forward<_Rg>(__rg), __a) 152 { } 153 #endif 154 155 ~map() = default; 156 #endif 157 158 map(_Base_ref __x) 159 : _Base(__x._M_ref) { } 160 161 explicit map(const _Compare& __comp, 162 const _Allocator& __a = _Allocator()) 163 : _Base(__comp, __a) { } 164 165 template<typename _InputIterator> 166 map(_InputIterator __first, _InputIterator __last, 167 const _Compare& __comp = _Compare(), 168 const _Allocator& __a = _Allocator()) 169 : _Base(__gnu_debug::__base( 170 __glibcxx_check_valid_constructor_range(__first, __last)), 171 __gnu_debug::__base(__last), 172 __comp, __a) { } 173 174 #if __cplusplus >= 201103L 175 map& 176 operator=(const map&) = default; 177 178 map& 179 operator=(map&&) = default; 180 181 map& 182 operator=(initializer_list<value_type> __l) 183 { 184 _Base::operator=(__l); 185 this->_M_invalidate_all(); 186 return *this; 187 } 188 #endif 189 190 // _GLIBCXX_RESOLVE_LIB_DEFECTS 191 // 133. map missing get_allocator() 192 using _Base::get_allocator; 193 194 // iterators: 195 iterator 196 begin() _GLIBCXX_NOEXCEPT 197 { return iterator(_Base::begin(), this); } 198 199 const_iterator 200 begin() const _GLIBCXX_NOEXCEPT 201 { return const_iterator(_Base::begin(), this); } 202 203 iterator 204 end() _GLIBCXX_NOEXCEPT 205 { return iterator(_Base::end(), this); } 206 207 const_iterator 208 end() const _GLIBCXX_NOEXCEPT 209 { return const_iterator(_Base::end(), this); } 210 211 reverse_iterator 212 rbegin() _GLIBCXX_NOEXCEPT 213 { return reverse_iterator(end()); } 214 215 const_reverse_iterator 216 rbegin() const _GLIBCXX_NOEXCEPT 217 { return const_reverse_iterator(end()); } 218 219 reverse_iterator 220 rend() _GLIBCXX_NOEXCEPT 221 { return reverse_iterator(begin()); } 222 223 const_reverse_iterator 224 rend() const _GLIBCXX_NOEXCEPT 225 { return const_reverse_iterator(begin()); } 226 227 #if __cplusplus >= 201103L 228 const_iterator 229 cbegin() const noexcept 230 { return const_iterator(_Base::begin(), this); } 231 232 const_iterator 233 cend() const noexcept 234 { return const_iterator(_Base::end(), this); } 235 236 const_reverse_iterator 237 crbegin() const noexcept 238 { return const_reverse_iterator(end()); } 239 240 const_reverse_iterator 241 crend() const noexcept 242 { return const_reverse_iterator(begin()); } 243 #endif 244 245 // capacity: 246 using _Base::empty; 247 using _Base::size; 248 using _Base::max_size; 249 250 // 23.3.1.2 element access: 251 using _Base::operator[]; 252 253 // _GLIBCXX_RESOLVE_LIB_DEFECTS 254 // DR 464. Suggestion for new member functions in standard containers. 255 using _Base::at; 256 257 // modifiers: 258 #if __cplusplus >= 201103L 259 template<typename... _Args> 260 std::pair<iterator, bool> 261 emplace(_Args&&... __args) 262 { 263 auto __res = _Base::emplace(std::forward<_Args>(__args)...); 264 return { { __res.first, this }, __res.second }; 265 } 266 267 template<typename... _Args> 268 iterator 269 emplace_hint(const_iterator __pos, _Args&&... __args) 270 { 271 __glibcxx_check_insert(__pos); 272 return 273 { 274 _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...), 275 this 276 }; 277 } 278 #endif 279 280 std::pair<iterator, bool> 281 insert(const value_type& __x) 282 { 283 std::pair<_Base_iterator, bool> __res = _Base::insert(__x); 284 return std::pair<iterator, bool>(iterator(__res.first, this), 285 __res.second); 286 } 287 288 #if __cplusplus >= 201103L 289 // _GLIBCXX_RESOLVE_LIB_DEFECTS 290 // 2354. Unnecessary copying when inserting into maps with braced-init 291 std::pair<iterator, bool> 292 insert(value_type&& __x) 293 { 294 auto __res = _Base::insert(std::move(__x)); 295 return { { __res.first, this }, __res.second }; 296 } 297 298 template<typename _Pair, typename = typename 299 std::enable_if<std::is_constructible<value_type, 300 _Pair&&>::value>::type> 301 std::pair<iterator, bool> 302 insert(_Pair&& __x) 303 { 304 auto __res = _Base::insert(std::forward<_Pair>(__x)); 305 return { { __res.first, this }, __res.second }; 306 } 307 #endif 308 309 #if __cplusplus >= 201103L 310 void 311 insert(std::initializer_list<value_type> __list) 312 { _Base::insert(__list); } 313 #endif 314 315 iterator 316 #if __cplusplus >= 201103L 317 insert(const_iterator __position, const value_type& __x) 318 #else 319 insert(iterator __position, const value_type& __x) 320 #endif 321 { 322 __glibcxx_check_insert(__position); 323 return iterator(_Base::insert(__position.base(), __x), this); 324 } 325 326 #if __cplusplus >= 201103L 327 // _GLIBCXX_RESOLVE_LIB_DEFECTS 328 // 2354. Unnecessary copying when inserting into maps with braced-init 329 iterator 330 insert(const_iterator __position, value_type&& __x) 331 { 332 __glibcxx_check_insert(__position); 333 return { _Base::insert(__position.base(), std::move(__x)), this }; 334 } 335 336 template<typename _Pair, typename = typename 337 std::enable_if<std::is_constructible<value_type, 338 _Pair&&>::value>::type> 339 iterator 340 insert(const_iterator __position, _Pair&& __x) 341 { 342 __glibcxx_check_insert(__position); 343 return 344 { 345 _Base::insert(__position.base(), std::forward<_Pair>(__x)), 346 this 347 }; 348 } 349 #endif 350 351 template<typename _InputIterator> 352 void 353 insert(_InputIterator __first, _InputIterator __last) 354 { 355 typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist; 356 __glibcxx_check_valid_range2(__first, __last, __dist); 357 358 if (__dist.second >= __gnu_debug::__dp_sign) 359 _Base::insert(__gnu_debug::__unsafe(__first), 360 __gnu_debug::__unsafe(__last)); 361 else 362 _Base::insert(__first, __last); 363 } 364 365 366 #ifdef __glibcxx_map_try_emplace // C++ >= 17 && HOSTED 367 template <typename... _Args> 368 pair<iterator, bool> 369 try_emplace(const key_type& __k, _Args&&... __args) 370 { 371 auto __res = _Base::try_emplace(__k, 372 std::forward<_Args>(__args)...); 373 return { { __res.first, this }, __res.second }; 374 } 375 376 template <typename... _Args> 377 pair<iterator, bool> 378 try_emplace(key_type&& __k, _Args&&... __args) 379 { 380 auto __res = _Base::try_emplace(std::move(__k), 381 std::forward<_Args>(__args)...); 382 return { { __res.first, this }, __res.second }; 383 } 384 385 template <typename... _Args> 386 iterator 387 try_emplace(const_iterator __hint, const key_type& __k, 388 _Args&&... __args) 389 { 390 __glibcxx_check_insert(__hint); 391 return 392 { 393 _Base::try_emplace(__hint.base(), __k, 394 std::forward<_Args>(__args)...), 395 this 396 }; 397 } 398 399 template <typename... _Args> 400 iterator 401 try_emplace(const_iterator __hint, key_type&& __k, _Args&&... __args) 402 { 403 __glibcxx_check_insert(__hint); 404 return 405 { 406 _Base::try_emplace(__hint.base(), std::move(__k), 407 std::forward<_Args>(__args)...), 408 this 409 }; 410 } 411 412 template <typename _Obj> 413 std::pair<iterator, bool> 414 insert_or_assign(const key_type& __k, _Obj&& __obj) 415 { 416 auto __res = _Base::insert_or_assign(__k, 417 std::forward<_Obj>(__obj)); 418 return { { __res.first, this }, __res.second }; 419 } 420 421 template <typename _Obj> 422 std::pair<iterator, bool> 423 insert_or_assign(key_type&& __k, _Obj&& __obj) 424 { 425 auto __res = _Base::insert_or_assign(std::move(__k), 426 std::forward<_Obj>(__obj)); 427 return { { __res.first, this }, __res.second }; 428 } 429 430 template <typename _Obj> 431 iterator 432 insert_or_assign(const_iterator __hint, 433 const key_type& __k, _Obj&& __obj) 434 { 435 __glibcxx_check_insert(__hint); 436 return 437 { 438 _Base::insert_or_assign(__hint.base(), __k, 439 std::forward<_Obj>(__obj)), 440 this 441 }; 442 } 443 444 template <typename _Obj> 445 iterator 446 insert_or_assign(const_iterator __hint, key_type&& __k, _Obj&& __obj) 447 { 448 __glibcxx_check_insert(__hint); 449 return 450 { 451 _Base::insert_or_assign(__hint.base(), std::move(__k), 452 std::forward<_Obj>(__obj)), 453 this 454 }; 455 } 456 #endif // C++17 457 458 #if __cplusplus > 201402L 459 using node_type = typename _Base::node_type; 460 using insert_return_type = _Node_insert_return<iterator, node_type>; 461 462 node_type 463 extract(const_iterator __position) 464 { 465 __glibcxx_check_erase(__position); 466 this->_M_invalidate_if(_Equal(__position.base())); 467 return _Base::extract(__position.base()); 468 } 469 470 node_type 471 extract(const key_type& __key) 472 { 473 const auto __position = find(__key); 474 if (__position != end()) 475 return extract(__position); 476 return {}; 477 } 478 479 insert_return_type 480 insert(node_type&& __nh) 481 { 482 auto __ret = _Base::insert(std::move(__nh)); 483 return 484 { { __ret.position, this }, __ret.inserted, std::move(__ret.node) }; 485 } 486 487 iterator 488 insert(const_iterator __hint, node_type&& __nh) 489 { 490 __glibcxx_check_insert(__hint); 491 return { _Base::insert(__hint.base(), std::move(__nh)), this }; 492 } 493 494 using _Base::merge; 495 #endif // C++17 496 497 #if __cplusplus >= 201103L 498 iterator 499 erase(const_iterator __position) 500 { 501 __glibcxx_check_erase(__position); 502 return { erase(__position.base()), this }; 503 } 504 505 _Base_iterator 506 erase(_Base_const_iterator __position) 507 { 508 __glibcxx_check_erase2(__position); 509 this->_M_invalidate_if(_Equal(__position)); 510 return _Base::erase(__position); 511 } 512 513 _GLIBCXX_ABI_TAG_CXX11 514 iterator 515 erase(iterator __position) 516 { return erase(const_iterator(__position)); } 517 #else 518 void 519 erase(iterator __position) 520 { 521 __glibcxx_check_erase(__position); 522 this->_M_invalidate_if(_Equal(__position.base())); 523 _Base::erase(__position.base()); 524 } 525 #endif 526 527 size_type 528 erase(const key_type& __x) 529 { 530 _Base_iterator __victim = _Base::find(__x); 531 if (__victim == _Base::end()) 532 return 0; 533 else 534 { 535 this->_M_invalidate_if(_Equal(__victim)); 536 _Base::erase(__victim); 537 return 1; 538 } 539 } 540 541 #if __cplusplus >= 201103L 542 iterator 543 erase(const_iterator __first, const_iterator __last) 544 { 545 // _GLIBCXX_RESOLVE_LIB_DEFECTS 546 // 151. can't currently clear() empty container 547 __glibcxx_check_erase_range(__first, __last); 548 for (_Base_const_iterator __victim = __first.base(); 549 __victim != __last.base(); ++__victim) 550 { 551 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(), 552 _M_message(__gnu_debug::__msg_valid_range) 553 ._M_iterator(__first, "first") 554 ._M_iterator(__last, "last")); 555 this->_M_invalidate_if(_Equal(__victim)); 556 } 557 558 return { _Base::erase(__first.base(), __last.base()), this }; 559 } 560 #else 561 void 562 erase(iterator __first, iterator __last) 563 { 564 // _GLIBCXX_RESOLVE_LIB_DEFECTS 565 // 151. can't currently clear() empty container 566 __glibcxx_check_erase_range(__first, __last); 567 for (_Base_iterator __victim = __first.base(); 568 __victim != __last.base(); ++__victim) 569 { 570 _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(), 571 _M_message(__gnu_debug::__msg_valid_range) 572 ._M_iterator(__first, "first") 573 ._M_iterator(__last, "last")); 574 this->_M_invalidate_if(_Equal(__victim)); 575 } 576 _Base::erase(__first.base(), __last.base()); 577 } 578 #endif 579 580 void 581 swap(map& __x) 582 _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) ) 583 { 584 _Safe::_M_swap(__x); 585 _Base::swap(__x); 586 } 587 588 void 589 clear() _GLIBCXX_NOEXCEPT 590 { 591 this->_M_invalidate_all(); 592 _Base::clear(); 593 } 594 595 // observers: 596 using _Base::key_comp; 597 using _Base::value_comp; 598 599 // 23.3.1.3 map operations: 600 iterator 601 find(const key_type& __x) 602 { return iterator(_Base::find(__x), this); } 603 604 #if __cplusplus > 201103L 605 template<typename _Kt, 606 typename _Req = 607 typename __has_is_transparent<_Compare, _Kt>::type> 608 iterator 609 find(const _Kt& __x) 610 { return { _Base::find(__x), this }; } 611 #endif 612 613 const_iterator 614 find(const key_type& __x) const 615 { return const_iterator(_Base::find(__x), this); } 616 617 #if __cplusplus > 201103L 618 template<typename _Kt, 619 typename _Req = 620 typename __has_is_transparent<_Compare, _Kt>::type> 621 const_iterator 622 find(const _Kt& __x) const 623 { return { _Base::find(__x), this }; } 624 #endif 625 626 using _Base::count; 627 628 iterator 629 lower_bound(const key_type& __x) 630 { return iterator(_Base::lower_bound(__x), this); } 631 632 #if __cplusplus > 201103L 633 template<typename _Kt, 634 typename _Req = 635 typename __has_is_transparent<_Compare, _Kt>::type> 636 iterator 637 lower_bound(const _Kt& __x) 638 { return { _Base::lower_bound(__x), this }; } 639 #endif 640 641 const_iterator 642 lower_bound(const key_type& __x) const 643 { return const_iterator(_Base::lower_bound(__x), this); } 644 645 #if __cplusplus > 201103L 646 template<typename _Kt, 647 typename _Req = 648 typename __has_is_transparent<_Compare, _Kt>::type> 649 const_iterator 650 lower_bound(const _Kt& __x) const 651 { return { _Base::lower_bound(__x), this }; } 652 #endif 653 654 iterator 655 upper_bound(const key_type& __x) 656 { return iterator(_Base::upper_bound(__x), this); } 657 658 #if __cplusplus > 201103L 659 template<typename _Kt, 660 typename _Req = 661 typename __has_is_transparent<_Compare, _Kt>::type> 662 iterator 663 upper_bound(const _Kt& __x) 664 { return { _Base::upper_bound(__x), this }; } 665 #endif 666 667 const_iterator 668 upper_bound(const key_type& __x) const 669 { return const_iterator(_Base::upper_bound(__x), this); } 670 671 #if __cplusplus > 201103L 672 template<typename _Kt, 673 typename _Req = 674 typename __has_is_transparent<_Compare, _Kt>::type> 675 const_iterator 676 upper_bound(const _Kt& __x) const 677 { return { _Base::upper_bound(__x), this }; } 678 #endif 679 680 std::pair<iterator,iterator> 681 equal_range(const key_type& __x) 682 { 683 std::pair<_Base_iterator, _Base_iterator> __res = 684 _Base::equal_range(__x); 685 return std::make_pair(iterator(__res.first, this), 686 iterator(__res.second, this)); 687 } 688 689 #if __cplusplus > 201103L 690 template<typename _Kt, 691 typename _Req = 692 typename __has_is_transparent<_Compare, _Kt>::type> 693 std::pair<iterator, iterator> 694 equal_range(const _Kt& __x) 695 { 696 auto __res = _Base::equal_range(__x); 697 return { { __res.first, this }, { __res.second, this } }; 698 } 699 #endif 700 701 std::pair<const_iterator,const_iterator> 702 equal_range(const key_type& __x) const 703 { 704 std::pair<_Base_const_iterator, _Base_const_iterator> __res = 705 _Base::equal_range(__x); 706 return std::make_pair(const_iterator(__res.first, this), 707 const_iterator(__res.second, this)); 708 } 709 710 #if __cplusplus > 201103L 711 template<typename _Kt, 712 typename _Req = 713 typename __has_is_transparent<_Compare, _Kt>::type> 714 std::pair<const_iterator, const_iterator> 715 equal_range(const _Kt& __x) const 716 { 717 auto __res = _Base::equal_range(__x); 718 return { { __res.first, this }, { __res.second, this } }; 719 } 720 #endif 721 722 _Base& 723 _M_base() _GLIBCXX_NOEXCEPT { return *this; } 724 725 const _Base& 726 _M_base() const _GLIBCXX_NOEXCEPT { return *this; } 727 }; 728 729 #if __cpp_deduction_guides >= 201606 730 731 template<typename _InputIterator, 732 typename _Compare = less<__iter_key_t<_InputIterator>>, 733 typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>, 734 typename = _RequireInputIter<_InputIterator>, 735 typename = _RequireNotAllocator<_Compare>, 736 typename = _RequireAllocator<_Allocator>> 737 map(_InputIterator, _InputIterator, 738 _Compare = _Compare(), _Allocator = _Allocator()) 739 -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, 740 _Compare, _Allocator>; 741 742 template<typename _Key, typename _Tp, typename _Compare = less<_Key>, 743 typename _Allocator = allocator<pair<const _Key, _Tp>>, 744 typename = _RequireNotAllocator<_Compare>, 745 typename = _RequireAllocator<_Allocator>> 746 map(initializer_list<pair<_Key, _Tp>>, 747 _Compare = _Compare(), _Allocator = _Allocator()) 748 -> map<_Key, _Tp, _Compare, _Allocator>; 749 750 template <typename _InputIterator, typename _Allocator, 751 typename = _RequireInputIter<_InputIterator>, 752 typename = _RequireAllocator<_Allocator>> 753 map(_InputIterator, _InputIterator, _Allocator) 754 -> map<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>, 755 less<__iter_key_t<_InputIterator>>, _Allocator>; 756 757 template<typename _Key, typename _Tp, typename _Allocator, 758 typename = _RequireAllocator<_Allocator>> 759 map(initializer_list<pair<_Key, _Tp>>, _Allocator) 760 -> map<_Key, _Tp, less<_Key>, _Allocator>; 761 762 #if __glibcxx_containers_ranges // C++ >= 23 763 template<ranges::input_range _Rg, 764 __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>, 765 __allocator_like _Alloc = 766 std::allocator<__detail::__range_to_alloc_type<_Rg>>> 767 map(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc()) 768 -> map<__detail::__range_key_type<_Rg>, 769 __detail::__range_mapped_type<_Rg>, 770 _Compare, _Alloc>; 771 772 template<ranges::input_range _Rg, __allocator_like _Alloc> 773 map(from_range_t, _Rg&&, _Alloc) 774 -> map<__detail::__range_key_type<_Rg>, 775 __detail::__range_mapped_type<_Rg>, 776 less<__detail::__range_key_type<_Rg>>, 777 _Alloc>; 778 #endif 779 #endif // deduction guides 780 781 template<typename _Key, typename _Tp, 782 typename _Compare, typename _Allocator> 783 inline bool 784 operator==(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 785 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 786 { return __lhs._M_base() == __rhs._M_base(); } 787 788 #if __cpp_lib_three_way_comparison 789 template<typename _Key, typename _Tp, typename _Compare, typename _Alloc> 790 inline __detail::__synth3way_t<pair<const _Key, _Tp>> 791 operator<=>(const map<_Key, _Tp, _Compare, _Alloc>& __lhs, 792 const map<_Key, _Tp, _Compare, _Alloc>& __rhs) 793 { return __lhs._M_base() <=> __rhs._M_base(); } 794 #else 795 template<typename _Key, typename _Tp, 796 typename _Compare, typename _Allocator> 797 inline bool 798 operator!=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 799 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 800 { return __lhs._M_base() != __rhs._M_base(); } 801 802 template<typename _Key, typename _Tp, 803 typename _Compare, typename _Allocator> 804 inline bool 805 operator<(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 806 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 807 { return __lhs._M_base() < __rhs._M_base(); } 808 809 template<typename _Key, typename _Tp, 810 typename _Compare, typename _Allocator> 811 inline bool 812 operator<=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 813 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 814 { return __lhs._M_base() <= __rhs._M_base(); } 815 816 template<typename _Key, typename _Tp, 817 typename _Compare, typename _Allocator> 818 inline bool 819 operator>=(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 820 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 821 { return __lhs._M_base() >= __rhs._M_base(); } 822 823 template<typename _Key, typename _Tp, 824 typename _Compare, typename _Allocator> 825 inline bool 826 operator>(const map<_Key, _Tp, _Compare, _Allocator>& __lhs, 827 const map<_Key, _Tp, _Compare, _Allocator>& __rhs) 828 { return __lhs._M_base() > __rhs._M_base(); } 829 #endif // three-way comparison 830 831 template<typename _Key, typename _Tp, 832 typename _Compare, typename _Allocator> 833 inline void 834 swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs, 835 map<_Key, _Tp, _Compare, _Allocator>& __rhs) 836 _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs))) 837 { __lhs.swap(__rhs); } 838 839 } // namespace __debug 840 } // namespace std 841 842 #endif