Containers

CMultimap

An ordered key–value container that permits repeated keys.

C++23 mc/CMultimap.h
#include <mc/CMultimap.h>

Standard-style names retain their familiar container meaning. The notes below explain lookup results, mutation, ownership, and Catalyst conveniences; only entirely obvious operations are left as declarations.

Exceptions escaping container operations are translated to CError. Direct iterator operations, element references, and calls through .std() follow the underlying type’s contracts.

Jump to a declaration · 72

CMultimap

template<class K, class V, class Cmp = std::less<K>, class Alloc = std::allocator<std::pair<const K, V>>> class CMultimap

Types, constants & data

using Map = std::multimap<K, V, Cmp, Alloc>;
using key_type = typename Map::key_type;
using value_type = typename Map::value_type;
using allocator_type = typename Map::allocator_type;
using reference = typename Map::reference;
using const_reference = typename Map::const_reference;
using pointer = typename Map::pointer;
using const_pointer = typename Map::const_pointer;
using size_type = typename Map::size_type;
using difference_type = typename Map::difference_type;
using iterator = typename Map::iterator;
using const_iterator = typename Map::const_iterator;
using node_type = typename Map::node_type;
using mapped_type = typename Map::mapped_type;
using key_compare = typename Map::key_compare;
using value_compare = typename Map::value_compare;
using reverse_iterator = typename Map::reverse_iterator;
using const_reverse_iterator = typename Map::const_reverse_iterator;

Methods

CMultimap

CMultimap() noexcept(std::is_nothrow_default_constructible_v<Map>);
explicit CMultimap(const key_compare& comp, const allocator_type& a = cContainerDefault<allocator_type>());
explicit CMultimap(const allocator_type& a);
template<CInputIterator I> CMultimap(I first, I last, const key_compare& comp = cContainerDefault<key_compare>(), const allocator_type& a = cContainerDefault<allocator_type>());
template<CInputIterator I> CMultimap(I first, I last, const allocator_type& a);
template<CContainerRange<value_type> R> CMultimap(std::from_range_t, R&& range, const key_compare& comp = cContainerDefault<key_compare>(), const allocator_type& a = cContainerDefault<allocator_type>());
template<CContainerRange<value_type> R> CMultimap(std::from_range_t, R&& range, const allocator_type& a);
CMultimap(std::initializer_list<value_type> values, const key_compare& comp = cContainerDefault<key_compare>(), const allocator_type& a = cContainerDefault<allocator_type>());
CMultimap(std::initializer_list<value_type> values, const allocator_type& a);
CMultimap(const CMultimap& other);
CMultimap(CMultimap&& other) noexcept(std::is_nothrow_move_constructible_v<Map>);
CMultimap(const CMultimap& other, const allocator_type& a);
CMultimap(CMultimap&& other, const allocator_type& a);
CMultimap(CBuffer& b);

Creates an empty container or copies entries from a range, initializer list, or compatible container. Duplicate keys are retained. The CBuffer overload restores the corresponding typed container format.

begin

iterator begin() noexcept;
const_iterator begin() const noexcept;

cbegin

const_iterator cbegin() const noexcept;

end

iterator end() noexcept;
const_iterator end() const noexcept;

cend

const_iterator cend() const noexcept;

rbegin

reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;

crbegin

const_reverse_iterator crbegin() const noexcept;

rend

reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;

crend

const_reverse_iterator crend() const noexcept;

span

cspan span() const noexcept;
cspan span(size_t start) const noexcept;
cspan span(size_t start, size_t endOffset) const noexcept;

Returns numeric indices from zero to size(), optionally excluding an initial or trailing portion. It does not return key/value pairs or an element view.

empty

bool empty() const noexcept;

size

size_type size() const noexcept;

max_size

size_type max_size() const noexcept;

find

iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
template<class Q> requires(CTransparent<key_compare>) iterator find(const Q& key);
template<class Q> requires(CTransparent<key_compare>) const_iterator find(const Q& key) const;

Returns an iterator to an equivalent key or element, or end() when none is present. This lookup does not insert a missing entry.

contains

bool contains(const key_type& key) const;
template<class Q> requires(CTransparent<key_compare>) bool contains(const Q& key) const;

Reports whether an equivalent key is present. This is the standard-style spelling of a membership lookup.

count

size_type count(const key_type& x) const;
template<class Q> requires(CTransparent<key_compare>) size_type count(const Q& key) const;

Returns the number of entries with an equivalent key; repeated keys can produce a count greater than one.

lower_bound

iterator lower_bound(const key_type& x);
const_iterator lower_bound(const key_type& x) const;
template<class Q> requires(CTransparent<key_compare>) iterator lower_bound(const Q& key);
template<class Q> requires(CTransparent<key_compare>) const_iterator lower_bound(const Q& key) const;

Returns the first position whose key is not less than the requested key according to the ordering policy, or end().

upper_bound

iterator upper_bound(const key_type& x);
const_iterator upper_bound(const key_type& x) const;
template<class Q> requires(CTransparent<key_compare>) iterator upper_bound(const Q& key);
template<class Q> requires(CTransparent<key_compare>) const_iterator upper_bound(const Q& key) const;

Returns the first position whose key is greater than the requested key according to the ordering policy, or end().

equal_range

std::pair<iterator,iterator> equal_range(const key_type& x);
std::pair<const_iterator,const_iterator> equal_range(const key_type& x) const;
template<class Q> requires(CTransparent<key_compare>) std::pair<iterator, iterator> equal_range(const Q& key);
template<class Q> requires(CTransparent<key_compare>) std::pair<const_iterator, const_iterator> equal_range(const Q& key) const;

Returns the half-open iterator range of equivalent keys. A missing key produces an empty range.

