#include #include #include #include #include #include namespace NYT { namespace { //////////////////////////////////////////////////////////////////////////////// struct TBase : public TRefCounted { }; struct TDerived : public TBase { int Tag = 42; }; struct TMoreDerived : public TDerived { }; //////////////////////////////////////////////////////////////////////////////// // Pointer form. TEST(TExactRefCountedCastTest, ExactMatch) { auto object = New(); TBase* base = object.Get(); EXPECT_EQ(ExactRefCountedCast(base), object.Get()); EXPECT_EQ(ExactRefCountedCast(base)->Tag, 42); } TEST(TExactRefCountedCastTest, SubclassDoesNotMatch) { auto object = New(); TBase* base = object.Get(); // Object was New(); an exact probe for TDerived must miss. EXPECT_EQ(ExactRefCountedCast(base), nullptr); // ...but the exact type matches. EXPECT_EQ(ExactRefCountedCast(base), object.Get()); } TEST(TExactRefCountedCastTest, BaseDoesNotMatch) { auto object = New(); TBase* base = object.Get(); // It is exactly a TDerived, not a TBase. EXPECT_EQ(ExactRefCountedCast(base), nullptr); } TEST(TExactRefCountedCastTest, Null) { TBase* base = nullptr; EXPECT_EQ(ExactRefCountedCast(base), nullptr); } TEST(TExactRefCountedCastTest, ConstnessPreserved) { auto object = New(); const TBase* base = object.Get(); auto* result = ExactRefCountedCast(base); static_assert(std::is_same_v); EXPECT_EQ(result, object.Get()); } //////////////////////////////////////////////////////////////////////////////// // Reference form. TEST(TExactRefCountedCastTest, RefExactMatch) { auto object = New(); TBase& base = *object; EXPECT_EQ(&ExactRefCountedCast(base), object.Get()); } TEST(TExactRefCountedCastTest, RefSubclassThrows) { auto object = New(); TBase& base = *object; EXPECT_THROW((void)ExactRefCountedCast(base), std::bad_cast); EXPECT_EQ(&ExactRefCountedCast(base), object.Get()); } TEST(TExactRefCountedCastTest, RefConstnessPreserved) { auto object = New(); const TBase& base = *object; static_assert(std::is_same_v(base)), const TDerived&>); EXPECT_EQ(&ExactRefCountedCast(base), object.Get()); } //////////////////////////////////////////////////////////////////////////////// } // namespace } // namespace NYT