1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14
10
11// <set>
12
13// class multiset
14
15// template <class C2>
16// void merge(set<Key, C2, Allocator>& source);
17// template <class C2>
18// void merge(set<Key, C2, Allocator>&& source);
19// template <class C2>
20// void merge(multiset<Key, C2, Allocator>& source);
21// template <class C2>
22// void merge(multiset<Key, C2, Allocator>&& source);
23
24#include <set>
25#include <cassert>
26#include "test_macros.h"
27#include "Counter.h"
28
29template <class Set>
30bool set_equal(const Set& set, Set other) {
31 return set == other;
32}
33
34#ifndef TEST_HAS_NO_EXCEPTIONS
35struct throw_comparator {
36 bool& should_throw_;
37
38 throw_comparator(bool& should_throw) : should_throw_(should_throw) {}
39
40 template <class T>
41 bool operator()(const T& lhs, const T& rhs) const {
42 if (should_throw_)
43 throw 0;
44 return lhs < rhs;
45 }
46};
47#endif
48
49int main(int, char**) {
50 {
51 std::multiset<int> src{1, 3, 5};
52 std::multiset<int> dst{2, 4, 5};
53 dst.merge(source&: src);
54 assert(set_equal(src, {}));
55 assert(set_equal(dst, {1, 2, 3, 4, 5, 5}));
56 }
57
58#ifndef TEST_HAS_NO_EXCEPTIONS
59 {
60 bool do_throw = false;
61 typedef std::multiset<Counter<int>, throw_comparator> set_type;
62 set_type src({1, 3, 5}, throw_comparator(do_throw));
63 set_type dst({2, 4, 5}, throw_comparator(do_throw));
64
65 assert(Counter_base::gConstructed == 6);
66
67 do_throw = true;
68 try {
69 dst.merge(src);
70 } catch (int) {
71 do_throw = false;
72 }
73 assert(!do_throw);
74 assert(set_equal(src, set_type({1, 3, 5}, throw_comparator(do_throw))));
75 assert(set_equal(dst, set_type({2, 4, 5}, throw_comparator(do_throw))));
76 }
77#endif
78 assert(Counter_base::gConstructed == 0);
79 struct comparator {
80 comparator() = default;
81
82 bool operator()(const Counter<int>& lhs, const Counter<int>& rhs) const { return lhs < rhs; }
83 };
84 {
85 typedef std::multiset<Counter<int>, std::less<Counter<int>>> first_set_type;
86 typedef std::multiset<Counter<int>, comparator> second_set_type;
87 typedef std::set<Counter<int>, comparator> third_set_type;
88
89 {
90 first_set_type first{1, 2, 3};
91 second_set_type second{2, 3, 4};
92 third_set_type third{1, 3};
93
94 assert(Counter_base::gConstructed == 8);
95
96 first.merge(second);
97 first.merge(third);
98
99 assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4}));
100 assert(set_equal(second, {}));
101 assert(set_equal(third, {}));
102
103 assert(Counter_base::gConstructed == 8);
104 }
105 assert(Counter_base::gConstructed == 0);
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(std::move(second));
114 first.merge(std::move(third));
115
116 assert(set_equal(first, {1, 1, 2, 2, 3, 3, 3, 4}));
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 {
125 std::multiset<int> first;
126 {
127 std::multiset<int> second;
128 first.merge(source&: second);
129 first.merge(source: std::move(second));
130 }
131 {
132 std::set<int> second;
133 first.merge(source&: second);
134 first.merge(source: std::move(second));
135 }
136 }
137 return 0;
138}
139

source code of libcxx/test/std/containers/associative/multiset/merge.pass.cpp