merge.pass.cpp (4472B)
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_set> 13 14 // class unordered_multiset 15 16 // template <class H2, class P2> 17 // void merge(unordered_set<key_type, H2, P2, allocator_type>& source); 18 // template <class H2, class P2> 19 // void merge(unordered_set<key_type, H2, P2, allocator_type>&& source); 20 // template <class H2, class P2> 21 // void merge(unordered_multiset<key_type, H2, P2, allocator_type>& source); 22 // template <class H2, class P2> 23 // void merge(unordered_multiset<key_type, H2, P2, allocator_type>&& source); 24 25 #include <unordered_set> 26 #include <cassert> 27 #include "test_macros.h" 28 #include "Counter.h" 29 30 template <class Set> 31 bool set_equal(const Set& set, Set other) 32 { 33 return set == 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_multiset<int> src{1, 3, 5}; 57 std::unordered_multiset<int> dst{2, 4, 5}; 58 dst.merge(src); 59 assert(set_equal(src, {})); 60 assert(set_equal(dst, {1, 2, 3, 4, 5, 5})); 61 } 62 63 #ifndef TEST_HAS_NO_EXCEPTIONS 64 { 65 bool do_throw = false; 66 typedef std::unordered_multiset<Counter<int>, throw_hasher<Counter<int>>> set_type; 67 set_type src({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw)); 68 set_type dst({2, 4, 5}, 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(set_equal(src, set_type({1, 3, 5}, 0, throw_hasher<Counter<int>>(do_throw)))); 83 assert(set_equal(dst, set_type({2, 4, 5}, 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 { return std::hash<Counter<int>>()(p); } 100 }; 101 { 102 typedef std::unordered_multiset<Counter<int>, std::hash<Counter<int>>, std::equal_to<Counter<int>>> first_set_type; 103 typedef std::unordered_multiset<Counter<int>, hasher, equal> second_set_type; 104 typedef std::unordered_set<Counter<int>, hasher, equal> third_set_type; 105 106 { 107 first_set_type first{1, 2, 3}; 108 second_set_type second{2, 3, 4}; 109 third_set_type third{1, 3}; 110 111 assert(Counter_base::gConstructed == 8); 112 113 first.merge(second); 114 first.merge(third); 115 116 assert(set_equal(first, {1, 2, 3, 4, 2, 3, 1, 3})); 117 assert(set_equal(second, {})); 118 assert(set_equal(third, {})); 119 120 assert(Counter_base::gConstructed == 8); 121 } 122 assert(Counter_base::gConstructed == 0); 123 { 124 first_set_type first{1, 2, 3}; 125 second_set_type second{2, 3, 4}; 126 third_set_type third{1, 3}; 127 128 assert(Counter_base::gConstructed == 8); 129 130 first.merge(std::move(second)); 131 first.merge(std::move(third)); 132 133 assert(set_equal(first, {1, 2, 3, 4, 2, 3, 1, 3})); 134 assert(set_equal(second, {})); 135 assert(set_equal(third, {})); 136 137 assert(Counter_base::gConstructed == 8); 138 } 139 assert(Counter_base::gConstructed == 0); 140 } 141 { 142 std::unordered_multiset<int> first; 143 { 144 std::unordered_multiset<int> second; 145 first.merge(second); 146 first.merge(std::move(second)); 147 } 148 { 149 std::unordered_set<int> second; 150 first.merge(second); 151 first.merge(std::move(second)); 152 } 153 } 154 }