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 // <map>
13
14 // class map
15
16 // template <class C2>
17 // void merge(map<key_type, value_type, C2, allocator_type>& source);
18 // template <class C2>
19 // void merge(map<key_type, value_type, C2, allocator_type>&& source);
20 // template <class C2>
21 // void merge(multimap<key_type, value_type, C2, allocator_type>& source);
22 // template <class C2>
23 // void merge(multimap<key_type, value_type, C2, allocator_type>&& source);
24
25 #include <map>
26 #include <cassert>
27 #include "test_macros.h"
28 #include "Counter.h"
29
30 template <class Map>
map_equal(const Map & map,Map other)31 bool map_equal(const Map& map, Map other)
32 {
33 return map == other;
34 }
35
36 #ifndef TEST_HAS_NO_EXCEPTIONS
37 struct throw_comparator
38 {
39 bool& should_throw_;
40
throw_comparatorthrow_comparator41 throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
42
43 template <class T>
operator ()throw_comparator44 bool operator()(const T& lhs, const T& rhs) const
45 {
46 if (should_throw_)
47 throw 0;
48 return lhs < rhs;
49 }
50 };
51 #endif
52
main()53 int main()
54 {
55 {
56 std::map<int, int> src{{1, 0}, {3, 0}, {5, 0}};
57 std::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::map<Counter<int>, int, throw_comparator> map_type;
67 map_type src({{1, 0}, {3, 0}, {5, 0}}, throw_comparator(do_throw));
68 map_type dst({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(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}}, throw_comparator(do_throw))));
83 assert(map_equal(dst, map_type({{2, 0}, {4, 0}, {5, 0}}, throw_comparator(do_throw))));
84 }
85 #endif
86 assert(Counter_base::gConstructed == 0);
87 struct comparator
88 {
89 comparator() = default;
90
91 bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const
92 {
93 return lhs < rhs;
94 }
95 };
96 {
97 typedef std::map<Counter<int>, int, std::less<Counter<int>>> first_map_type;
98 typedef std::map<Counter<int>, int, comparator> second_map_type;
99 typedef std::multimap<Counter<int>, int, comparator> third_map_type;
100
101 {
102 first_map_type first{{1, 0}, {2, 0}, {3, 0}};
103 second_map_type second{{2, 0}, {3, 0}, {4, 0}};
104 third_map_type third{{1, 0}, {3, 0}};
105
106 assert(Counter_base::gConstructed == 8);
107
108 first.merge(second);
109 first.merge(third);
110
111 assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
112 assert(map_equal(second, {{2, 0}, {3, 0}}));
113 assert(map_equal(third, {{1, 0}, {3, 0}}));
114
115 assert(Counter_base::gConstructed == 8);
116 }
117 assert(Counter_base::gConstructed == 0);
118 {
119 first_map_type first{{1, 0}, {2, 0}, {3, 0}};
120 second_map_type second{{2, 0}, {3, 0}, {4, 0}};
121 third_map_type third{{1, 0}, {3, 0}};
122
123 assert(Counter_base::gConstructed == 8);
124
125 first.merge(std::move(second));
126 first.merge(std::move(third));
127
128 assert(map_equal(first, {{1, 0}, {2, 0}, {3, 0}, {4, 0}}));
129 assert(map_equal(second, {{2, 0}, {3, 0}}));
130 assert(map_equal(third, {{1, 0}, {3, 0}}));
131
132 assert(Counter_base::gConstructed == 8);
133 }
134 assert(Counter_base::gConstructed == 0);
135 }
136 assert(Counter_base::gConstructed == 0);
137 {
138 std::map<int, int> first;
139 {
140 std::map<int, int> second;
141 first.merge(second);
142 first.merge(std::move(second));
143 }
144 {
145 std::multimap<int, int> second;
146 first.merge(second);
147 first.merge(std::move(second));
148 }
149 }
150 }
151