libstdc++
multimap.h
Go to the documentation of this file.
1 // Debugging multimap 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/multimap.h
26  * This file is a GNU debug extension to the Standard C++ Library.
27  */
28 
29 #ifndef _GLIBCXX_DEBUG_MULTIMAP_H
30 #define _GLIBCXX_DEBUG_MULTIMAP_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::multimap 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 multimap
46  multimap<_Key, _Tp, _Compare, _Allocator>, _Allocator,
47  __gnu_debug::_Safe_node_sequence>,
48  public _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Allocator>
49  {
50  typedef _GLIBCXX_STD_C::multimap<
51  _Key, _Tp, _Compare, _Allocator> _Base;
54 
56  typedef typename _Base::iterator _Base_iterator;
58 
59  template<typename _ItT, typename _SeqT, typename _CatT>
60  friend class ::__gnu_debug::_Safe_iterator;
61 
62  // Reference wrapper for base class. Disambiguates multimap(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;
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 
83  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;
93 
94  // 23.3.1.1 construct/copy/destroy:
95 
96 #if __cplusplus < 201103L
97  multimap() : _Base() { }
98 
99  multimap(const multimap& __x)
100  : _Base(__x) { }
101 
102  ~multimap() { }
103 #else
104  multimap() = default;
105  multimap(const multimap&) = default;
106  multimap(multimap&&) = default;
107 
109  const _Compare& __c = _Compare(),
110  const allocator_type& __a = allocator_type())
111  : _Base(__l, __c, __a) { }
112 
113  explicit
114  multimap(const allocator_type& __a)
115  : _Base(__a) { }
116 
117  multimap(const multimap& __m,
118  const __type_identity_t<allocator_type>& __a)
119  : _Base(__m, __a) { }
120 
121  multimap(multimap&& __m, const __type_identity_t<allocator_type>& __a)
122  noexcept( noexcept(_Base(std::move(__m), __a)) )
123  : _Safe(std::move(__m), __a),
124  _Base(std::move(__m), __a) { }
125 
126  multimap(initializer_list<value_type> __l, const allocator_type& __a)
127  : _Base(__l, __a) { }
128 
129  template<typename _InputIterator>
130  multimap(_InputIterator __first, _InputIterator __last,
131  const allocator_type& __a)
133  __glibcxx_check_valid_constructor_range(__first, __last)),
134  __gnu_debug::__base(__last), __a) { }
135 
136 #if __glibcxx_containers_ranges // C++ >= 23
137  /**
138  * @brief Construct a multimap from a range.
139  * @since C++23
140  */
141  template<std::__detail::__container_compatible_range<value_type> _Rg>
142  multimap(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  multimap(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  ~multimap() = default;
156 #endif
157 
158  explicit multimap(const _Compare& __comp,
159  const _Allocator& __a = _Allocator())
160  : _Base(__comp, __a) { }
161 
162  template<typename _InputIterator>
163  multimap(_InputIterator __first, _InputIterator __last,
164  const _Compare& __comp = _Compare(),
165  const _Allocator& __a = _Allocator())
167  __glibcxx_check_valid_constructor_range(__first, __last)),
168  __gnu_debug::__base(__last),
169  __comp, __a) { }
170 
171  multimap(_Base_ref __x)
172  : _Base(__x._M_ref) { }
173 
174 #if __cplusplus >= 201103L
175  multimap&
176  operator=(const multimap&) = default;
177 
178  multimap&
179  operator=(multimap&&) = default;
180 
181  multimap&
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  using _Base::get_allocator;
191 
192  // iterators:
193  iterator
194  begin() _GLIBCXX_NOEXCEPT
195  { return iterator(_Base::begin(), this); }
196 
198  begin() const _GLIBCXX_NOEXCEPT
199  { return const_iterator(_Base::begin(), this); }
200 
201  iterator
202  end() _GLIBCXX_NOEXCEPT
203  { return iterator(_Base::end(), this); }
204 
206  end() const _GLIBCXX_NOEXCEPT
207  { return const_iterator(_Base::end(), this); }
208 
210  rbegin() _GLIBCXX_NOEXCEPT
211  { return reverse_iterator(end()); }
212 
214  rbegin() const _GLIBCXX_NOEXCEPT
215  { return const_reverse_iterator(end()); }
216 
218  rend() _GLIBCXX_NOEXCEPT
219  { return reverse_iterator(begin()); }
220 
222  rend() const _GLIBCXX_NOEXCEPT
223  { return const_reverse_iterator(begin()); }
224 
225 #if __cplusplus >= 201103L
227  cbegin() const noexcept
228  { return const_iterator(_Base::begin(), this); }
229 
231  cend() const noexcept
232  { return const_iterator(_Base::end(), this); }
233 
235  crbegin() const noexcept
236  { return const_reverse_iterator(end()); }
237 
239  crend() const noexcept
240  { return const_reverse_iterator(begin()); }
241 #endif
242 
243  // capacity:
244  using _Base::empty;
245  using _Base::size;
246  using _Base::max_size;
247 
248  // modifiers:
249 #if __cplusplus >= 201103L
250  template<typename... _Args>
251  iterator
252  emplace(_Args&&... __args)
253  { return { _Base::emplace(std::forward<_Args>(__args)...), this }; }
254 
255  template<typename... _Args>
256  iterator
257  emplace_hint(const_iterator __pos, _Args&&... __args)
258  {
259  __glibcxx_check_insert(__pos);
260  return
261  {
262  _Base::emplace_hint(__pos.base(), std::forward<_Args>(__args)...),
263  this
264  };
265  }
266 #endif
267 
268  iterator
269  insert(const value_type& __x)
270  { return iterator(_Base::insert(__x), this); }
271 
272 #if __cplusplus >= 201103L
273  // _GLIBCXX_RESOLVE_LIB_DEFECTS
274  // 2354. Unnecessary copying when inserting into maps with braced-init
275  iterator
276  insert(value_type&& __x)
277  { return { _Base::insert(std::move(__x)), this }; }
278 
279  template<typename _Pair, typename = typename
281  _Pair&&>::value>::type>
282  iterator
283  insert(_Pair&& __x)
284  { return { _Base::insert(std::forward<_Pair>(__x)), this }; }
285 #endif
286 
287 #if __cplusplus >= 201103L
288  void
289  insert(std::initializer_list<value_type> __list)
290  { _Base::insert(__list); }
291 #endif
292 
293  iterator
294 #if __cplusplus >= 201103L
295  insert(const_iterator __position, const value_type& __x)
296 #else
297  insert(iterator __position, const value_type& __x)
298 #endif
299  {
300  __glibcxx_check_insert(__position);
301  return iterator(_Base::insert(__position.base(), __x), this);
302  }
303 
304 #if __cplusplus >= 201103L
305  // _GLIBCXX_RESOLVE_LIB_DEFECTS
306  // 2354. Unnecessary copying when inserting into maps with braced-init
307  iterator
308  insert(const_iterator __position, value_type&& __x)
309  {
310  __glibcxx_check_insert(__position);
311  return { _Base::insert(__position.base(), std::move(__x)), this };
312  }
313 
314  template<typename _Pair, typename = typename
316  _Pair&&>::value>::type>
317  iterator
318  insert(const_iterator __position, _Pair&& __x)
319  {
320  __glibcxx_check_insert(__position);
321  return
322  {
323  _Base::insert(__position.base(), std::forward<_Pair>(__x)),
324  this
325  };
326  }
327 #endif
328 
329  template<typename _InputIterator>
330  void
331  insert(_InputIterator __first, _InputIterator __last)
332  {
334  __glibcxx_check_valid_range2(__first, __last, __dist);
335 
336  if (__dist.second >= __gnu_debug::__dp_sign)
337  _Base::insert(__gnu_debug::__unsafe(__first),
338  __gnu_debug::__unsafe(__last));
339  else
340  _Base::insert(__first, __last);
341  }
342 
343 #if __cplusplus > 201402L
344  using node_type = typename _Base::node_type;
345 
346  node_type
347  extract(const_iterator __position)
348  {
349  __glibcxx_check_erase(__position);
350  this->_M_invalidate_if(_Equal(__position.base()));
351  return _Base::extract(__position.base());
352  }
353 
354  node_type
355  extract(const key_type& __key)
356  {
357  const auto __position = find(__key);
358  if (__position != end())
359  return extract(__position);
360  return {};
361  }
362 
363  iterator
364  insert(node_type&& __nh)
365  { return { _Base::insert(std::move(__nh)), this }; }
366 
367  iterator
368  insert(const_iterator __hint, node_type&& __nh)
369  {
370  __glibcxx_check_insert(__hint);
371  return { _Base::insert(__hint.base(), std::move(__nh)), this };
372  }
373 
374  using _Base::merge;
375 #endif // C++17
376 
377 #if __cplusplus >= 201103L
378  iterator
379  erase(const_iterator __position)
380  {
381  __glibcxx_check_erase(__position);
382  return { erase(__position.base()), this };
383  }
384 
386  erase(_Base_const_iterator __position)
387  {
388  __glibcxx_check_erase2(__position);
389  this->_M_invalidate_if(_Equal(__position));
390  return _Base::erase(__position);
391  }
392 
393  _GLIBCXX_ABI_TAG_CXX11
394  iterator
395  erase(iterator __position)
396  { return erase(const_iterator(__position)); }
397 #else
398  void
399  erase(iterator __position)
400  {
401  __glibcxx_check_erase(__position);
402  this->_M_invalidate_if(_Equal(__position.base()));
403  _Base::erase(__position.base());
404  }
405 #endif
406 
407  size_type
408  erase(const key_type& __x)
409  {
411  _Base::equal_range(__x);
412  size_type __count = 0;
413  _Base_iterator __victim = __victims.first;
414  while (__victim != __victims.second)
415  {
416  this->_M_invalidate_if(_Equal(__victim));
417  _Base::erase(__victim++);
418  ++__count;
419  }
420  return __count;
421  }
422 
423 #if __cplusplus >= 201103L
424  iterator
425  erase(const_iterator __first, const_iterator __last)
426  {
427  // _GLIBCXX_RESOLVE_LIB_DEFECTS
428  // 151. can't currently clear() empty container
429  __glibcxx_check_erase_range(__first, __last);
430  for (_Base_const_iterator __victim = __first.base();
431  __victim != __last.base(); ++__victim)
432  {
433  _GLIBCXX_DEBUG_VERIFY(__victim != _Base::cend(),
434  _M_message(__gnu_debug::__msg_valid_range)
435  ._M_iterator(__first, "first")
436  ._M_iterator(__last, "last"));
437  this->_M_invalidate_if(_Equal(__victim));
438  }
439 
440  return { _Base::erase(__first.base(), __last.base()), this };
441  }
442 #else
443  void
444  erase(iterator __first, iterator __last)
445  {
446  // _GLIBCXX_RESOLVE_LIB_DEFECTS
447  // 151. can't currently clear() empty container
448  __glibcxx_check_erase_range(__first, __last);
449  for (_Base_iterator __victim = __first.base();
450  __victim != __last.base(); ++__victim)
451  {
452  _GLIBCXX_DEBUG_VERIFY(__victim != _Base::end(),
453  _M_message(__gnu_debug::__msg_valid_range)
454  ._M_iterator(__first, "first")
455  ._M_iterator(__last, "last"));
456  this->_M_invalidate_if(_Equal(__victim));
457  }
458  _Base::erase(__first.base(), __last.base());
459  }
460 #endif
461 
462  void
463  swap(multimap& __x)
464  _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
465  {
466  _Safe::_M_swap(__x);
467  _Base::swap(__x);
468  }
469 
470  void
471  clear() _GLIBCXX_NOEXCEPT
472  {
473  this->_M_invalidate_all();
474  _Base::clear();
475  }
476 
477  // observers:
478  using _Base::key_comp;
479  using _Base::value_comp;
480 
481  // 23.3.1.3 multimap operations:
482  iterator
483  find(const key_type& __x)
484  { return iterator(_Base::find(__x), this); }
485 
486 #if __cplusplus > 201103L
487  template<typename _Kt,
488  typename _Req =
489  typename __has_is_transparent<_Compare, _Kt>::type>
490  iterator
491  find(const _Kt& __x)
492  { return { _Base::find(__x), this }; }
493 #endif
494 
496  find(const key_type& __x) const
497  { return const_iterator(_Base::find(__x), this); }
498 
499 #if __cplusplus > 201103L
500  template<typename _Kt,
501  typename _Req =
502  typename __has_is_transparent<_Compare, _Kt>::type>
504  find(const _Kt& __x) const
505  { return { _Base::find(__x), this }; }
506 #endif
507 
508  using _Base::count;
509 
510  iterator
511  lower_bound(const key_type& __x)
512  { return iterator(_Base::lower_bound(__x), this); }
513 
514 #if __cplusplus > 201103L
515  template<typename _Kt,
516  typename _Req =
517  typename __has_is_transparent<_Compare, _Kt>::type>
518  iterator
519  lower_bound(const _Kt& __x)
520  { return { _Base::lower_bound(__x), this }; }
521 #endif
522 
524  lower_bound(const key_type& __x) const
525  { return const_iterator(_Base::lower_bound(__x), this); }
526 
527 #if __cplusplus > 201103L
528  template<typename _Kt,
529  typename _Req =
530  typename __has_is_transparent<_Compare, _Kt>::type>
532  lower_bound(const _Kt& __x) const
533  { return { _Base::lower_bound(__x), this }; }
534 #endif
535 
536  iterator
537  upper_bound(const key_type& __x)
538  { return iterator(_Base::upper_bound(__x), this); }
539 
540 #if __cplusplus > 201103L
541  template<typename _Kt,
542  typename _Req =
543  typename __has_is_transparent<_Compare, _Kt>::type>
544  iterator
545  upper_bound(const _Kt& __x)
546  { return { _Base::upper_bound(__x), this }; }
547 #endif
548 
550  upper_bound(const key_type& __x) const
551  { return const_iterator(_Base::upper_bound(__x), this); }
552 
553 #if __cplusplus > 201103L
554  template<typename _Kt,
555  typename _Req =
556  typename __has_is_transparent<_Compare, _Kt>::type>
558  upper_bound(const _Kt& __x) const
559  { return { _Base::upper_bound(__x), this }; }
560 #endif
561 
563  equal_range(const key_type& __x)
564  {
566  _Base::equal_range(__x);
567  return std::make_pair(iterator(__res.first, this),
568  iterator(__res.second, this));
569  }
570 
571 #if __cplusplus > 201103L
572  template<typename _Kt,
573  typename _Req =
574  typename __has_is_transparent<_Compare, _Kt>::type>
576  equal_range(const _Kt& __x)
577  {
578  auto __res = _Base::equal_range(__x);
579  return { { __res.first, this }, { __res.second, this } };
580  }
581 #endif
582 
584  equal_range(const key_type& __x) const
585  {
587  _Base::equal_range(__x);
588  return std::make_pair(const_iterator(__res.first, this),
589  const_iterator(__res.second, this));
590  }
591 
592 #if __cplusplus > 201103L
593  template<typename _Kt,
594  typename _Req =
595  typename __has_is_transparent<_Compare, _Kt>::type>
597  equal_range(const _Kt& __x) const
598  {
599  auto __res = _Base::equal_range(__x);
600  return { { __res.first, this }, { __res.second, this } };
601  }
602 #endif
603 
604  _Base&
605  _M_base() _GLIBCXX_NOEXCEPT { return *this; }
606 
607  const _Base&
608  _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
609  };
610 
611 #if __cpp_deduction_guides >= 201606
612 
613  template<typename _InputIterator,
614  typename _Compare = less<__iter_key_t<_InputIterator>>,
615  typename _Allocator = allocator<__iter_to_alloc_t<_InputIterator>>,
616  typename = _RequireInputIter<_InputIterator>,
617  typename = _RequireNotAllocator<_Compare>,
618  typename = _RequireAllocator<_Allocator>>
619  multimap(_InputIterator, _InputIterator,
620  _Compare = _Compare(), _Allocator = _Allocator())
621  -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
622  _Compare, _Allocator>;
623 
624  template<typename _Key, typename _Tp, typename _Compare = less<_Key>,
625  typename _Allocator = allocator<pair<const _Key, _Tp>>,
626  typename = _RequireNotAllocator<_Compare>,
627  typename = _RequireAllocator<_Allocator>>
629  _Compare = _Compare(), _Allocator = _Allocator())
631 
632  template<typename _InputIterator, typename _Allocator,
633  typename = _RequireInputIter<_InputIterator>,
634  typename = _RequireAllocator<_Allocator>>
635  multimap(_InputIterator, _InputIterator, _Allocator)
636  -> multimap<__iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>,
637  less<__iter_key_t<_InputIterator>>, _Allocator>;
638 
639  template<typename _Key, typename _Tp, typename _Allocator,
640  typename = _RequireAllocator<_Allocator>>
642  -> multimap<_Key, _Tp, less<_Key>, _Allocator>;
643 
644 #if __glibcxx_containers_ranges // C++ >= 23
645  template<ranges::input_range _Rg,
646  __not_allocator_like _Compare = less<__detail::__range_key_type<_Rg>>,
647  __allocator_like _Alloc =
649  multimap(from_range_t, _Rg&&, _Compare = _Compare(), _Alloc = _Alloc())
651  __detail::__range_mapped_type<_Rg>,
652  _Compare, _Alloc>;
653 
654  template<ranges::input_range _Rg, __allocator_like _Alloc>
655  multimap(from_range_t, _Rg&&, _Alloc)
657  __detail::__range_mapped_type<_Rg>,
659  _Alloc>;
660 #endif
661 #endif
662 
663  template<typename _Key, typename _Tp,
664  typename _Compare, typename _Allocator>
665  inline bool
666  operator==(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
668  { return __lhs._M_base() == __rhs._M_base(); }
669 
670 #if __cpp_lib_three_way_comparison
671  template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
672  inline __detail::__synth3way_t<pair<const _Key, _Tp>>
673  operator<=>(const multimap<_Key, _Tp, _Compare, _Alloc>& __lhs,
675  { return __lhs._M_base() <=> __rhs._M_base(); }
676 #else
677  template<typename _Key, typename _Tp,
678  typename _Compare, typename _Allocator>
679  inline bool
680  operator!=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
681  const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
682  { return __lhs._M_base() != __rhs._M_base(); }
683 
684  template<typename _Key, typename _Tp,
685  typename _Compare, typename _Allocator>
686  inline bool
687  operator<(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
688  const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
689  { return __lhs._M_base() < __rhs._M_base(); }
690 
691  template<typename _Key, typename _Tp,
692  typename _Compare, typename _Allocator>
693  inline bool
694  operator<=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
695  const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
696  { return __lhs._M_base() <= __rhs._M_base(); }
697 
698  template<typename _Key, typename _Tp,
699  typename _Compare, typename _Allocator>
700  inline bool
701  operator>=(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
702  const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
703  { return __lhs._M_base() >= __rhs._M_base(); }
704 
705  template<typename _Key, typename _Tp,
706  typename _Compare, typename _Allocator>
707  inline bool
708  operator>(const multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
709  const multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
710  { return __lhs._M_base() > __rhs._M_base(); }
711 #endif // three-way comparison
712 
713  template<typename _Key, typename _Tp,
714  typename _Compare, typename _Allocator>
715  inline void
716  swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
717  multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
718  _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
719  { __lhs.swap(__rhs); }
720 
721 } // namespace __debug
722 } // namespace std
723 
724 #endif
#define __glibcxx_check_insert(_Position)
Definition: macros.h:143
#define __glibcxx_check_erase_range(_First, _Last)
Definition: macros.h:245
#define __glibcxx_check_erase(_Position)
Definition: macros.h:209
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition: chrono.h:866
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:138
ISO C++ entities toplevel namespace is std.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
Definition: range_access.h:294
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
Definition: range_access.h:274
constexpr _Iterator __base(_Iterator __it)
initializer_list
Define a member typedef type only if a boolean constant is true.
Definition: type_traits:134
is_constructible
Definition: type_traits:1158
The standard allocator, as per C++03 [20.4.1].
Definition: allocator.h:134
Safe iterator wrapper.
constexpr _Iterator & base() noexcept
Return the underlying iterator.
One of the comparison functors.
Definition: stl_function.h:401
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:304
_T1 first
The first member.
Definition: stl_pair.h:308
_T2 second
The second member.
Definition: stl_pair.h:309
A standard container made up of (key,value) pairs, which can be retrieved based on a key,...
Definition: stl_multimap.h:105
void _M_invalidate_if(_Predicate __pred)
Class std::multimap with safety/checking/debug instrumentation.
Definition: multimap.h:49
Safe class dealing with some allocator dependent operations.
Like _Safe_sequence but with a special _M_invalidate_all implementation not invalidating past-the-end...