1 // Copyright 2016 PDFium Authors. All rights reserved. 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 "core/fxcrt/maybe_owned.h" 6 7 #include <memory> 8 #include <utility> 9 10 #include "core/fxcrt/fx_memory.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "third_party/base/ptr_util.h" 13 14 namespace fxcrt { 15 namespace { 16 17 class PseudoDeletable { 18 public: 19 explicit PseudoDeletable(int id, int* count_location) 20 : id_(id), count_location_(count_location) {} 21 ~PseudoDeletable() { ++(*count_location_); } 22 int GetID() const { return id_; } 23 24 private: 25 int id_; 26 int* count_location_; 27 }; 28 29 } // namespace 30 31 TEST(MaybeOwned, Null) { 32 MaybeOwned<PseudoDeletable> ptr1; 33 EXPECT_FALSE(ptr1.IsOwned()); 34 EXPECT_FALSE(ptr1); 35 EXPECT_EQ(nullptr, ptr1.Get()); 36 37 MaybeOwned<PseudoDeletable> ptr2; 38 EXPECT_TRUE(ptr1 == ptr2); 39 EXPECT_FALSE(ptr1 != ptr2); 40 } 41 42 TEST(MaybeOwned, NotOwned) { 43 int delete_count = 0; 44 PseudoDeletable thing1(100, &delete_count); 45 { 46 MaybeOwned<PseudoDeletable> ptr(&thing1); 47 EXPECT_FALSE(ptr.IsOwned()); 48 EXPECT_EQ(ptr.Get(), &thing1); 49 EXPECT_EQ(100, ptr->GetID()); 50 EXPECT_TRUE(ptr == &thing1); 51 EXPECT_FALSE(ptr != &thing1); 52 53 MaybeOwned<PseudoDeletable> empty; 54 EXPECT_FALSE(ptr == empty); 55 EXPECT_TRUE(ptr != empty); 56 } 57 EXPECT_EQ(0, delete_count); 58 59 delete_count = 0; 60 PseudoDeletable thing2(200, &delete_count); 61 { 62 MaybeOwned<PseudoDeletable> ptr(&thing1); 63 ptr = &thing2; 64 EXPECT_FALSE(ptr.IsOwned()); 65 EXPECT_EQ(ptr.Get(), &thing2); 66 EXPECT_EQ(200, ptr->GetID()); 67 } 68 EXPECT_EQ(0, delete_count); 69 70 delete_count = 0; 71 int owned_delete_count = 0; 72 { 73 MaybeOwned<PseudoDeletable> ptr(&thing1); 74 EXPECT_EQ(100, ptr->GetID()); 75 ptr = pdfium::MakeUnique<PseudoDeletable>(300, &owned_delete_count); 76 EXPECT_TRUE(ptr.IsOwned()); 77 EXPECT_EQ(300, ptr->GetID()); 78 } 79 EXPECT_EQ(0, delete_count); 80 EXPECT_EQ(1, owned_delete_count); 81 } 82 83 TEST(MaybeOwned, Owned) { 84 int delete_count = 0; 85 { 86 MaybeOwned<PseudoDeletable> ptr( 87 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count)); 88 EXPECT_TRUE(ptr.IsOwned()); 89 EXPECT_EQ(100, ptr->GetID()); 90 91 MaybeOwned<PseudoDeletable> empty; 92 EXPECT_FALSE(ptr == empty); 93 EXPECT_TRUE(ptr != empty); 94 } 95 EXPECT_EQ(1, delete_count); 96 97 delete_count = 0; 98 { 99 MaybeOwned<PseudoDeletable> ptr( 100 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count)); 101 ptr = pdfium::MakeUnique<PseudoDeletable>(300, &delete_count); 102 EXPECT_TRUE(ptr.IsOwned()); 103 EXPECT_EQ(300, ptr->GetID()); 104 EXPECT_EQ(1, delete_count); 105 } 106 EXPECT_EQ(2, delete_count); 107 108 delete_count = 0; 109 int unowned_delete_count = 0; 110 PseudoDeletable thing2(400, &unowned_delete_count); 111 { 112 MaybeOwned<PseudoDeletable> ptr( 113 pdfium::MakeUnique<PseudoDeletable>(500, &delete_count)); 114 ptr = &thing2; 115 EXPECT_FALSE(ptr.IsOwned()); 116 EXPECT_EQ(400, ptr->GetID()); 117 EXPECT_EQ(1, delete_count); 118 EXPECT_EQ(0, unowned_delete_count); 119 } 120 EXPECT_EQ(1, delete_count); 121 EXPECT_EQ(0, unowned_delete_count); 122 } 123 124 TEST(MaybeOwned, Release) { 125 int delete_count = 0; 126 { 127 std::unique_ptr<PseudoDeletable> stolen; 128 { 129 MaybeOwned<PseudoDeletable> ptr( 130 pdfium::MakeUnique<PseudoDeletable>(100, &delete_count)); 131 EXPECT_TRUE(ptr.IsOwned()); 132 stolen = ptr.Release(); 133 EXPECT_FALSE(ptr.IsOwned()); 134 EXPECT_EQ(ptr, stolen); 135 EXPECT_EQ(0, delete_count); 136 } 137 EXPECT_EQ(0, delete_count); 138 } 139 EXPECT_EQ(1, delete_count); 140 } 141 142 TEST(MaybeOwned, Move) { 143 int delete_count = 0; 144 PseudoDeletable thing1(100, &delete_count); 145 { 146 MaybeOwned<PseudoDeletable> ptr1(&thing1); 147 MaybeOwned<PseudoDeletable> ptr2( 148 pdfium::MakeUnique<PseudoDeletable>(200, &delete_count)); 149 EXPECT_FALSE(ptr1.IsOwned()); 150 EXPECT_TRUE(ptr2.IsOwned()); 151 152 MaybeOwned<PseudoDeletable> ptr3(std::move(ptr1)); 153 MaybeOwned<PseudoDeletable> ptr4(std::move(ptr2)); 154 EXPECT_FALSE(ptr1.IsOwned()); 155 EXPECT_FALSE(ptr2.IsOwned()); 156 EXPECT_FALSE(ptr3.IsOwned()); 157 EXPECT_TRUE(ptr4.IsOwned()); 158 EXPECT_EQ(0, delete_count); 159 EXPECT_EQ(nullptr, ptr1.Get()); 160 EXPECT_EQ(nullptr, ptr2.Get()); 161 EXPECT_EQ(100, ptr3->GetID()); 162 EXPECT_EQ(200, ptr4->GetID()); 163 164 MaybeOwned<PseudoDeletable> ptr5; 165 MaybeOwned<PseudoDeletable> ptr6; 166 ptr5 = std::move(ptr3); 167 ptr6 = std::move(ptr4); 168 EXPECT_FALSE(ptr3.IsOwned()); 169 EXPECT_FALSE(ptr4.IsOwned()); 170 EXPECT_FALSE(ptr5.IsOwned()); 171 EXPECT_TRUE(ptr6.IsOwned()); 172 EXPECT_EQ(0, delete_count); 173 EXPECT_EQ(nullptr, ptr3.Get()); 174 EXPECT_EQ(nullptr, ptr4.Get()); 175 EXPECT_EQ(100, ptr5->GetID()); 176 EXPECT_EQ(200, ptr6->GetID()); 177 } 178 EXPECT_EQ(1, delete_count); 179 } 180 181 } // namespace fxcrt 182