#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <functional>
struct Person {
int id;
std::string name;
bool operator<(const Person& other) const {
return id < other.id;
}
};
template<typename K, typename V>
void printMap(const std::map<K, V>& m, const std::string& title) {
std::cout << title << ":\n";
for (const auto& [key, value] : m) {
std::cout << " " << key << " -> " << value << '\n';
}
std::cout << " size = " << m.size() << "\n\n";
}
int main() {
std::cout << "=== 1. Construction and initialization ===\n";
std::map<int, std::string> m1;
std::map<int, std::string> m2 = {
{1, "one"},
{2, "two"},
{3, "three"}
};
std::map<int, std::string> m3(m2);
std::map<int, std::string> m4(m2.begin(), m2.end());
printMap(m2, "m2");
std::cout << "=== 2. Inserting elements ===\n";
std::map<int, std::string> mp;
mp[10] = "ten";
mp[20] = "twenty";
mp.insert(std::pair<int, std::string>(30, "thirty"));
mp.insert(std::make_pair(40, "forty"));
mp.insert({50, "fifty"});
auto [it, inserted] = mp.insert({20, "TWENTY"});
if (!inserted) {
std::cout << "Key 20 already exists, value is " << it->second << ", insertion failed\n";
}
mp.emplace(60, "sixty");
mp.try_emplace(70, "seventy");
mp.try_emplace(10, "TEN");
mp.insert_or_assign(10, "TEN");
mp.insert_or_assign(80, "eighty");
printMap(mp, "map after insertions");
std::cout << "=== 3. Accessing elements ===\n";
std::cout << "mp[10] = " << mp[10] << '\n';
std::cout << "mp[100] (not existing) = " << mp[100] << " (automatically inserted empty string)\n";
try {
std::cout << "mp.at(20) = " << mp.at(20) << '\n';
} catch (const std::out_of_range& e) {
std::cout << "Exception: " << e.what() << '\n';
}
std::cout << '\n';
std::cout << "=== 4. Iterators and traversal ===\n";
std::cout << "Forward traversal: ";
for (auto it = mp.begin(); it != mp.end(); ++it) {
std::cout << it->first << ":" << it->second << " ";
}
std::cout << '\n';
std::cout << "Reverse traversal: ";
for (auto rit = mp.rbegin(); rit != mp.rend(); ++rit) {
std::cout << rit->first << ":" << rit->second << " ";
}
std::cout << '\n';
std::cout << "Range-based for loop: ";
for (const auto& [k, v] : mp) {
std::cout << k << ":" << v << " ";
}
std::cout << "\n\n";
std::cout << "=== 5. Finding elements ===\n";
int key = 50;
auto it_find = mp.find(key);
if (it_find != mp.end()) {
std::cout << "find(" << key << ") -> " << it_find->first << ":" << it_find->second << '\n';
} else {
std::cout << "find(" << key << ") not found\n";
}
std::cout << "count(30) = " << mp.count(30) << '\n';
std::cout << "count(99) = " << mp.count(99) << '\n';
#if __cplusplus >= 202002L
std::cout << "contains(40): " << mp.contains(40) << '\n';
#endif
auto lb = mp.lower_bound(30);
auto ub = mp.upper_bound(30);
std::cout << "lower_bound(30): " << lb->first << ":" << lb->second << '\n';
std::cout << "upper_bound(30): " << ub->first << ":" << ub->second << '\n';
auto eq = mp.equal_range(30);
std::cout << "equal_range(30): ["
<< eq.first->first << ":" << eq.first->second << ", "
<< eq.second->first << ":" << eq.second->second << "]\n\n";
std::cout << "=== 6. Erasing elements ===\n";
mp.erase(100);
mp.erase(80);
auto it_del = mp.find(60);
if (it_del != mp.end()) {
mp.erase(it_del);
}
auto first = mp.begin();
auto last = mp.begin();
std::advance(last, 2);
mp.erase(first, last);
printMap(mp, "map after erasing some elements");
std::cout << "=== 7. Size and capacity ===\n";
std::cout << "size() = " << mp.size() << '\n';
std::cout << "empty() = " << (mp.empty() ? "true" : "false") << '\n';
std::cout << "max_size() = " << mp.max_size() << " (platform-dependent)\n\n";
std::cout << "=== 8. Modifiers ===\n";
std::map<int, std::string> other = {{999, "nine-nine-nine"}};
mp.swap(other);
std::cout << "after swap mp: ";
for (const auto& [k, v] : mp) std::cout << k << ":" << v << " ";
std::cout << "\nafter swap other: ";
for (const auto& [k, v] : other) std::cout << k << ":" << v << " ";
std::cout << '\n';
mp.clear();
std::cout << "after clear mp.size() = " << mp.size() << "\n\n";
std::cout << "=== 9. Custom comparison (descending) ===\n";
std::map<int, std::string, std::greater<int>> descMap = {
{1, "a"}, {3, "c"}, {2, "b"}
};
for (const auto& [k, v] : descMap) {
std::cout << k << " -> " << v << '\n';
}
auto cmp = [](const Person& p1, const Person& p2) { return p1.id > p2.id; };
std::map<Person, std::string, decltype(cmp)> personMap(cmp);
personMap[{101, "Alice"}] = "Manager";
personMap[{102, "Bob"}] = "Engineer";
personMap[{100, "Carol"}] = "Director";
std::cout << "\nPerson map (sorted by id descending):\n";
for (const auto& [p, role] : personMap) {
std::cout << " id:" << p.id << " name:" << p.name << " -> " << role << '\n';
}
std::cout << '\n';
std::cout << "=== 10. Merge and extract ===\n";
std::map<int, std::string> src = {{1, "one"}, {2, "two"}, {3, "three"}};
std::map<int, std::string> dst = {{2, "TWO"}, {4, "four"}};
auto node = src.extract(1);
node.key() = 10;
dst.insert(std::move(node));
dst.merge(src);
std::cout << "after merge dst: ";
for (const auto& [k, v] : dst) std::cout << k << ":" << v << " ";
std::cout << "\nafter merge src: ";
for (const auto& [k, v] : src) std::cout << k << ":" << v << " ";
std::cout << "\n";
std::cout << "\n=== 11. Other utilities ===\n";
std::map<int, std::string> a = {{1, "a"}};
std::map<int, std::string> b = {{2, "b"}};
std::swap(a, b);
std::cout << "after std::swap a: ";
for (const auto& [k, v] : a) std::cout << k << ":" << v << " ";
std::cout << "\n";
std::map<int, int> m_a = {{1,10}, {2,20}};
std::map<int, int> m_b = {{1,10}, {2,20}};
std::map<int, int> m_c = {{1,10}, {3,30}};
std::cout << "m_a == m_b: " << (m_a == m_b) << '\n';
std::cout << "m_a < m_c: " << (m_a < m_c) << '\n';
return 0;
}