//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "lldb/Utility/NonNullSharedPtr.h" #include "gtest/gtest.h" #include using namespace lldb_private; namespace { struct TestObject { int value; TestObject() : value(0) {} explicit TestObject(int v) : value(v) {} }; } // namespace TEST(NonNullSharedPtrTest, ConstructFromValidSharedPtr) { auto sp = std::make_shared(42); NonNullSharedPtr nps(sp); EXPECT_EQ(nps->value, 42); EXPECT_EQ(nps.get(), sp.get()); EXPECT_EQ(nps.use_count(), 2); } TEST(NonNullSharedPtrTest, ConstructFromRValueSharedPtr) { auto sp = std::make_shared(100); auto *raw_ptr = sp.get(); NonNullSharedPtr nps(std::move(sp)); EXPECT_EQ(nps->value, 100); EXPECT_EQ(nps.get(), raw_ptr); EXPECT_EQ(nps.use_count(), 1); } TEST(NonNullSharedPtrTest, CopyConstructor) { auto sp = std::make_shared(42); NonNullSharedPtr nps1(sp); NonNullSharedPtr nps2(nps1); EXPECT_EQ(nps1.get(), nps2.get()); EXPECT_EQ(nps2->value, 42); EXPECT_EQ(nps1.use_count(), 3); EXPECT_EQ(nps2.use_count(), 3); } TEST(NonNullSharedPtrTest, MoveConstructor) { auto sp = std::make_shared(42); auto *raw_ptr = sp.get(); NonNullSharedPtr nps1(sp); NonNullSharedPtr nps2(std::move(nps1)); EXPECT_EQ(nps2.get(), raw_ptr); EXPECT_EQ(nps2->value, 42); EXPECT_EQ(nps2.use_count(), 2); } TEST(NonNullSharedPtrTest, CopyAssignment) { auto sp1 = std::make_shared(42); auto sp2 = std::make_shared(100); NonNullSharedPtr nps1(sp1); NonNullSharedPtr nps2(sp2); nps2 = nps1; EXPECT_EQ(nps1.get(), nps2.get()); EXPECT_EQ(nps2->value, 42); EXPECT_EQ(nps1.use_count(), 3); } TEST(NonNullSharedPtrTest, MoveAssignment) { auto sp1 = std::make_shared(42); auto sp2 = std::make_shared(100); auto *raw_ptr = sp1.get(); NonNullSharedPtr nps1(sp1); NonNullSharedPtr nps2(sp2); nps2 = std::move(nps1); EXPECT_EQ(nps2.get(), raw_ptr); EXPECT_EQ(nps2->value, 42); EXPECT_EQ(nps2.use_count(), 2); } TEST(NonNullSharedPtrTest, DereferenceOperator) { auto sp = std::make_shared(42); NonNullSharedPtr nps(sp); TestObject &obj = *nps; EXPECT_EQ(obj.value, 42); (*nps).value = 100; EXPECT_EQ(nps->value, 100); } TEST(NonNullSharedPtrTest, ArrowOperator) { auto sp = std::make_shared(42); NonNullSharedPtr nps(sp); EXPECT_EQ(nps->value, 42); nps->value = 200; EXPECT_EQ(nps->value, 200); } TEST(NonNullSharedPtrTest, GetMethod) { auto sp = std::make_shared(42); auto *raw_ptr = sp.get(); NonNullSharedPtr nps(sp); EXPECT_EQ(nps.get(), raw_ptr); EXPECT_NE(nps.get(), nullptr); } TEST(NonNullSharedPtrTest, UseCount) { auto sp = std::make_shared(42); EXPECT_EQ(sp.use_count(), 1); NonNullSharedPtr nps1(sp); EXPECT_EQ(sp.use_count(), 2); EXPECT_EQ(nps1.use_count(), 2); { // Copy constructor. NonNullSharedPtr nps2(nps1); EXPECT_EQ(sp.use_count(), 3); EXPECT_EQ(nps1.use_count(), 3); EXPECT_EQ(nps2.use_count(), 3); } { // Copy assignment constructor. NonNullSharedPtr nps2 = nps1; EXPECT_EQ(sp.use_count(), 3); EXPECT_EQ(nps1.use_count(), 3); EXPECT_EQ(nps2.use_count(), 3); } EXPECT_EQ(sp.use_count(), 2); EXPECT_EQ(nps1.use_count(), 2); sp.reset(); EXPECT_EQ(nps1.use_count(), 1); EXPECT_TRUE(nps1); } TEST(NonNullSharedPtrTest, BoolOperator) { auto sp = std::make_shared(42); NonNullSharedPtr nps(sp); EXPECT_TRUE(static_cast(nps)); EXPECT_TRUE(nps); } TEST(NonNullSharedPtrTest, SwapMethod) { auto sp1 = std::make_shared(42); auto sp2 = std::make_shared(100); auto *raw_ptr1 = sp1.get(); auto *raw_ptr2 = sp2.get(); NonNullSharedPtr nps1(sp1); NonNullSharedPtr nps2(sp2); nps1.swap(nps2); EXPECT_EQ(nps1.get(), raw_ptr2); EXPECT_EQ(nps2.get(), raw_ptr1); EXPECT_EQ(nps1->value, 100); EXPECT_EQ(nps2->value, 42); } TEST(NonNullSharedPtrTest, ADLSwap) { auto sp1 = std::make_shared(42); auto sp2 = std::make_shared(100); auto *raw_ptr1 = sp1.get(); auto *raw_ptr2 = sp2.get(); NonNullSharedPtr nps1(sp1); NonNullSharedPtr nps2(sp2); // Use ADL swap. swap(nps1, nps2); EXPECT_EQ(nps1.get(), raw_ptr2); EXPECT_EQ(nps2.get(), raw_ptr1); EXPECT_EQ(nps1->value, 100); EXPECT_EQ(nps2->value, 42); } TEST(NonNullSharedPtrTest, MultipleReferences) { auto sp = std::make_shared(42); NonNullSharedPtr nps1(sp); NonNullSharedPtr nps2(nps1); NonNullSharedPtr nps3(nps2); EXPECT_EQ(nps1.get(), nps2.get()); EXPECT_EQ(nps2.get(), nps3.get()); nps1->value = 999; EXPECT_EQ(nps2->value, 999); EXPECT_EQ(nps3->value, 999); }