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