From 137013265ea10fd8a99ae76e9d075592bc05d953 Mon Sep 17 00:00:00 2001 From: babenko Date: Fri, 3 Jul 2026 16:17:12 +0300 Subject: Add TAnyObject::Holds and rename IsCurrentlyStored to HoldsType commit_hash:5f0c248f2c24b501b04777fb0300693b0e942c89 --- library/cpp/yt/memory/type_erasure.h | 18 ++++++++++++---- library/cpp/yt/memory/type_erasure_detail.h | 6 +++--- .../cpp/yt/memory/unittests/type_erasure_ut.cpp | 24 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) (limited to 'library/cpp') diff --git a/library/cpp/yt/memory/type_erasure.h b/library/cpp/yt/memory/type_erasure.h index 8d87a347b45..3b2dbe34015 100644 --- a/library/cpp/yt/memory/type_erasure.h +++ b/library/cpp/yt/memory/type_erasure.h @@ -94,7 +94,7 @@ public: T& AnyCast() & { const auto& vtable = GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored()) { + if (!vtable.IsValid() || !vtable.template HoldsType()) { throw TBadAnyCast{}; } @@ -106,7 +106,7 @@ public: const T& AnyCast() const & { const auto& vtable = Holder_.GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored()) { + if (!vtable.IsValid() || !vtable.template HoldsType()) { throw TBadAnyCast{}; } @@ -306,7 +306,7 @@ public: using TWrapped = TOwningWrapper; const auto& vtable = GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored()) { + if (!vtable.IsValid() || !vtable.template HoldsType()) { throw TBadAnyCast{}; } @@ -320,13 +320,23 @@ public: using TWrapped = TOwningWrapper; const auto& vtable = GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored()) { + if (!vtable.IsValid() || !vtable.template HoldsType()) { throw TBadAnyCast{}; } return Storage_.template As().Unwrap(); } + template + Y_FORCE_INLINE bool Holds() const + { + using TDecayed = std::remove_cvref_t; + using TWrapped = TOwningWrapper; + + const auto& vtable = GetVTable(); + return vtable.IsValid() && vtable.template HoldsType(); + } + Y_FORCE_INLINE bool IsValid() const { return Holder_.IsValid(); diff --git a/library/cpp/yt/memory/type_erasure_detail.h b/library/cpp/yt/memory/type_erasure_detail.h index 92904573d01..76b611a2d67 100644 --- a/library/cpp/yt/memory/type_erasure_detail.h +++ b/library/cpp/yt/memory/type_erasure_detail.h @@ -304,7 +304,7 @@ public: // NB(arkady-e1ppa): This method may or may not work correctly // for dynamically-linked libraries. template - Y_FORCE_INLINE bool IsCurrentlyStored() const noexcept + Y_FORCE_INLINE bool HoldsType() const noexcept { return Function_ == &TVTableEntry::StaticInvoke; } @@ -358,9 +358,9 @@ public: } template - Y_FORCE_INLINE bool IsCurrentlyStored() const noexcept + Y_FORCE_INLINE bool HoldsType() const noexcept { - return TVTableEntry::template IsCurrentlyStored(); + return TVTableEntry::template HoldsType(); } private: diff --git a/library/cpp/yt/memory/unittests/type_erasure_ut.cpp b/library/cpp/yt/memory/unittests/type_erasure_ut.cpp index b33ab368023..c923ec29a11 100644 --- a/library/cpp/yt/memory/unittests/type_erasure_ut.cpp +++ b/library/cpp/yt/memory/unittests/type_erasure_ut.cpp @@ -23,6 +23,14 @@ struct TCustomized } }; +struct TOtherCustomized +{ + friend int TagInvoke(TTagInvokeTag, const TOtherCustomized&) + { + return 0; + } +}; + //////////////////////////////////////////////////////////////////////////////// // 2 CPOs won't trigger static vtable. @@ -253,6 +261,22 @@ TEST(TAnyObjectTest, EmptyAny) EXPECT_EQ(conc.Value, 11); } +TEST(TAnyObjectTest, Holds) +{ + using TAnyObject = TAnyObject>; + + TAnyObject any{TCustomized{.Value = 42}}; + EXPECT_TRUE(any.Holds()); + EXPECT_FALSE(any.Holds()); + + TAnyObject other{TOtherCustomized{}}; + EXPECT_TRUE(other.Holds()); + EXPECT_FALSE(other.Holds()); + + TAnyObject empty; + EXPECT_FALSE(empty.Holds()); +} + TEST(TAnyObjectTest, CvRefCorrectness) { using TAnyObject = TAnyObject< -- cgit v1.3