std::unordered_map::swap(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::unordered_map::swap πŸ’…

okay so welcome to std::unordered_map::swap(3) from the C++ Standard Libary manual β€” yes bestie, that’s the exact spelling up top, keep it cute 😌. This is the page for swapping two unordered maps, and it’s lowkey iconic.


✨ NAME ✨

std::unordered_map::swap β€” std::unordered_map::swap

yes, the name is literally the same on both sides. main character energy fr fr.


πŸ¦‹ Synopsis πŸ¦‹

two signature eras, two vibes:

void swap( unordered_map& other );                            (since C++11)
                                                              (until C++17)
void swap( unordered_map& other ) noexcept(/* see below */);  (since C++17)

🌸 Parameters 🌸

  • other β€” the container you’re exchanging contents with 🫢

πŸŽ€ Return value πŸŽ€

(none)

no return, just vibes.


πŸ’€ Exceptions πŸ’€

  • Any exception thrown by the swap of the Hash or KeyEqual objects. (until C++17)

noexcept specification, and yes it’s giving very specific:

noexcept(std::allocator_traits<Allocator>::is_always_equal::value
&& std::is_nothrow_swappable<Hash>::value
&& std::is_nothrow_swappable<key_equal>::value)

(since C++17)


⭐ Complexity ⭐

Constant. periodt.


🧚 Example 🧚

run this code and watch the swap do its little magic trick:

// Run this code

#include <iostream>
#include <string>
#include <utility>
#include <unordered_map>

// print out a std::pair
template<class Os, class U, class V>
Os& operator<<(Os& os, const std::pair<U, V>& p)
{
    return os << p.first << ':' << p.second;
}

// print out a container
template<class Os, class Co>
Os& operator<<(Os& os, const Co& co)
{
    os << '{';
    for (auto const& i : co)
        os << ' ' << i;
    return os << " }\n";
}

int main()
{
    std::unordered_map<std::string, std::string>
        m1{{"Ξ³", "gamma"}, {"Ξ²", "beta"}, {"Ξ±", "alpha"}, {"Ξ³", "gamma"}},
        m2{{"Ξ΅", "epsilon"}, {"Ξ΄", "delta"}, {"Ξ΅", "epsilon"}};

    const auto& ref = *(m1.begin());
    const auto iter = std::next(m1.cbegin());

    std::cout << "──────── before swap ────────\n"
              << "m1: " << m1 << "m2: " << m2 << "ref: " << ref
              << "\niter: " << *iter << '\n';

    m1.swap(m2);

    std::cout << "──────── after swap ────────\n"
              << "m1: " << m1 << "m2: " << m2 << "ref: " << ref
              << "\niter: " << *iter << '\n';

    // Note that every iterator referring to an element in one container before
    // the swap refers to the same element in the other container after the swap.
    // Same is true for references.
}

πŸ“ Possible output πŸ“

──────── before swap ────────
m1: { Ξ±:alpha Ξ²:beta Ξ³:gamma }
m2: { Ξ΄:delta Ξ΅:epsilon }
ref: Ξ±:alpha
iter: Ξ²:beta
──────── after swap ────────
m1: { Ξ΄:delta Ξ΅:epsilon }
m2: { Ξ±:alpha Ξ²:beta Ξ³:gamma }
ref: Ξ±:alpha
iter: Ξ²:beta

πŸ‘‘ See also πŸ‘‘

  • std::swap(std::unordered_map) β€” specializes the std::swap algorithm (C++11) (function template)

🌈 Category 🌈

  • * conditionally noexcept

okay bestie, real talk: this swap exchanges the contents of the container with those of other. It does not invoke any move, copy, or swap operations on individual elements. Zero touching of the little guys πŸ’….
All iterators and references remain valid. The end() iterator is invalidated β€” so don’t get attached to that one 😭.
The Hash and KeyEqual objects must be Swappable, and they are exchanged using unqualified calls to non-member swap.
If std::allocator_traits<allocator_type>::propagate_on_container_swap::value is true, then the allocators are exchanged using an unqualified call to non-member swap. Otherwise, they are not swapped (and if get_allocator() != other.get_allocator(), the behavior is undefined) (since C++11). undefined behavior is not the vibe, bestie πŸ’€.

xoxo, your local Unix bestie πŸ’– β€” source/version/date check: http://cppreference.com, 2024.06.10, and this iconic page is std::unordered_map::swap(3) 🫢✨

πŸ“¦ where this page comes from