blob: 3ede4e5ed08446c091a611f82cf38e6912829966 [file] [log] [blame] [edit]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/containers/unique_ptr_adapters.h"
#include <algorithm>
#include <memory>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace {
class Foo {
public:
Foo() { instance_count++; }
~Foo() { instance_count--; }
static int instance_count;
};
int Foo::instance_count = 0;
TEST(UniquePtrComparatorTest, Basic) {
std::set<std::unique_ptr<Foo>, UniquePtrComparator> set;
Foo* foo1 = new Foo();
Foo* foo2 = new Foo();
Foo* foo3 = new Foo();
EXPECT_EQ(3, Foo::instance_count);
raw_ptr<Foo> raw_foo1 = foo1;
raw_ptr<Foo> raw_foo2 = foo2;
raw_ptr<Foo> raw_foo3 = foo3;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
set.emplace(foo1);
set.emplace(foo2);
auto it1 = set.find(foo1);
EXPECT_TRUE(it1 != set.end());
EXPECT_EQ(foo1, it1->get());
EXPECT_TRUE(set.find(raw_foo1) == it1);
EXPECT_TRUE(set.find(dangling_foo1) == it1);
{
auto it2 = set.find(foo2);
EXPECT_TRUE(it2 != set.end());
EXPECT_EQ(foo2, it2->get());
EXPECT_TRUE(set.find(raw_foo2) == it2);
EXPECT_TRUE(set.find(dangling_foo2) == it2);
}
EXPECT_TRUE(set.find(foo3) == set.end());
EXPECT_TRUE(set.find(raw_foo3) == set.end());
EXPECT_TRUE(set.find(dangling_foo3) == set.end());
raw_foo1 = nullptr; // Avoid dangling raw_ptr.
set.erase(it1);
EXPECT_EQ(2, Foo::instance_count);
EXPECT_TRUE(set.find(foo1) == set.end());
EXPECT_TRUE(set.find(dangling_foo1) == set.end());
{
auto it2 = set.find(foo2);
EXPECT_TRUE(it2 != set.end());
EXPECT_EQ(foo2, it2->get());
EXPECT_TRUE(set.find(raw_foo2) == it2);
EXPECT_TRUE(set.find(dangling_foo2) == it2);
}
raw_foo2 = nullptr; // Avoid dangling raw_ptr.
set.clear();
EXPECT_EQ(1, Foo::instance_count);
EXPECT_TRUE(set.find(foo1) == set.end());
EXPECT_TRUE(set.find(foo2) == set.end());
EXPECT_TRUE(set.find(foo3) == set.end());
EXPECT_TRUE(set.find(dangling_foo1) == set.end());
EXPECT_TRUE(set.find(dangling_foo2) == set.end());
EXPECT_TRUE(set.find(dangling_foo3) == set.end());
raw_foo3 = nullptr; // Avoid dangling raw_ptr.
delete foo3;
EXPECT_EQ(0, Foo::instance_count);
}
TEST(UniquePtrMatcherTest, Basic) {
std::vector<std::unique_ptr<Foo>> v;
auto foo_ptr1 = std::make_unique<Foo>();
Foo* foo1 = foo_ptr1.get();
raw_ptr<Foo> raw_foo1 = foo1;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
v.push_back(std::move(foo_ptr1));
auto foo_ptr2 = std::make_unique<Foo>();
Foo* foo2 = foo_ptr2.get();
raw_ptr<Foo> raw_foo2 = foo2;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
v.push_back(std::move(foo_ptr2));
auto foo_ptr3 = std::make_unique<Foo>();
Foo* foo3 = foo_ptr3.get();
raw_ptr<Foo> raw_foo3 = foo3;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
{
auto iter = std::ranges::find_if(v, UniquePtrMatcher<Foo>(foo1));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo1, iter->get());
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo1)) ==
iter);
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo1)) ==
iter);
}
{
auto iter = std::ranges::find_if(v, UniquePtrMatcher<Foo>(foo2));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo2, iter->get());
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo2)) ==
iter);
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo2)) ==
iter);
}
{
auto iter = std::ranges::find_if(v, MatchesUniquePtr(foo2));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo2, iter->get());
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr(raw_foo2)) == iter);
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr(dangling_foo2)) ==
iter);
}
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo3)) ==
v.end());
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo3)) ==
v.end());
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr(foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr(raw_foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr(dangling_foo3)) ==
v.end());
raw_foo1 = nullptr;
raw_foo2 = nullptr;
raw_foo3 = nullptr;
}
class TestDeleter {
public:
void operator()(Foo* foo) { delete foo; }
};
TEST(UniquePtrMatcherTest, Deleter) {
using UniqueFoo = std::unique_ptr<Foo, TestDeleter>;
std::vector<UniqueFoo> v;
UniqueFoo foo_ptr1(new Foo);
Foo* foo1 = foo_ptr1.get();
raw_ptr<Foo> raw_foo1 = foo1;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
v.push_back(std::move(foo_ptr1));
UniqueFoo foo_ptr2(new Foo);
Foo* foo2 = foo_ptr2.get();
raw_ptr<Foo> raw_foo2 = foo2;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
v.push_back(std::move(foo_ptr2));
UniqueFoo foo_ptr3(new Foo);
Foo* foo3 = foo_ptr3.get();
raw_ptr<Foo> raw_foo3 = foo3;
raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
{
auto iter =
std::ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo1));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo1, iter->get());
EXPECT_TRUE(std::ranges::find_if(
v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo1)) == iter);
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
dangling_foo1)) == iter);
}
{
auto iter =
std::ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo2));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo2, iter->get());
EXPECT_TRUE(std::ranges::find_if(
v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo2)) == iter);
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
dangling_foo2)) == iter);
}
{
auto iter =
std::ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo2));
ASSERT_TRUE(iter != v.end());
EXPECT_EQ(foo2, iter->get());
EXPECT_TRUE(std::ranges::find_if(
v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo2)) == iter);
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
dangling_foo2)) == iter);
}
EXPECT_TRUE(std::ranges::find_if(
v, UniquePtrMatcher<Foo, TestDeleter>(foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(
v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
dangling_foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(
v, MatchesUniquePtr<Foo, TestDeleter>(foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(
v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo3)) == v.end());
EXPECT_TRUE(std::ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
dangling_foo3)) == v.end());
raw_foo1 = nullptr;
raw_foo2 = nullptr;
raw_foo3 = nullptr;
}
} // namespace
} // namespace base