Index: third_party/base/nonstd_unique_ptr_unittest.cpp |
diff --git a/third_party/base/nonstd_unique_ptr_unittest.cpp b/third_party/base/nonstd_unique_ptr_unittest.cpp |
index 49cc901fe26e248f084a194fba34737e1e0f4bfc..2b120581f422ebe5265ad0b5a9234d2221744e81 100644 |
--- a/third_party/base/nonstd_unique_ptr_unittest.cpp |
+++ b/third_party/base/nonstd_unique_ptr_unittest.cpp |
@@ -85,3 +85,306 @@ TEST(UniquePtrTest, MoveTest) { |
} |
EXPECT_EQ(0, constructed); |
} |
+ |
+TEST(UniquePtrTest, UniquePtr) { |
+ int constructed = 0; |
+ |
+ // Ensure size of unique_ptr<> doesn't increase unexpectedly. |
+ static_assert(sizeof(int*) >= sizeof(unique_ptr<int>), |
+ "unique_ptr_larger_than_raw_ptr"); |
+ |
+ { |
+ unique_ptr<CtorDtorLogger> scoper(new CtorDtorLogger(&constructed)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_TRUE(scoper.get()); |
+ |
+ EXPECT_EQ(10, scoper->SomeMeth(10)); |
+ EXPECT_EQ(10, scoper.get()->SomeMeth(10)); |
+ EXPECT_EQ(10, (*scoper).SomeMeth(10)); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test reset() and release() |
+ { |
+ unique_ptr<CtorDtorLogger> scoper(new CtorDtorLogger(&constructed)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_TRUE(scoper.get()); |
+ |
+ scoper.reset(new CtorDtorLogger(&constructed)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_TRUE(scoper.get()); |
+ |
+ scoper.reset(); |
+ EXPECT_EQ(0, constructed); |
+ EXPECT_FALSE(scoper.get()); |
+ |
+ scoper.reset(new CtorDtorLogger(&constructed)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_TRUE(scoper.get()); |
+ |
+ CtorDtorLogger* take = scoper.release(); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_FALSE(scoper.get()); |
+ delete take; |
+ EXPECT_EQ(0, constructed); |
+ |
+ scoper.reset(new CtorDtorLogger(&constructed)); |
+ EXPECT_EQ(1, constructed); |
+ EXPECT_TRUE(scoper.get()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test swap(), == and != |
+ { |
+ unique_ptr<CtorDtorLogger> scoper1; |
+ unique_ptr<CtorDtorLogger> scoper2; |
+ EXPECT_TRUE(scoper1 == scoper2.get()); |
+ EXPECT_FALSE(scoper1 != scoper2.get()); |
+ |
+ CtorDtorLogger* logger = new CtorDtorLogger(&constructed); |
+ scoper1.reset(logger); |
+ EXPECT_EQ(logger, scoper1.get()); |
+ EXPECT_FALSE(scoper2.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ |
+ scoper2.swap(scoper1); |
+ EXPECT_EQ(logger, scoper2.get()); |
+ EXPECT_FALSE(scoper1.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(UniquePtrTest, UniquePtrWithArray) { |
+ static const int kNumLoggers = 12; |
+ |
+ int constructed = 0; |
+ |
+ { |
+ unique_ptr<CtorDtorLogger[]> scoper(new CtorDtorLogger[kNumLoggers]); |
+ EXPECT_TRUE(scoper); |
+ EXPECT_EQ(&scoper[0], scoper.get()); |
+ for (int i = 0; i < kNumLoggers; ++i) { |
+ scoper[i].SetPtr(&constructed); |
+ } |
+ EXPECT_EQ(12, constructed); |
+ |
+ EXPECT_EQ(10, scoper.get()->SomeMeth(10)); |
+ EXPECT_EQ(10, scoper[2].SomeMeth(10)); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test reset() and release() |
+ { |
+ unique_ptr<CtorDtorLogger[]> scoper; |
+ EXPECT_FALSE(scoper.get()); |
+ EXPECT_FALSE(scoper.release()); |
+ EXPECT_FALSE(scoper.get()); |
+ scoper.reset(); |
+ EXPECT_FALSE(scoper.get()); |
+ |
+ scoper.reset(new CtorDtorLogger[kNumLoggers]); |
+ for (int i = 0; i < kNumLoggers; ++i) { |
+ scoper[i].SetPtr(&constructed); |
+ } |
+ EXPECT_EQ(12, constructed); |
+ scoper.reset(); |
+ EXPECT_EQ(0, constructed); |
+ |
+ scoper.reset(new CtorDtorLogger[kNumLoggers]); |
+ for (int i = 0; i < kNumLoggers; ++i) { |
+ scoper[i].SetPtr(&constructed); |
+ } |
+ EXPECT_EQ(12, constructed); |
+ CtorDtorLogger* ptr = scoper.release(); |
+ EXPECT_EQ(12, constructed); |
+ delete[] ptr; |
+ EXPECT_EQ(0, constructed); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test swap(), ==, !=, and type-safe Boolean. |
+ { |
+ unique_ptr<CtorDtorLogger[]> scoper1; |
+ unique_ptr<CtorDtorLogger[]> scoper2; |
+ EXPECT_TRUE(scoper1 == scoper2.get()); |
+ EXPECT_FALSE(scoper1 != scoper2.get()); |
+ |
+ CtorDtorLogger* loggers = new CtorDtorLogger[kNumLoggers]; |
+ for (int i = 0; i < kNumLoggers; ++i) { |
+ loggers[i].SetPtr(&constructed); |
+ } |
+ scoper1.reset(loggers); |
+ EXPECT_TRUE(scoper1); |
+ EXPECT_EQ(loggers, scoper1.get()); |
+ EXPECT_FALSE(scoper2); |
+ EXPECT_FALSE(scoper2.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ |
+ scoper2.swap(scoper1); |
+ EXPECT_EQ(loggers, scoper2.get()); |
+ EXPECT_FALSE(scoper1.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(UniquePtrTest, ReturnTypeBehavior) { |
+ int constructed = 0; |
+ |
+ // Test that we can return a unique_ptr. |
+ { |
+ CtorDtorLogger* logger = new CtorDtorLogger(&constructed); |
+ unique_ptr<CtorDtorLogger> scoper(logger); |
+ EXPECT_EQ(1, constructed); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Test uncaught return type not leak. |
+ { |
+ CtorDtorLogger* logger = new CtorDtorLogger(&constructed); |
+ unique_ptr<CtorDtorLogger> scoper(logger); |
+ EXPECT_EQ(1, constructed); |
+ } |
+ EXPECT_EQ(0, constructed); |
+ |
+ // Call TestReturnOfType() so the compiler doesn't warn for an unused |
+ // function. |
+ { TestReturnOfType(&constructed); } |
+ EXPECT_EQ(0, constructed); |
+} |
+ |
+TEST(UniquePtrTest, CustomDeleter) { |
+ double dummy_value; // Custom deleter never touches this value. |
+ int deletes = 0; |
+ int alternate_deletes = 0; |
+ |
+ // Normal delete support. |
+ { |
+ deletes = 0; |
+ unique_ptr<double, CountingDeleter> scoper(&dummy_value, |
+ CountingDeleter(&deletes)); |
+ EXPECT_EQ(0, deletes); |
+ EXPECT_TRUE(scoper.get()); |
+ } |
+ EXPECT_EQ(1, deletes); |
+ |
+ // Test reset() and release(). |
+ deletes = 0; |
+ { |
+ unique_ptr<double, CountingDeleter> scoper(nullptr, |
+ CountingDeleter(&deletes)); |
+ EXPECT_FALSE(scoper.get()); |
+ EXPECT_FALSE(scoper.release()); |
+ EXPECT_FALSE(scoper.get()); |
+ scoper.reset(); |
+ EXPECT_FALSE(scoper.get()); |
+ EXPECT_EQ(0, deletes); |
+ |
+ scoper.reset(&dummy_value); |
+ scoper.reset(); |
+ EXPECT_EQ(1, deletes); |
+ |
+ scoper.reset(&dummy_value); |
+ EXPECT_EQ(&dummy_value, scoper.release()); |
+ } |
+ EXPECT_EQ(1, deletes); |
+ |
+ // Test get_deleter(). |
+ deletes = 0; |
+ alternate_deletes = 0; |
+ { |
+ unique_ptr<double, CountingDeleter> scoper(&dummy_value, |
+ CountingDeleter(&deletes)); |
+ // Call deleter manually. |
+ EXPECT_EQ(0, deletes); |
+ scoper.get_deleter()(&dummy_value); |
+ EXPECT_EQ(1, deletes); |
+ |
+ // Deleter is still there after reset. |
+ scoper.reset(); |
+ EXPECT_EQ(2, deletes); |
+ scoper.get_deleter()(&dummy_value); |
+ EXPECT_EQ(3, deletes); |
+ |
+ // Deleter can be assigned into (matches C++11 unique_ptr<> spec). |
+ scoper.get_deleter() = CountingDeleter(&alternate_deletes); |
+ scoper.reset(&dummy_value); |
+ EXPECT_EQ(0, alternate_deletes); |
+ } |
+ EXPECT_EQ(3, deletes); |
+ EXPECT_EQ(1, alternate_deletes); |
+ |
+ // Test swap(), ==, !=, and type-safe Boolean. |
+ { |
+ unique_ptr<double, CountingDeleter> scoper1(nullptr, |
+ CountingDeleter(&deletes)); |
+ unique_ptr<double, CountingDeleter> scoper2(nullptr, |
+ CountingDeleter(&deletes)); |
+ EXPECT_TRUE(scoper1 == scoper2.get()); |
+ EXPECT_FALSE(scoper1 != scoper2.get()); |
+ |
+ scoper1.reset(&dummy_value); |
+ EXPECT_TRUE(scoper1); |
+ EXPECT_EQ(&dummy_value, scoper1.get()); |
+ EXPECT_FALSE(scoper2); |
+ EXPECT_FALSE(scoper2.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ |
+ scoper2.swap(scoper1); |
+ EXPECT_EQ(&dummy_value, scoper2.get()); |
+ EXPECT_FALSE(scoper1.get()); |
+ EXPECT_FALSE(scoper1 == scoper2.get()); |
+ EXPECT_TRUE(scoper1 != scoper2.get()); |
+ } |
+} |
+ |
+unique_ptr<int> NullIntReturn() { |
+ return nullptr; |
+} |
+ |
+TEST(UniquePtrTest, Nullptr) { |
+ unique_ptr<int> scoper1(nullptr); |
+ unique_ptr<int> scoper2(new int); |
+ scoper2 = nullptr; |
+ unique_ptr<int> scoper3(NullIntReturn()); |
+ unique_ptr<int> scoper4 = NullIntReturn(); |
+ EXPECT_EQ(nullptr, scoper1.get()); |
+ EXPECT_EQ(nullptr, scoper2.get()); |
+ EXPECT_EQ(nullptr, scoper3.get()); |
+ EXPECT_EQ(nullptr, scoper4.get()); |
+} |
+ |
+unique_ptr<int[]> NullIntArrayReturn() { |
+ return nullptr; |
+} |
+ |
+TEST(UniquePtrTest, NullptrArray) { |
+ unique_ptr<int[]> scoper1(nullptr); |
+ unique_ptr<int[]> scoper2(new int[3]); |
+ scoper2 = nullptr; |
+ unique_ptr<int[]> scoper3(NullIntArrayReturn()); |
+ unique_ptr<int[]> scoper4 = NullIntArrayReturn(); |
+ EXPECT_EQ(nullptr, scoper1.get()); |
+ EXPECT_EQ(nullptr, scoper2.get()); |
+ EXPECT_EQ(nullptr, scoper3.get()); |
+ EXPECT_EQ(nullptr, scoper4.get()); |
+} |
+ |
+// Logging a unique_ptr<T> to an ostream shouldn't convert it to a boolean |
+// value first. |
+TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) { |
+ unique_ptr<int> x(new int); |
+ std::stringstream s1; |
+ s1 << x; |
+ |
+ std::stringstream s2; |
+ s2 << x.get(); |
+ |
+ EXPECT_EQ(s2.str(), s1.str()); |
+} |