insert

iterator insert(const value_type& x);
iterator insert(const_iterator position, const value_type& x);
template<CInputIterator InputIterator> void insert(InputIterator first, InputIterator last);
template<class P> requires std::is_constructible_v<value_type, P&&> iterator insert(const_iterator position, P&& p);
void insert(std::initializer_list<value_type> il);
iterator insert(value_type&& value);
iterator insert(const_iterator hint, value_type&& value);
template<class P> requires std::is_constructible_v<value_type, P&&> iterator insert(P&& value);
iterator insert(node_type&& node);
iterator insert(const_iterator hint, node_type&& node);

Inserts entries including duplicate keys. A single-entry overload returns an iterator to the new entry.

insert_range

template<CContainerRange<value_type> R> void insert_range(R&& range);

Inserts elements from a C++ range using the container’s duplicate-key policy. It does not clear the existing contents.

emplace

template<class... Args> iterator emplace(Args&&... args);

Constructs and inserts a new entry from forwarded arguments, including when an equivalent key exists. Returns the inserted entry’s iterator.

emplace_hint

template<class... Args> iterator emplace_hint(const_iterator position, Args&&... args);

Attempts emplacement using the supplied position as a lookup hint and returns an iterator to the result. The hint does not change the key ordering or duplicate policy.

add

CMultimap& add(const K& k, const V& t);

Adds another key/value entry even when the key already exists, and returns this multimap for chaining.

erase

iterator erase(iterator itr);
size_type erase(const key_type& x);
iterator erase(const_iterator first, const_iterator last);
iterator erase(const_iterator position);
template<class Q> requires(CTransparent<key_compare> && !std::is_convertible_v<Q, iterator> && !std::is_convertible_v<Q, const_iterator>) size_type erase(Q&& key);

Erases an iterator, a half-open iterator range, or all entries equivalent to a key. Iterator forms return the following iterator; key forms return the number removed.

clear

void clear() noexcept;

clearExcept

template<class S> void clearExcept(const S& s);

Removes entries whose keys are not present in s, as tested by s.has(key).

extract

node_type extract(const_iterator itr);
node_type extract(const key_type& x);
template<class Q> requires(CTransparent<key_compare> && !std::is_convertible_v<Q, iterator> && !std::is_convertible_v<Q, const_iterator>) node_type extract(Q&& key);

Detaches one element into an owning node handle without copying its value. Key lookup returns an empty handle if absent; the node may be inserted into a compatible container.

merge

template<class C2> void merge(CMap<K, V, C2, Alloc>& source);
template<class C2> void merge(CMap<K, V, C2, Alloc>&& source);
template<class C2> void merge(CMultimap<K, V, C2, Alloc>& source);
template<class C2> void merge(CMultimap<K, V, C2, Alloc>&& source);
template<class C2> void merge(std::map<K, V, C2, Alloc>& source);
template<class C2> void merge(std::map<K, V, C2, Alloc>&& source);
template<class C2> void merge(std::multimap<K, V, C2, Alloc>& source);
template<class C2> void merge(std::multimap<K, V, C2, Alloc>&& source);

Transfers all entries from a compatible source, including equivalent keys. The source is emptied.

innerMerge

void innerMerge(const CMultimap& m);

Copies all incoming entries into this multimap, including repeated keys. Existing entries are retained.

std

const Map& std() const noexcept;
Map& std() noexcept;

Returns a reference to the underlying container for interoperation. Changes affect this object directly; operations through that reference bypass Catalyst exception translation.

operator const Map&

operator const Map&() const noexcept;

Borrows the underlying container for interoperability. This does not copy storage; references and iterators follow that container’s lifetime and invalidation rules.

operator Map&

operator Map&() noexcept;

Borrows the underlying container for interoperability. This does not copy storage; references and iterators follow that container’s lifetime and invalidation rules.

store

void store(CBuffer& b) const;

Appends the container to a CBuffer; restore it with the buffer-taking constructor.

dump

cstr dump() const;

Returns the stream-formatted contents as a cstr. Use store() for binary serialization.

Free functions & types

Functions

operator<<

template<class K, class V, class C, class A> std::ostream& operator<<(std::ostream& ostr, const CMultimap<K, V, C, A>& m);

swap

template<class K, class V, class C, class A> void swap(CMultimap<K, V, C, A>& x, CMultimap<K, V, C, A>& y) noexcept(noexcept(x.swap(y)));

erase_if

template<class K, class V, class C, class A, class Predicate> typename CMultimap<K, V, C, A>::size_type erase_if(CMultimap<K, V, C, A>& container, Predicate predicate);

Removes every element for which the predicate returns true and returns the number removed. Map predicates receive key/value entries.

<deduction guide for CMultimap>

template<class... Args, class S = decltype(std::multimap(std::declval<Args>()...))> CMultimap(Args&&...) -> CMultimap< typename S::key_type, typename S::mapped_type, typename S::key_compare, typename S::allocator_type>;
template<class K, class V, class C = std::less<std::remove_const_t<K>>, CAllocator A = std::allocator<std::pair<const K, V>>> requires(!CAllocator<C>) CMultimap(std::initializer_list<std::pair<K, V>>, C = C(), A = A()) -> CMultimap<std::remove_const_t<K>, V, C, A>;
template<class K, class V, CAllocator A> CMultimap(std::initializer_list<std::pair<K, V>>, A) -> CMultimap<std::remove_const_t<K>, V, std::less<std::remove_const_t<K>>, A>;

pmr

Types, constants & data

template<class K, class V, class C = std::less<K>> using CMultimap = mc::CMultimap<K, V, C, std::pmr::polymorphic_allocator<std::pair<const K, V>>>;