• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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