1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/stl_util.h"
6
7 #include <array>
8 #include <deque>
9 #include <forward_list>
10 #include <functional>
11 #include <initializer_list>
12 #include <iterator>
13 #include <list>
14 #include <optional>
15 #include <queue>
16 #include <set>
17 #include <stack>
18 #include <string>
19 #include <type_traits>
20 #include <unordered_set>
21 #include <vector>
22
23 #include "base/containers/queue.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 namespace base {
28 namespace {
29
TEST(STLUtilTest,GetUnderlyingContainer)30 TEST(STLUtilTest, GetUnderlyingContainer) {
31 {
32 std::queue<int> queue({1, 2, 3, 4, 5});
33 static_assert(std::is_same_v<decltype(GetUnderlyingContainer(queue)),
34 const std::deque<int>&>,
35 "GetUnderlyingContainer(queue) should be of type deque");
36 EXPECT_THAT(GetUnderlyingContainer(queue),
37 testing::ElementsAre(1, 2, 3, 4, 5));
38 }
39
40 {
41 std::queue<int> queue;
42 EXPECT_THAT(GetUnderlyingContainer(queue), testing::ElementsAre());
43 }
44
45 {
46 base::queue<int> queue({1, 2, 3, 4, 5});
47 static_assert(
48 std::is_same_v<decltype(GetUnderlyingContainer(queue)),
49 const base::circular_deque<int>&>,
50 "GetUnderlyingContainer(queue) should be of type circular_deque");
51 EXPECT_THAT(GetUnderlyingContainer(queue),
52 testing::ElementsAre(1, 2, 3, 4, 5));
53 }
54
55 {
56 std::vector<int> values = {1, 2, 3, 4, 5};
57 std::priority_queue<int> queue(values.begin(), values.end());
58 static_assert(std::is_same_v<decltype(GetUnderlyingContainer(queue)),
59 const std::vector<int>&>,
60 "GetUnderlyingContainer(queue) should be of type vector");
61 EXPECT_THAT(GetUnderlyingContainer(queue),
62 testing::UnorderedElementsAre(1, 2, 3, 4, 5));
63 }
64
65 {
66 std::stack<int> stack({1, 2, 3, 4, 5});
67 static_assert(std::is_same_v<decltype(GetUnderlyingContainer(stack)),
68 const std::deque<int>&>,
69 "GetUnderlyingContainer(stack) should be of type deque");
70 EXPECT_THAT(GetUnderlyingContainer(stack),
71 testing::ElementsAre(1, 2, 3, 4, 5));
72 }
73 }
74
TEST(STLUtilTest,STLSetDifference)75 TEST(STLUtilTest, STLSetDifference) {
76 std::set<int> a1;
77 a1.insert(1);
78 a1.insert(2);
79 a1.insert(3);
80 a1.insert(4);
81
82 std::set<int> a2;
83 a2.insert(3);
84 a2.insert(4);
85 a2.insert(5);
86 a2.insert(6);
87 a2.insert(7);
88
89 {
90 std::set<int> difference;
91 difference.insert(1);
92 difference.insert(2);
93 EXPECT_EQ(difference, STLSetDifference<std::set<int> >(a1, a2));
94 }
95
96 {
97 std::set<int> difference;
98 difference.insert(5);
99 difference.insert(6);
100 difference.insert(7);
101 EXPECT_EQ(difference, STLSetDifference<std::set<int> >(a2, a1));
102 }
103
104 {
105 std::vector<int> difference;
106 difference.push_back(1);
107 difference.push_back(2);
108 EXPECT_EQ(difference, STLSetDifference<std::vector<int> >(a1, a2));
109 }
110
111 {
112 std::vector<int> difference;
113 difference.push_back(5);
114 difference.push_back(6);
115 difference.push_back(7);
116 EXPECT_EQ(difference, STLSetDifference<std::vector<int> >(a2, a1));
117 }
118 }
119
TEST(STLUtilTest,STLSetUnion)120 TEST(STLUtilTest, STLSetUnion) {
121 std::set<int> a1;
122 a1.insert(1);
123 a1.insert(2);
124 a1.insert(3);
125 a1.insert(4);
126
127 std::set<int> a2;
128 a2.insert(3);
129 a2.insert(4);
130 a2.insert(5);
131 a2.insert(6);
132 a2.insert(7);
133
134 {
135 std::set<int> result;
136 result.insert(1);
137 result.insert(2);
138 result.insert(3);
139 result.insert(4);
140 result.insert(5);
141 result.insert(6);
142 result.insert(7);
143 EXPECT_EQ(result, STLSetUnion<std::set<int> >(a1, a2));
144 }
145
146 {
147 std::set<int> result;
148 result.insert(1);
149 result.insert(2);
150 result.insert(3);
151 result.insert(4);
152 result.insert(5);
153 result.insert(6);
154 result.insert(7);
155 EXPECT_EQ(result, STLSetUnion<std::set<int> >(a2, a1));
156 }
157
158 {
159 std::vector<int> result;
160 result.push_back(1);
161 result.push_back(2);
162 result.push_back(3);
163 result.push_back(4);
164 result.push_back(5);
165 result.push_back(6);
166 result.push_back(7);
167 EXPECT_EQ(result, STLSetUnion<std::vector<int> >(a1, a2));
168 }
169
170 {
171 std::vector<int> result;
172 result.push_back(1);
173 result.push_back(2);
174 result.push_back(3);
175 result.push_back(4);
176 result.push_back(5);
177 result.push_back(6);
178 result.push_back(7);
179 EXPECT_EQ(result, STLSetUnion<std::vector<int> >(a2, a1));
180 }
181 }
182
TEST(STLUtilTest,STLSetIntersection)183 TEST(STLUtilTest, STLSetIntersection) {
184 std::set<int> a1;
185 a1.insert(1);
186 a1.insert(2);
187 a1.insert(3);
188 a1.insert(4);
189
190 std::set<int> a2;
191 a2.insert(3);
192 a2.insert(4);
193 a2.insert(5);
194 a2.insert(6);
195 a2.insert(7);
196
197 {
198 std::set<int> result;
199 result.insert(3);
200 result.insert(4);
201 EXPECT_EQ(result, STLSetIntersection<std::set<int> >(a1, a2));
202 }
203
204 {
205 std::set<int> result;
206 result.insert(3);
207 result.insert(4);
208 EXPECT_EQ(result, STLSetIntersection<std::set<int> >(a2, a1));
209 }
210
211 {
212 std::vector<int> result;
213 result.push_back(3);
214 result.push_back(4);
215 EXPECT_EQ(result, STLSetIntersection<std::vector<int> >(a1, a2));
216 }
217
218 {
219 std::vector<int> result;
220 result.push_back(3);
221 result.push_back(4);
222 EXPECT_EQ(result, STLSetIntersection<std::vector<int> >(a2, a1));
223 }
224 }
225
TEST(Erase,IsNotIn)226 TEST(Erase, IsNotIn) {
227 // Should keep both '2' but only one '4', like std::set_intersection.
228 std::vector<int> lhs = {0, 2, 2, 4, 4, 4, 6, 8, 10};
229 std::vector<int> rhs = {1, 2, 2, 4, 5, 6, 7};
230 std::vector<int> expected = {2, 2, 4, 6};
231 EXPECT_EQ(5u, std::erase_if(lhs, IsNotIn<std::vector<int>>(rhs)));
232 EXPECT_EQ(expected, lhs);
233 }
234
235 } // namespace
236 } // namespace base
237