| // 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/unowned_ptr.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, UnownedPtr) { | |
| int delete_count = 0; | |
| PseudoDeletable thing1(100, &delete_count); | |
| PseudoDeletable thing2(200, &delete_count); | |
| UnownedPtr<PseudoDeletable> unowned1(&thing1); | |
| UnownedPtr<PseudoDeletable> unowned2(&thing2); | |
| { | |
| MaybeOwned<PseudoDeletable> ptr1(unowned1); | |
| MaybeOwned<PseudoDeletable> ptr2(unowned2); | |
| ptr2 = unowned1; | |
| ptr1 = unowned2; | |
| } | |
| EXPECT_EQ(0, 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 |