// Copyright 2016 PDFium Authors. All rights reserved.
|
// Use of this source code is governed by a BSD-style license that can be
|
// found in the LICENSE file.
|
|
#include "core/fxcrt/maybe_owned.h"
|
|
#include <memory>
|
#include <utility>
|
|
#include "core/fxcrt/fx_memory.h"
|
#include "testing/gtest/include/gtest/gtest.h"
|
#include "third_party/base/ptr_util.h"
|
|
namespace fxcrt {
|
namespace {
|
|
class PseudoDeletable {
|
public:
|
explicit PseudoDeletable(int id, int* count_location)
|
: id_(id), count_location_(count_location) {}
|
~PseudoDeletable() { ++(*count_location_); }
|
int GetID() const { return id_; }
|
|
private:
|
int id_;
|
int* count_location_;
|
};
|
|
} // namespace
|
|
TEST(MaybeOwned, Null) {
|
MaybeOwned<PseudoDeletable> ptr1;
|
EXPECT_FALSE(ptr1.IsOwned());
|
EXPECT_FALSE(ptr1);
|
EXPECT_EQ(nullptr, ptr1.Get());
|
|
MaybeOwned<PseudoDeletable> ptr2;
|
EXPECT_TRUE(ptr1 == ptr2);
|
EXPECT_FALSE(ptr1 != ptr2);
|
}
|
|
TEST(MaybeOwned, NotOwned) {
|
int delete_count = 0;
|
PseudoDeletable thing1(100, &delete_count);
|
{
|
MaybeOwned<PseudoDeletable> ptr(&thing1);
|
EXPECT_FALSE(ptr.IsOwned());
|
EXPECT_EQ(ptr.Get(), &thing1);
|
EXPECT_EQ(100, ptr->GetID());
|
EXPECT_TRUE(ptr == &thing1);
|
EXPECT_FALSE(ptr != &thing1);
|
|
MaybeOwned<PseudoDeletable> empty;
|
EXPECT_FALSE(ptr == empty);
|
EXPECT_TRUE(ptr != empty);
|
}
|
EXPECT_EQ(0, delete_count);
|
|
delete_count = 0;
|
PseudoDeletable thing2(200, &delete_count);
|
{
|
MaybeOwned<PseudoDeletable> ptr(&thing1);
|
ptr = &thing2;
|
EXPECT_FALSE(ptr.IsOwned());
|
EXPECT_EQ(ptr.Get(), &thing2);
|
EXPECT_EQ(200, ptr->GetID());
|
}
|
EXPECT_EQ(0, delete_count);
|
|
delete_count = 0;
|
int owned_delete_count = 0;
|
{
|
MaybeOwned<PseudoDeletable> ptr(&thing1);
|
EXPECT_EQ(100, ptr->GetID());
|
ptr = pdfium::MakeUnique<PseudoDeletable>(300, &owned_delete_count);
|
EXPECT_TRUE(ptr.IsOwned());
|
EXPECT_EQ(300, ptr->GetID());
|
}
|
EXPECT_EQ(0, delete_count);
|
EXPECT_EQ(1, owned_delete_count);
|
}
|
|
TEST(MaybeOwned, Owned) {
|
int delete_count = 0;
|
{
|
MaybeOwned<PseudoDeletable> ptr(
|
pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
|
EXPECT_TRUE(ptr.IsOwned());
|
EXPECT_EQ(100, ptr->GetID());
|
|
MaybeOwned<PseudoDeletable> empty;
|
EXPECT_FALSE(ptr == empty);
|
EXPECT_TRUE(ptr != empty);
|
}
|
EXPECT_EQ(1, delete_count);
|
|
delete_count = 0;
|
{
|
MaybeOwned<PseudoDeletable> ptr(
|
pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
|
ptr = pdfium::MakeUnique<PseudoDeletable>(300, &delete_count);
|
EXPECT_TRUE(ptr.IsOwned());
|
EXPECT_EQ(300, ptr->GetID());
|
EXPECT_EQ(1, delete_count);
|
}
|
EXPECT_EQ(2, delete_count);
|
|
delete_count = 0;
|
int unowned_delete_count = 0;
|
PseudoDeletable thing2(400, &unowned_delete_count);
|
{
|
MaybeOwned<PseudoDeletable> ptr(
|
pdfium::MakeUnique<PseudoDeletable>(500, &delete_count));
|
ptr = &thing2;
|
EXPECT_FALSE(ptr.IsOwned());
|
EXPECT_EQ(400, ptr->GetID());
|
EXPECT_EQ(1, delete_count);
|
EXPECT_EQ(0, unowned_delete_count);
|
}
|
EXPECT_EQ(1, delete_count);
|
EXPECT_EQ(0, unowned_delete_count);
|
}
|
|
TEST(MaybeOwned, Release) {
|
int delete_count = 0;
|
{
|
std::unique_ptr<PseudoDeletable> stolen;
|
{
|
MaybeOwned<PseudoDeletable> ptr(
|
pdfium::MakeUnique<PseudoDeletable>(100, &delete_count));
|
EXPECT_TRUE(ptr.IsOwned());
|
stolen = ptr.Release();
|
EXPECT_FALSE(ptr.IsOwned());
|
EXPECT_EQ(ptr, stolen);
|
EXPECT_EQ(0, delete_count);
|
}
|
EXPECT_EQ(0, delete_count);
|
}
|
EXPECT_EQ(1, delete_count);
|
}
|
|
TEST(MaybeOwned, Move) {
|
int delete_count = 0;
|
PseudoDeletable thing1(100, &delete_count);
|
{
|
MaybeOwned<PseudoDeletable> ptr1(&thing1);
|
MaybeOwned<PseudoDeletable> ptr2(
|
pdfium::MakeUnique<PseudoDeletable>(200, &delete_count));
|
EXPECT_FALSE(ptr1.IsOwned());
|
EXPECT_TRUE(ptr2.IsOwned());
|
|
MaybeOwned<PseudoDeletable> ptr3(std::move(ptr1));
|
MaybeOwned<PseudoDeletable> ptr4(std::move(ptr2));
|
EXPECT_FALSE(ptr1.IsOwned());
|
EXPECT_FALSE(ptr2.IsOwned());
|
EXPECT_FALSE(ptr3.IsOwned());
|
EXPECT_TRUE(ptr4.IsOwned());
|
EXPECT_EQ(0, delete_count);
|
EXPECT_EQ(nullptr, ptr1.Get());
|
EXPECT_EQ(nullptr, ptr2.Get());
|
EXPECT_EQ(100, ptr3->GetID());
|
EXPECT_EQ(200, ptr4->GetID());
|
|
MaybeOwned<PseudoDeletable> ptr5;
|
MaybeOwned<PseudoDeletable> ptr6;
|
ptr5 = std::move(ptr3);
|
ptr6 = std::move(ptr4);
|
EXPECT_FALSE(ptr3.IsOwned());
|
EXPECT_FALSE(ptr4.IsOwned());
|
EXPECT_FALSE(ptr5.IsOwned());
|
EXPECT_TRUE(ptr6.IsOwned());
|
EXPECT_EQ(0, delete_count);
|
EXPECT_EQ(nullptr, ptr3.Get());
|
EXPECT_EQ(nullptr, ptr4.Get());
|
EXPECT_EQ(100, ptr5->GetID());
|
EXPECT_EQ(200, ptr6->GetID());
|
}
|
EXPECT_EQ(1, delete_count);
|
}
|
|
} // namespace fxcrt
|