1 // Copyright 2017 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/containers/unique_ptr_adapters.h"
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/memory/raw_ptr.h"
11 #include "base/ranges/algorithm.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace base {
15 namespace {
16
17 class Foo {
18 public:
Foo()19 Foo() { instance_count++; }
~Foo()20 ~Foo() { instance_count--; }
21 static int instance_count;
22 };
23
24 int Foo::instance_count = 0;
25
TEST(UniquePtrComparatorTest,Basic)26 TEST(UniquePtrComparatorTest, Basic) {
27 std::set<std::unique_ptr<Foo>, UniquePtrComparator> set;
28 Foo* foo1 = new Foo();
29 Foo* foo2 = new Foo();
30 Foo* foo3 = new Foo();
31 EXPECT_EQ(3, Foo::instance_count);
32
33 raw_ptr<Foo> raw_foo1 = foo1;
34 raw_ptr<Foo> raw_foo2 = foo2;
35 raw_ptr<Foo> raw_foo3 = foo3;
36 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
37 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
38 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
39
40 set.emplace(foo1);
41 set.emplace(foo2);
42
43 auto it1 = set.find(foo1);
44 EXPECT_TRUE(it1 != set.end());
45 EXPECT_EQ(foo1, it1->get());
46 EXPECT_TRUE(set.find(raw_foo1) == it1);
47 EXPECT_TRUE(set.find(dangling_foo1) == it1);
48
49 {
50 auto it2 = set.find(foo2);
51 EXPECT_TRUE(it2 != set.end());
52 EXPECT_EQ(foo2, it2->get());
53 EXPECT_TRUE(set.find(raw_foo2) == it2);
54 EXPECT_TRUE(set.find(dangling_foo2) == it2);
55 }
56
57 EXPECT_TRUE(set.find(foo3) == set.end());
58 EXPECT_TRUE(set.find(raw_foo3) == set.end());
59 EXPECT_TRUE(set.find(dangling_foo3) == set.end());
60
61 raw_foo1 = nullptr; // Avoid dangling raw_ptr.
62 set.erase(it1);
63 EXPECT_EQ(2, Foo::instance_count);
64
65 EXPECT_TRUE(set.find(foo1) == set.end());
66 EXPECT_TRUE(set.find(dangling_foo1) == set.end());
67
68 {
69 auto it2 = set.find(foo2);
70 EXPECT_TRUE(it2 != set.end());
71 EXPECT_EQ(foo2, it2->get());
72 EXPECT_TRUE(set.find(raw_foo2) == it2);
73 EXPECT_TRUE(set.find(dangling_foo2) == it2);
74 }
75
76 raw_foo2 = nullptr; // Avoid dangling raw_ptr.
77 set.clear();
78 EXPECT_EQ(1, Foo::instance_count);
79
80 EXPECT_TRUE(set.find(foo1) == set.end());
81 EXPECT_TRUE(set.find(foo2) == set.end());
82 EXPECT_TRUE(set.find(foo3) == set.end());
83 EXPECT_TRUE(set.find(dangling_foo1) == set.end());
84 EXPECT_TRUE(set.find(dangling_foo2) == set.end());
85 EXPECT_TRUE(set.find(dangling_foo3) == set.end());
86
87 raw_foo3 = nullptr; // Avoid dangling raw_ptr.
88 delete foo3;
89 EXPECT_EQ(0, Foo::instance_count);
90 }
91
TEST(UniquePtrMatcherTest,Basic)92 TEST(UniquePtrMatcherTest, Basic) {
93 std::vector<std::unique_ptr<Foo>> v;
94
95 auto foo_ptr1 = std::make_unique<Foo>();
96 Foo* foo1 = foo_ptr1.get();
97 raw_ptr<Foo> raw_foo1 = foo1;
98 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
99 v.push_back(std::move(foo_ptr1));
100
101 auto foo_ptr2 = std::make_unique<Foo>();
102 Foo* foo2 = foo_ptr2.get();
103 raw_ptr<Foo> raw_foo2 = foo2;
104 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
105 v.push_back(std::move(foo_ptr2));
106
107 auto foo_ptr3 = std::make_unique<Foo>();
108 Foo* foo3 = foo_ptr3.get();
109 raw_ptr<Foo> raw_foo3 = foo3;
110 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
111
112 {
113 auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo1));
114 ASSERT_TRUE(iter != v.end());
115 EXPECT_EQ(foo1, iter->get());
116 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo1)) == iter);
117 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo1)) ==
118 iter);
119 }
120
121 {
122 auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo2));
123 ASSERT_TRUE(iter != v.end());
124 EXPECT_EQ(foo2, iter->get());
125 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo2)) == iter);
126 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo2)) ==
127 iter);
128 }
129
130 {
131 auto iter = ranges::find_if(v, MatchesUniquePtr(foo2));
132 ASSERT_TRUE(iter != v.end());
133 EXPECT_EQ(foo2, iter->get());
134 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(raw_foo2)) == iter);
135 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(dangling_foo2)) == iter);
136 }
137
138 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(foo3)) == v.end());
139 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo3)) == v.end());
140 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo3)) ==
141 v.end());
142
143 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(foo3)) == v.end());
144 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(raw_foo3)) == v.end());
145 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(dangling_foo3)) == v.end());
146
147 raw_foo1 = nullptr;
148 raw_foo2 = nullptr;
149 raw_foo3 = nullptr;
150 }
151
152 class TestDeleter {
153 public:
operator ()(Foo * foo)154 void operator()(Foo* foo) { delete foo; }
155 };
156
TEST(UniquePtrMatcherTest,Deleter)157 TEST(UniquePtrMatcherTest, Deleter) {
158 using UniqueFoo = std::unique_ptr<Foo, TestDeleter>;
159 std::vector<UniqueFoo> v;
160
161 UniqueFoo foo_ptr1(new Foo);
162 Foo* foo1 = foo_ptr1.get();
163 raw_ptr<Foo> raw_foo1 = foo1;
164 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
165 v.push_back(std::move(foo_ptr1));
166
167 UniqueFoo foo_ptr2(new Foo);
168 Foo* foo2 = foo_ptr2.get();
169 raw_ptr<Foo> raw_foo2 = foo2;
170 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
171 v.push_back(std::move(foo_ptr2));
172
173 UniqueFoo foo_ptr3(new Foo);
174 Foo* foo3 = foo_ptr3.get();
175 raw_ptr<Foo> raw_foo3 = foo3;
176 raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
177
178 {
179 auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo1));
180 ASSERT_TRUE(iter != v.end());
181 EXPECT_EQ(foo1, iter->get());
182 EXPECT_TRUE(ranges::find_if(
183 v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo1)) == iter);
184 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
185 dangling_foo1)) == iter);
186 }
187
188 {
189 auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo2));
190 ASSERT_TRUE(iter != v.end());
191 EXPECT_EQ(foo2, iter->get());
192 EXPECT_TRUE(ranges::find_if(
193 v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo2)) == iter);
194 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
195 dangling_foo2)) == iter);
196 }
197
198 {
199 auto iter = ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo2));
200 ASSERT_TRUE(iter != v.end());
201 EXPECT_EQ(foo2, iter->get());
202 EXPECT_TRUE(ranges::find_if(
203 v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo2)) == iter);
204 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
205 dangling_foo2)) == iter);
206 }
207
208 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo3)) ==
209 v.end());
210 EXPECT_TRUE(ranges::find_if(
211 v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo3)) == v.end());
212 EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
213 dangling_foo3)) == v.end());
214
215 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo3)) ==
216 v.end());
217 EXPECT_TRUE(ranges::find_if(
218 v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo3)) == v.end());
219 EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
220 dangling_foo3)) == v.end());
221
222 raw_foo1 = nullptr;
223 raw_foo2 = nullptr;
224 raw_foo3 = nullptr;
225 }
226
227 } // namespace
228 } // namespace base
229