11#ifndef INCLUDED_BSLSTL_MULTIMAP_CPP03
12#define INCLUDED_BSLSTL_MULTIMAP_CPP03
63#ifdef COMPILING_BSLSTL_MULTIMAP_H
88 class COMPARATOR = std::less<KEY>,
89 class ALLOCATOR = allocator<pair<const KEY, VALUE> > >
96 typedef pair<const KEY, VALUE> ValueType;
100 typedef BloombergLP::bslstl::MapComparator<KEY, VALUE, COMPARATOR>
105 typedef BloombergLP::bslstl::TreeNode<ValueType> Node;
109 typedef BloombergLP::bslstl::TreeNodePool<ValueType, ALLOCATOR>
118 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
129 class DataWrapper :
public Comparator {
136 DataWrapper(
const DataWrapper&);
137 DataWrapper& operator=(
const DataWrapper&);
145 DataWrapper(
const COMPARATOR& comparator,
146 const ALLOCATOR& basicAllocator);
154 BloombergLP::bslmf::MovableRef<DataWrapper> original);
160 NodeFactory& nodeFactory();
166 const NodeFactory& nodeFactory()
const;
170 DataWrapper d_compAndAlloc;
174 BloombergLP::bslalg::RbTreeAnchor d_tree;
192 typedef BloombergLP::bslstl::TreeIterator<
value_type,
196 typedef BloombergLP::bslstl::TreeIterator<
const value_type,
212 class value_compare {
275 static Node *toNode(BloombergLP::bslalg::RbTreeNode *node);
281 static const Node *toNode(
const BloombergLP::bslalg::RbTreeNode *node);
287 Comparator& comparator();
291 NodeFactory& nodeFactory();
298 void quickSwapExchangeAllocators(
multimap& other);
307 void quickSwapRetainAllocators(
multimap& other);
313 template <
class INPUT_ITERATOR,
class SENTINEL>
314 void constructFromRange(INPUT_ITERATOR first, SENTINEL last);
316#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
317 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
327 template <
class INPUT_ITERATOR,
class SENTINEL>
328 void constructFromRange(INPUT_ITERATOR first,
334 template <
class INPUT_ITERATOR,
class SENTINEL>
335 void insertFromRange(INPUT_ITERATOR first,
338#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
339 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
347 template <
class INPUT_ITERATOR,
class SENTINEL>
348 void insertFromRange(INPUT_ITERATOR first,
357 const Comparator& comparator()
const;
361 const NodeFactory& nodeFactory()
const;
378 explicit multimap(
const COMPARATOR& comparator,
379 const ALLOCATOR& basicAllocator = ALLOCATOR())
380 : d_compAndAlloc(comparator, basicAllocator)
397 explicit multimap(
const ALLOCATOR& basicAllocator);
416 multimap(BloombergLP::bslmf::MovableRef<multimap> original);
428 const typename type_identity<ALLOCATOR>::type& basicAllocator);
443 multimap(BloombergLP::bslmf::MovableRef<multimap> original,
444 const typename type_identity<ALLOCATOR>::type& basicAllocator);
473 template <
class INPUT_ITERATOR>
476 const COMPARATOR& comparator = COMPARATOR(),
477 const ALLOCATOR& basicAllocator = ALLOCATOR());
478 template <
class INPUT_ITERATOR>
481 const ALLOCATOR& basicAllocator);
501 template <
class RANGE>
506 const COMPARATOR& comparator = COMPARATOR(),
507 const ALLOCATOR& basicAllocator = ALLOCATOR())
508 : d_compAndAlloc(comparator, basicAllocator)
513#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
514 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
515 if constexpr (std::ranges::sized_range<RANGE>) {
516 constructFromRange(bsl::ranges::begin(range),
517 bsl::ranges::end (range),
518 bsl::ranges::size (range));
522 constructFromRange(bsl::ranges::begin(range),
523 bsl::ranges::end (range));
527 template <
class RANGE>
531 const ALLOCATOR& basicAllocator)
532 : d_compAndAlloc(COMPARATOR(), basicAllocator)
540 nodeFactory().allocator());
541 quickSwapRetainAllocators(other);
544#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
563 multimap(std::initializer_list<value_type> values,
564 const COMPARATOR& comparator = COMPARATOR(),
565 const ALLOCATOR& basicAllocator = ALLOCATOR());
566 multimap(std::initializer_list<value_type> values,
567 const ALLOCATOR& basicAllocator);
588 AllocatorTraits::is_always_equal::value &&
589 std::is_nothrow_move_assignable<COMPARATOR>::value);
605#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
646#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
647 template <
class ALT_VALUE_TYPE>
649#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
650 template <
class ALT_VALUE_TYPE>
651 typename enable_if<is_convertible<ALT_VALUE_TYPE, value_type>::value,
663 template <
class ALT_VALUE_TYPE>
664 typename enable_if<std::is_constructible<
value_type,
665 ALT_VALUE_TYPE&&>::value,
690#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
691 template <
class ALT_VALUE_TYPE>
693#elif !defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
694 template <
class ALT_VALUE_TYPE>
695 typename enable_if<is_convertible<ALT_VALUE_TYPE, value_type>::value,
712 template <
class ALT_VALUE_TYPE>
713 typename enable_if<std::is_constructible<
value_type,
714 ALT_VALUE_TYPE&&>::value,
739 template <
class INPUT_ITERATOR>
740 void insert(INPUT_ITERATOR first, INPUT_ITERATOR last);
751 template <
class RANGE>
757#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
758 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
759 if constexpr (std::ranges::sized_range<RANGE>) {
760 insertFromRange(bsl::ranges::begin(range),
761 bsl::ranges::end (range),
762 bsl::ranges::size (range));
766 insertFromRange(bsl::ranges::begin(range),
767 bsl::ranges::end (range));
771#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
786#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
792 void insert(std::initializer_list<value_type> values);
795#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
798#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT
799#define BSLSTL_MULTIMAP_VARIADIC_LIMIT 2
801#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT_A
802#define BSLSTL_MULTIMAP_VARIADIC_LIMIT_A BSLSTL_MULTIMAP_VARIADIC_LIMIT
805#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
809#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
810 template <
class Args_1>
814#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
815 template <
class Args_1,
822#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 0
826#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 1
827 template <
class Args_1>
832#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_A >= 2
833 template <
class Args_1,
844 template <
class... Args>
847 template <
class... Args>
872 template <
class t_KEY>
874 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
885 while (it !=
end() && !
key_comp()(key, it->first)) {
905 AllocatorTraits::is_always_equal::value &&
906 bsl::is_nothrow_swappable<COMPARATOR>::value);
943 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
944 d_tree, this->comparator(), key));
953 template <
class LOOKUP_KEY>
955 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
958 find(
const LOOKUP_KEY& key)
960 return iterator(BloombergLP::bslalg::RbTreeUtil::find(
961 d_tree, this->comparator(), key));
977 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
978 d_tree, this->comparator(), key));
992 template <
class LOOKUP_KEY>
994 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
999 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1000 d_tree, this->comparator(), key));
1016 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1017 d_tree, this->comparator(), key));
1031 template <
class LOOKUP_KEY>
1033 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1038 return iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1039 d_tree, this->comparator(), key));
1057 if (endIt !=
end() && !comparator()(key, *endIt.node())) {
1074 template <
class LOOKUP_KEY>
1076 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1078 pair<iterator, iterator> >::type
1083 if (endIt !=
end() && !comparator()(key, *endIt.node())) {
1086 return pair<iterator, iterator>(startIt, endIt);
1149 template <class LOOKUP_KEY>
1150 typename
bsl::enable_if<
1151 BloombergLP::
bslmf::IsTransparentPredicate<COMPARATOR,
1154 contains(const LOOKUP_KEY& key)
const
1201 d_tree, this->comparator(), key));
1210 template <
class LOOKUP_KEY>
1212 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1215 find(
const LOOKUP_KEY& key)
const
1218 d_tree, this->comparator(), key));
1230 while (it !=
end() && !comparator()(key, *it.node())) {
1241 template <
class LOOKUP_KEY>
1243 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1246 count(
const LOOKUP_KEY& key)
const
1251 while (it !=
end() && !comparator()(key, *it.node())) {
1272 return iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1273 d_tree, this->comparator(), key));
1288 template <
class LOOKUP_KEY>
1290 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1295 return const_iterator(BloombergLP::bslalg::RbTreeUtil::lowerBound(
1296 d_tree, this->comparator(), key));
1312 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1313 d_tree, this->comparator(), key));
1327 template <
class LOOKUP_KEY>
1329 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1334 return const_iterator(BloombergLP::bslalg::RbTreeUtil::upperBound(
1335 d_tree, this->comparator(), key));
1353 if (endIt !=
end() && !comparator()(key, *endIt.node())) {
1370 template <
class LOOKUP_KEY>
1372 BloombergLP::bslmf::IsTransparentPredicate<COMPARATOR,
1374 pair<const_iterator, const_iterator> >::type
1379 if (endIt !=
end() && !comparator()(key, *endIt.node())) {
1382 return pair<const_iterator, const_iterator>(startIt, endIt);
1388#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1398 class INPUT_ITERATOR,
1399 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1401 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1402 class COMPARATOR = std::less<KEY>,
1404 BloombergLP::bslstl::IteratorUtil::IterToAlloc_t<INPUT_ITERATOR>>,
1405 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1406 class = bsl::enable_if_t<
bsl::IsStdAllocator_v<ALLOCATOR>>
1408multimap(INPUT_ITERATOR,
1410 COMPARATOR = COMPARATOR(),
1411 ALLOCATOR = ALLOCATOR())
1412-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1421 class INPUT_ITERATOR,
1424 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1426 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1427 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1428 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1430multimap(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, ALLOC *)
1431-> multimap<KEY, VALUE, COMPARATOR>;
1438 class INPUT_ITERATOR,
1440 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1442 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1443 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1445multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOCATOR)
1446-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1453 class INPUT_ITERATOR,
1455 class KEY = BloombergLP::bslstl::IteratorUtil::IterKey_t<INPUT_ITERATOR>,
1457 BloombergLP::bslstl::IteratorUtil::IterMapped_t<INPUT_ITERATOR>,
1458 class DEFAULT_ALLOCATOR = bsl::allocator<pair<const KEY, VALUE>>,
1459 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1461multimap(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1462-> multimap<KEY, VALUE>;
1473 class COMPARATOR = std::less<KEY>,
1474 class ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1475 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<COMPARATOR>>,
1476 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1478multimap(std::initializer_list<pair<const KEY, VALUE>>,
1479 COMPARATOR = COMPARATOR(),
1480 ALLOCATOR = ALLOCATOR())
1481-> multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>;
1494 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1495 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1497multimap(std::initializer_list<pair<const KEY, VALUE>>, COMPARATOR, ALLOC *)
1498-> multimap<KEY, VALUE, COMPARATOR>;
1510 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>
1512multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOCATOR)
1513-> multimap<KEY, VALUE, std::less<KEY>, ALLOCATOR>;
1523 class DEFAULT_ALLOCATOR = bsl::allocator<bsl::pair<const KEY, VALUE>>,
1524 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1526multimap(std::initializer_list<pair<const KEY, VALUE>>, ALLOC *)
1527-> multimap<KEY, VALUE>;
1540template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1541bool operator==(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1542 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1544#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1545template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1546bool operator!=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1547 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1558#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1564template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1565BloombergLP::bslalg::SynthThreeWayUtil::Result<pair<const KEY, VALUE>>
1566operator<=>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1567 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1571template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1572bool operator<(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1573 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1586template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1587bool operator>(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1588 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1597template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1598bool operator<=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1599 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1608template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1609bool operator>=(const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
1610 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs);
1630typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
1631erase_if(multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& m,
1632 PREDICATE predicate);
1652template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1653void
swap(multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& a,
1654 multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& b)
1666template <class KEY, class VALUE, class COMPARATOR, class ALLOCATOR>
1668multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1669 const COMPARATOR& comparator,
1670 const ALLOCATOR& basicAllocator)
1671:
::bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(comparator)
1672, d_pool(basicAllocator)
1676template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1678multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::DataWrapper(
1679 BloombergLP::bslmf::MovableRef<DataWrapper> original)
1680: ::
bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator(
1681 MoveUtil::access(original).keyComparator())
1682, d_pool(MoveUtil::move(MoveUtil::access(original).d_pool))
1687template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1689typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1690multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
1696template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1698const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1699multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::DataWrapper::nodeFactory()
const
1708template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1710multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare::value_compare(
1711 COMPARATOR comparator)
1716template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1718bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare::operator()(
1719 const value_type& x,
1720 const value_type& y)
const
1722 return comp(x.first, y.first);
1730template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1732typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
1733multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator()
1735 return d_compAndAlloc;
1738template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1740typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1741multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory()
1743 return d_compAndAlloc.nodeFactory();
1746template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1748void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapExchangeAllocators(
1751 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1752 nodeFactory().swapExchangeAllocators(other.nodeFactory());
1760 if (
sizeof(NodeFactory) !=
sizeof(DataWrapper)) {
1761 comparator().swap(other.comparator());
1765template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1767void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::quickSwapRetainAllocators(
1770 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &other.d_tree);
1771 nodeFactory().swapRetainAllocators(other.nodeFactory());
1775 if (
sizeof(NodeFactory) !=
sizeof(DataWrapper)) {
1776 comparator().swap(other.comparator());
1780template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1781template <
class INPUT_ITERATOR,
class SENTINEL>
1784multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::constructFromRange(
1785 INPUT_ITERATOR first,
1788 if (first == last) {
1793 BloombergLP::bslstl::IteratorUtil::
1794 canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()) {
1795 nodeFactory().reserveNodes(
1796 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
1799 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1810 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1812 while (++first != last) {
1814 const value_type& value = *first;
1815 if (this->comparator()(value.first, *prevNode)) {
1818 insertFromRange(++first, last);
1823 BloombergLP::bslalg::RbTreeNode *node =
1824 nodeFactory().emplaceIntoNewNode(value);
1825 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1835#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
1836 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1838template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1839template <
class INPUT_ITERATOR,
class SENTINEL>
1842multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::constructFromRange(
1843 INPUT_ITERATOR first,
1849 !BloombergLP::bslstl::IteratorUtil
1850 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
1851 || numElements ==
static_cast<size_type
>(
1852 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last))));
1854 if (first == last) {
1858 if (0 < numElements) {
1859 nodeFactory().reserveNodes(numElements);
1862 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
1872 insert(*first); --numElements;
1873 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
1875 while (++first != last) {
1877 const value_type& value = *first;
1878 if (this->comparator()(value.first, *prevNode)) {
1880 insert(value); --numElements;
1881 insertFromRange(++first, last, numElements);
1886 BloombergLP::bslalg::RbTreeNode *node =
1887 nodeFactory().emplaceIntoNewNode(value);
1888 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
1901template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1902template <
class INPUT_ITERATOR,
class SENTINEL>
1905multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insertFromRange(
1906 INPUT_ITERATOR first,
1919 while (first != last) {
1921 if (BloombergLP::bslstl::IteratorUtil
1922 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
1924 !nodeFactory().hasFreeNodes())) {
1925 nodeFactory().reserveNodes(
1926 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
1934#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
1935 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1937template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1938template <
class INPUT_ITERATOR,
class SENTINEL>
1940void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insertFromRange(
1941 INPUT_ITERATOR first,
1946 !BloombergLP::bslstl::IteratorUtil
1947 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()
1948 || numElements ==
static_cast<size_type
>(
1949 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last))));
1951 while (first != last) {
1954 !nodeFactory().hasFreeNodes())) {
1955 nodeFactory().reserveNodes(numElements);
1967template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1969const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::Comparator&
1970multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::comparator()
const
1972 return d_compAndAlloc;
1975template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1977const typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::NodeFactory&
1978multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::nodeFactory()
const
1980 return d_compAndAlloc.nodeFactory();
1984template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1986multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap()
1987: d_compAndAlloc(COMPARATOR(), ALLOCATOR())
1992template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
1994multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
1995 const ALLOCATOR& basicAllocator)
1996: d_compAndAlloc(COMPARATOR(), basicAllocator)
2001template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2003multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
const multimap& original)
2004: d_compAndAlloc(original.comparator().keyComparator(),
2005 AllocatorTraits::select_on_container_copy_construction(
2006 original.nodeFactory().allocator()))
2009 if (0 < original.size()) {
2010 nodeFactory().reserveNodes(original.size());
2011 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2017template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2019multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2020 BloombergLP::bslmf::MovableRef<multimap> original)
2021: d_compAndAlloc(MoveUtil::move(MoveUtil::access(original).d_compAndAlloc))
2024 multimap& lvalue = original;
2025 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2028template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2030multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2031 const multimap& original,
2032 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2033: d_compAndAlloc(original.comparator().keyComparator(), basicAllocator)
2036 if (0 < original.size()) {
2037 nodeFactory().reserveNodes(original.size());
2038 BloombergLP::bslalg::RbTreeUtil::copyTree(&d_tree,
2044template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2046multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2047 BloombergLP::bslmf::MovableRef<multimap> original,
2048 const typename type_identity<ALLOCATOR>::type& basicAllocator)
2049: d_compAndAlloc(MoveUtil::access(original).comparator().keyComparator(),
2053 multimap& lvalue = original;
2056 nodeFactory().allocator() == lvalue.nodeFactory().allocator())) {
2057 d_compAndAlloc.nodeFactory().adopt(
2058 MoveUtil::move(lvalue.d_compAndAlloc.nodeFactory()));
2059 BloombergLP::bslalg::RbTreeUtil::swap(&d_tree, &lvalue.d_tree);
2062 if (0 < lvalue.size()) {
2063 nodeFactory().reserveNodes(lvalue.size());
2064 BloombergLP::bslalg::RbTreeUtil::moveTree(&d_tree,
2067 &lvalue.nodeFactory());
2072template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2073template <
class INPUT_ITERATOR>
2075multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2076 INPUT_ITERATOR first,
2077 INPUT_ITERATOR last,
2078 const COMPARATOR& comparator,
2079 const ALLOCATOR& basicAllocator)
2080: d_compAndAlloc(comparator, basicAllocator)
2083 if (first != last) {
2085 const size_type numElements =
static_cast<size_type
>(
2086 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2088 if (0 < numElements) {
2089 nodeFactory().reserveNodes(numElements);
2092 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2103 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2104 while (++first != last) {
2107 const value_type& value = *first;
2108 if (this->comparator()(value.first, *prevNode)) {
2110 insert(++first, last);
2113 BloombergLP::bslalg::RbTreeNode *node =
2114 nodeFactory().emplaceIntoNewNode(value);
2115 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2125template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2126template <
class INPUT_ITERATOR>
2128multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2129 INPUT_ITERATOR first,
2130 INPUT_ITERATOR last,
2131 const ALLOCATOR& basicAllocator)
2132: d_compAndAlloc(COMPARATOR(), basicAllocator)
2135 if (first != last) {
2137 const size_type numElements =
static_cast<size_type
>(
2138 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2140 if (0 < numElements) {
2141 nodeFactory().reserveNodes(numElements);
2144 BloombergLP::bslalg::RbTreeUtilTreeProctor<NodeFactory> proctor(
2155 BloombergLP::bslalg::RbTreeNode *prevNode = d_tree.rootNode();
2156 while (++first != last) {
2159 const value_type& value = *first;
2160 if (this->comparator()(value.first, *prevNode)) {
2162 insert(++first, last);
2165 BloombergLP::bslalg::RbTreeNode *node =
2166 nodeFactory().emplaceIntoNewNode(value);
2167 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2177#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2178template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2180multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2181 std::initializer_list<value_type> values,
2182 const COMPARATOR& comparator,
2183 const ALLOCATOR& basicAllocator)
2184: multimap(values.
begin(), values.
end(), comparator, basicAllocator)
2188template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2190multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::multimap(
2191 std::initializer_list<value_type> values,
2192 const ALLOCATOR& basicAllocator)
2193: multimap(values.
begin(), values.
end(), COMPARATOR(), basicAllocator)
2198template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2200multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::~multimap()
2206template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2208multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
2209multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(
const multimap& rhs)
2212 if (AllocatorTraits::propagate_on_container_copy_assignment::value) {
2213 multimap other(rhs,
rhs.nodeFactory().allocator());
2214 quickSwapExchangeAllocators(other);
2217 multimap other(rhs, nodeFactory().allocator());
2218 quickSwapRetainAllocators(other);
2224template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2226multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
2227multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(
2228 BloombergLP::bslmf::MovableRef<multimap> rhs)
2230 AllocatorTraits::is_always_equal::value &&
2231 std::is_nothrow_move_assignable<COMPARATOR>::value)
2233 multimap& lvalue =
rhs;
2236 if (nodeFactory().allocator() == lvalue.nodeFactory().allocator()) {
2237 multimap other(MoveUtil::move(lvalue));
2238 quickSwapRetainAllocators(other);
2241 AllocatorTraits::propagate_on_container_move_assignment::value) {
2242 multimap other(MoveUtil::move(lvalue));
2243 quickSwapExchangeAllocators(other);
2246 multimap other(MoveUtil::move(lvalue), nodeFactory().allocator());
2247 quickSwapRetainAllocators(other);
2253#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2254template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2256multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>&
2257multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::operator=(
2258 std::initializer_list<value_type> values)
2261 insert(values.begin(), values.end());
2266template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2268typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2271 return iterator(d_tree.firstNode());
2274template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2276typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2279 return iterator(d_tree.sentinel());
2282template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2284typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::reverse_iterator
2287 return reverse_iterator(
end());
2290template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2292typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::reverse_iterator
2295 return reverse_iterator(
begin());
2298template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2300typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2301multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(
const value_type& value)
2305 BloombergLP::bslalg::RbTreeNode *insertLocation =
2306 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2311 BloombergLP::bslalg::RbTreeNode *node =
2312 nodeFactory().emplaceIntoNewNode(value);
2314 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2318 return iterator(node);
2321template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2322template <
class INPUT_ITERATOR>
2324void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(INPUT_ITERATOR first,
2325 INPUT_ITERATOR last)
2335 while (first != last) {
2336 if (BloombergLP::bslstl::IteratorUtil
2337 ::canCalculateInsertDistance<INPUT_ITERATOR, INPUT_ITERATOR>()
2339 !nodeFactory().hasFreeNodes())) {
2340 const size_type numElements =
static_cast<size_type
>(
2341 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last));
2343 nodeFactory().reserveNodes(numElements);
2350#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
2351template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2353void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const_iterator first,
2354 const_iterator last)
2356 while (first != last) {
2363template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2365typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2366multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(const_iterator hint,
2367 const value_type& value)
2371 BloombergLP::bslalg::RbTreeNode *hintNode =
2372 const_cast<BloombergLP::bslalg::RbTreeNode *
>(hint.node());
2374 BloombergLP::bslalg::RbTreeNode *insertLocation =
2375 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(&leftChild,
2381 BloombergLP::bslalg::RbTreeNode *node =
2382 nodeFactory().emplaceIntoNewNode(value);
2384 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2388 return iterator(node);
2391#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2392template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2394void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::insert(
2395 std::initializer_list<value_type> values)
2397 insert(values.begin(), values.end());
2401#if BSLS_COMPILERFEATURES_SIMULATE_VARIADIC_TEMPLATES
2404#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT
2405#define BSLSTL_MULTIMAP_VARIADIC_LIMIT 2
2407#ifndef BSLSTL_MULTIMAP_VARIADIC_LIMIT_B
2408#define BSLSTL_MULTIMAP_VARIADIC_LIMIT_B BSLSTL_MULTIMAP_VARIADIC_LIMIT
2410#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2411template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2413typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2414multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2419 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2422 BloombergLP::bslalg::RbTreeNode *insertLocation =
2423 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2427 static_cast<const Node *
>(node)->value().first);
2429 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2433 return iterator(node);
2437#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2438template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2439template <
class Args_1>
2441typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2442multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2447 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2450 BloombergLP::bslalg::RbTreeNode *insertLocation =
2451 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2455 static_cast<const Node *
>(node)->value().first);
2457 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2461 return iterator(node);
2465#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2466template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2467template <
class Args_1,
2470typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2471multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2477 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2481 BloombergLP::bslalg::RbTreeNode *insertLocation =
2482 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2486 static_cast<const Node *
>(node)->value().first);
2488 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2492 return iterator(node);
2497#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 0
2498template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2500typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2501multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint)
2505 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2508 BloombergLP::bslalg::RbTreeNode *hintNode =
2509 const_cast<BloombergLP::bslalg::RbTreeNode *
>(hint.node());
2511 BloombergLP::bslalg::RbTreeNode *insertLocation =
2512 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2516 static_cast<const Node *
>(node)->value().first,
2519 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2523 return iterator(node);
2527#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 1
2528template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2529template <
class Args_1>
2531typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2532multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2537 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2540 BloombergLP::bslalg::RbTreeNode *hintNode =
2541 const_cast<BloombergLP::bslalg::RbTreeNode *
>(hint.node());
2543 BloombergLP::bslalg::RbTreeNode *insertLocation =
2544 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2548 static_cast<const Node *
>(node)->value().first,
2551 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2555 return iterator(node);
2559#if BSLSTL_MULTIMAP_VARIADIC_LIMIT_B >= 2
2560template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2561template <
class Args_1,
2564typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2565multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2571 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2575 BloombergLP::bslalg::RbTreeNode *hintNode =
2576 const_cast<BloombergLP::bslalg::RbTreeNode *
>(hint.node());
2578 BloombergLP::bslalg::RbTreeNode *insertLocation =
2579 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2583 static_cast<const Node *
>(node)->value().first,
2586 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2590 return iterator(node);
2597template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2598template <
class... Args>
2600typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2601multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace(
2606 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2609 BloombergLP::bslalg::RbTreeNode *insertLocation =
2610 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2614 static_cast<const Node *
>(node)->value().first);
2616 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2620 return iterator(node);
2623template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2624template <
class... Args>
2626typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2627multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::emplace_hint(const_iterator hint,
2632 BloombergLP::bslalg::RbTreeNode *node = nodeFactory().emplaceIntoNewNode(
2635 BloombergLP::bslalg::RbTreeNode *hintNode =
2636 const_cast<BloombergLP::bslalg::RbTreeNode *
>(hint.node());
2638 BloombergLP::bslalg::RbTreeNode *insertLocation =
2639 BloombergLP::bslalg::RbTreeUtil::findInsertLocation(
2643 static_cast<const Node *
>(node)->value().first,
2646 BloombergLP::bslalg::RbTreeUtil::insertAt(&d_tree,
2650 return iterator(node);
2656template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2658typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2659multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(const_iterator position)
2663 BloombergLP::bslalg::RbTreeNode *node =
2664 const_cast<BloombergLP::bslalg::RbTreeNode *
>(position.node());
2665 BloombergLP::bslalg::RbTreeNode *result =
2666 BloombergLP::bslalg::RbTreeUtil::next(node);
2667 BloombergLP::bslalg::RbTreeUtil::remove(&d_tree, node);
2668 nodeFactory().deleteNode(node);
2669 return iterator(result);
2672template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2674typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2675multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(iterator position)
2677 return erase(const_iterator(position));
2680template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2682typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2683multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(
const key_type& key)
2685 size_type count = 0;
2686 const_iterator first = find(key);
2688 if (first !=
end()) {
2689 const_iterator last = upper_bound(key);
2690 while (first != last) {
2691 first =
erase(first);
2698template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2700typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::iterator
2701multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::erase(const_iterator first,
2702 const_iterator last)
2704 while (first != last) {
2705 first =
erase(first);
2707 return iterator(last.node());
2710template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2712void multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::swap(multimap& other)
2714 AllocatorTraits::is_always_equal::value &&
2715 bsl::is_nothrow_swappable<COMPARATOR>::value)
2717 if (AllocatorTraits::propagate_on_container_swap::value) {
2718 quickSwapExchangeAllocators(other);
2725 nodeFactory().allocator() == other.nodeFactory().allocator())) {
2726 quickSwapRetainAllocators(other);
2731 multimap toOtherCopy(MoveUtil::move(*
this),
2732 other.nodeFactory().allocator());
2733 multimap toThisCopy( MoveUtil::move(other),
2734 nodeFactory().allocator());
2736 this->quickSwapRetainAllocators(toThisCopy);
2737 other.quickSwapRetainAllocators(toOtherCopy);
2742template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2748 if (d_tree.rootNode()) {
2752 BloombergLP::bslalg::RbTreeUtil::deleteTree(&d_tree, &nodeFactory());
2754#if defined(BSLS_ASSERT_SAFE_IS_USED)
2763template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2765typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::allocator_type
2766multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::get_allocator() const
2769 return nodeFactory().allocator();
2772template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2774typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2775multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::begin() const
2781template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2783typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2789template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2791typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2792multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::rbegin() const
2798template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2800typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2806template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2808typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2809multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::cbegin() const
2812 return const_iterator(d_tree.firstNode());
2815template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2817typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_iterator
2820 return const_iterator(d_tree.sentinel());
2823template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2825typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2826multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::crbegin() const
2829 return const_reverse_iterator(
end());
2832template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2834typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::const_reverse_iterator
2835multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::crend() const
2838 return const_reverse_iterator(
begin());
2841template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2843bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::contains(
2844 const key_type& key)
const
2846 return find(key) !=
end();
2850template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2852bool multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::empty() const
2855 return 0 == d_tree.numNodes();
2858template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2860typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2863 return d_tree.numNodes();
2866template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2868typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::size_type
2869multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::max_size() const
2872 return AllocatorTraits::max_size(get_allocator());
2875template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2877typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::key_compare
2878multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::key_comp()
const
2880 return comparator().keyComparator();
2883template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2885typename multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_compare
2886multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>::value_comp()
const
2888 return value_compare(key_comp());
2894template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2900 return BloombergLP::bslalg::RangeCompare::equal(
lhs.begin(),
2908#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
2909template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2919#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
2921template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2923BloombergLP::bslalg::SynthThreeWayUtil::Result<bsl::pair<const KEY, VALUE>>
2924bsl::operator<=>(
const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& lhs,
2925 const multimap<KEY, VALUE, COMPARATOR, ALLOCATOR>& rhs)
2927 return bsl::lexicographical_compare_three_way(
2932 BloombergLP::bslalg::SynthThreeWayUtil::compare);
2937template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2943 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(
lhs.begin(),
2951template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2960template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2969template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
2989 PREDICATE predicate)
2991 return BloombergLP::bslstl::AlgorithmUtil::containerEraseIf(m, predicate);
2994template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
3016template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
3017struct HasStlIterators<
bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
3026template <
class KEY,
class VALUE,
class COMPARATOR,
class ALLOCATOR>
3027struct UsesBslmaAllocator<
bsl::multimap<KEY, VALUE, COMPARATOR, ALLOCATOR> >
3036# error Not valid except when included from bslstl_multimap.h
Definition bslma_bslallocator.h:588
COMPARATOR comp
Definition bslstl_multimap.h:819
friend class multimap
Definition bslstl_multimap.h:815
value_compare & operator=(const value_compare &rhs)=default
bool operator()(const value_type &x, const value_type &y) const
Definition bslstl_multimap.h:2292
value_type first_argument_type
Definition bslstl_multimap.h:839
value_compare(COMPARATOR comparator)
Definition bslstl_multimap.h:2284
bool result_type
Definition bslstl_multimap.h:834
value_type second_argument_type
Definition bslstl_multimap.h:844
Definition bslstl_multimap.h:690
void swap(multimap &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:1503
AllocatorTraits::difference_type difference_type
Definition bslstl_multimap.h:788
pair< const KEY, VALUE > value_type
Definition bslstl_multimap.h:781
bool contains(const key_type &key) const
Definition bslstl_multimap.h:3220
bsl::reverse_iterator< const_iterator > const_reverse_iterator
Definition bslstl_multimap.h:801
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3246
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this multimap.
Definition bslstl_multimap.h:3238
bsl::pair< iterator, iterator > equal_range(const key_type &key)
Definition bslstl_multimap.h:1627
const value_type & const_reference
Definition bslstl_multimap.h:785
COMPARATOR key_compare
Definition bslstl_multimap.h:782
iterator emplace(Args &&... args)
Definition bslstl_multimap.h:2980
AllocatorTraits::const_pointer const_pointer
Definition bslstl_multimap.h:790
AllocatorTraits::size_type size_type
Definition bslstl_multimap.h:787
iterator insert(const value_type &value)
Definition bslstl_multimap.h:2875
BloombergLP::bslstl::TreeIterator< const value_type, Node, difference_type > const_iterator
Definition bslstl_multimap.h:798
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3203
iterator erase(const_iterator position)
Definition bslstl_multimap.h:3036
BloombergLP::bslstl::TreeIterator< value_type, Node, difference_type > iterator
Definition bslstl_multimap.h:794
multimap & operator=(const multimap &rhs)
Definition bslstl_multimap.h:2783
bsl::reverse_iterator< iterator > reverse_iterator
Definition bslstl_multimap.h:800
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3229
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2859
ALLOCATOR allocator_type
Definition bslstl_multimap.h:783
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3143
~multimap()
Destroy this object.
Definition bslstl_multimap.h:2774
AllocatorTraits::pointer pointer
Definition bslstl_multimap.h:789
iterator emplace_hint(const_iterator hint, Args &&... args)
Definition bslstl_multimap.h:3005
value_compare value_comp() const
Definition bslstl_multimap.h:3263
iterator lower_bound(const key_type &key)
Definition bslstl_multimap.h:1549
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3195
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2851
key_compare key_comp() const
Definition bslstl_multimap.h:3255
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3212
iterator find(const key_type &key)
Definition bslstl_multimap.h:1515
size_type count(const key_type &key) const
Definition bslstl_multimap.h:1799
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:3186
multimap()
Definition bslstl_multimap.h:2560
VALUE mapped_type
Definition bslstl_multimap.h:780
KEY key_type
Definition bslstl_multimap.h:779
iterator upper_bound(const key_type &key)
Definition bslstl_multimap.h:1588
value_type & reference
Definition bslstl_multimap.h:784
void insert_range(BSLS_COMPILERFEATURES_FORWARD_REF(RANGE) range)
Definition bslstl_multimap.h:1353
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2867
multimap &operator=(BloombergLP::bslmf::MovableRef< multimap > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_multimap.h:2843
Definition bslstl_pair.h:1280
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_KEYWORD_CONSTEXPR_CPP17
Definition bsls_keyword.h:639
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:674
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
#define BSLSTL_MULTIMAP_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
Definition bslstl_multimap.h:649
void swap(OptionValue &a, OptionValue &b)
Definition bdlat_valuetypefunctions.h:939
void swap(array< VALUE_TYPE, SIZE > &lhs, array< VALUE_TYPE, SIZE > &rhs)
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1709
bool operator<(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
T::const_reverse_iterator crbegin(const T &container)
Definition bslstl_iterator.h:1695
bool operator>(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator>=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
bool operator<=(const array< VALUE_TYPE, SIZE > &lhs, const array< VALUE_TYPE, SIZE > &rhs)
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4424
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
const from_range_t from_range
bool operator==(const memory_resource &a, const memory_resource &b)
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1651
ALLOCATOR & lhs
Definition bslstl_string.h:3917
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4433
bool operator!=(const memory_resource &a, const memory_resource &b)
T::const_reverse_iterator crend(const T &container)
Definition bslstl_iterator.h:1752
Definition bdlc_flathashmap.h:2218
Definition baljsn_encoder_testtypes.h:76
Definition bdlbb_blob.h:579
Definition bslma_allocatortraits.h:1089
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1183
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR >::type size_type
Definition bslma_allocatortraits.h:1196
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1180
BloombergLP::bslma::AllocatorTraits_DifferenceType< ALLOCATOR >::type difference_type
Definition bslma_allocatortraits.h:1193
Definition bslmf_enableif.h:530
Definition bslstl_ranges.h:301
Definition bslmf_isconvertible.h:875