merge.pass.cpp (4832B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03, c++11, c++14 11 12 // <unordered_map> 13 14 // class unordered_map 15 16 // template <class H2, class P2> 17 // void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>& source); 18 // template <class H2, class P2> 19 // void merge(unordered_map<key_type, value_type, H2, P2, allocator_type>&& source); 20 // template <class H2, class P2> 21 // void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>& source); 22 // template <class H2, class P2> 23 // void merge(unordered_multimap<key_type, value_type, H2, P2, allocator_type>&& source); 24 25 #include <unordered_map> 26 #include <cassert> 27 #include "test_macros.h" 28 #include "Counter.h" 29 30 template <class Map> 31 bool map_equal(const Map& map, Map other) 32 { 33 return map == other; 34 } 35 36 #ifndef TEST_HAS_NO_EXCEPTIONS 37 template <class T> 38 struct throw_hasher 39 { 40 bool& should_throw_; 41 42 throw_hasher(bool& should_throw) : should_throw_(should_throw) {} 43 44 size_t operator()(const T& p) const 45 { 46 if (should_throw_) 47 throw 0; 48 return std::hash<T>()(p); 49 } 50 }; 51 #endif 52 53 int main() 54 { 55 { 56 std::unordered_map<int, int> src{{1, 0}, {3, 0}, {5, 0}}; 57 std::unordered_map<int, int> dst{{2, 0}, {4, 0}, {5, 0}}; 58 dst.merge(src); 59 assert(map_equal(src, {{5,0}})); 60 assert(map_equal(dst, {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}})); 61 } 62 63 #ifndef TEST_HAS_NO_EXCEPTIONS 64 { 65 bool do_throw = false; 66 typedef std::unordered_map<Counter<int>, int, throw_hasher<Counter<int>>> map_type; 67 map_type src({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); 68 map_type dst({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)); 69 70 assert(Counter_base::gConstructed == 6); 71 72 do_throw = true; 73 try 74 { 75 dst.merge(src); 76 } 77 catch (int) 78 { 79 do_throw = false; 80 } 81 assert(!do_throw); 82 assert(map_equal(src, map_type({{1, 0}, {3, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); 83 assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, 0, throw_hasher<Counter<int>>(do_throw)))); 84 } 85 #endif 86 assert(Counter_base::gConstructed == 0); 87 struct equal 88 { 89 equal() = default; 90 91 bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const 92 { 93 return lhs == rhs; 94 } 95 }; 96 struct hasher 97 { 98 hasher() = default; 99 size_t operator()(const Counter<int>& p) const 100 { 101 return std::hash<Counter<int>>()(p); 102 } 103 }; 104 { 105 typedef std::unordered_map<Counter<int>, int, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_map_type; 106 typedef std::unordered_map<Counter<int>, int, hasher, equal> second_map_type; 107 typedef std::unordered_multimap<Counter<int>, int, hasher, equal> third_map_type; 108 109 { 110 first_map_type first{{1, 0}, {2, 0}, {3, 0}}; 111 second_map_type second{{2, 0}, {3, 0}, {4, 0}}; 112 third_map_type third{{1, 0}, {3, 0}}; 113 114 assert(Counter_base::gConstructed == 8); 115 116 first.merge(second); 117 first.merge(third); 118 119 assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); 120 assert(map_equal(second, {{2, 0}, {3, 0}})); 121 assert(map_equal(third, {{1, 0}, {3, 0}})); 122 123 assert(Counter_base::gConstructed == 8); 124 } 125 assert(Counter_base::gConstructed == 0); 126 { 127 first_map_type first{{1, 0}, {2, 0}, {3, 0}}; 128 second_map_type second{{2, 0}, {3, 0}, {4, 0}}; 129 third_map_type third{{1, 0}, {3, 0}}; 130 131 assert(Counter_base::gConstructed == 8); 132 133 first.merge(std::move(second)); 134 first.merge(std::move(third)); 135 136 assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}})); 137 assert(map_equal(second, {{2, 0}, {3, 0}})); 138 assert(map_equal(third, {{1, 0}, {3, 0}})); 139 140 assert(Counter_base::gConstructed == 8); 141 } 142 assert(Counter_base::gConstructed == 0); 143 } 144 { 145 std::unordered_map<int, int> first; 146 { 147 std::unordered_map<int, int> second; 148 first.merge(second); 149 first.merge(std::move(second)); 150 } 151 { 152 std::unordered_multimap<int, int> second; 153 first.merge(second); 154 first.merge(std::move(second)); 155 } 156 } 157 }