diff options
| author | babenko <[email protected]> | 2026-07-03 16:17:12 +0300 |
|---|---|---|
| committer | babenko <[email protected]> | 2026-07-03 16:51:23 +0300 |
| commit | 137013265ea10fd8a99ae76e9d075592bc05d953 (patch) | |
| tree | 3cb3cbda6396bb902387f1c21e55702c3ac52f5d /library/cpp | |
| parent | 884f6fd0f34672f34e071dfa8df8b02720d5715e (diff) | |
Add TAnyObject::Holds<T> and rename IsCurrentlyStored to HoldsType
commit_hash:5f0c248f2c24b501b04777fb0300693b0e942c89
Diffstat (limited to 'library/cpp')
| -rw-r--r-- | library/cpp/yt/memory/type_erasure.h | 18 | ||||
| -rw-r--r-- | library/cpp/yt/memory/type_erasure_detail.h | 6 | ||||
| -rw-r--r-- | library/cpp/yt/memory/unittests/type_erasure_ut.cpp | 24 |
3 files changed, 41 insertions, 7 deletions
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<T>()) { + if (!vtable.IsValid() || !vtable.template HoldsType<T>()) { throw TBadAnyCast{}; } @@ -106,7 +106,7 @@ public: const T& AnyCast() const & { const auto& vtable = Holder_.GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored<T>()) { + if (!vtable.IsValid() || !vtable.template HoldsType<T>()) { throw TBadAnyCast{}; } @@ -306,7 +306,7 @@ public: using TWrapped = TOwningWrapper<TDecayed, TStorage, EnableCopy, TCpos...>; const auto& vtable = GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored<TWrapped>()) { + if (!vtable.IsValid() || !vtable.template HoldsType<TWrapped>()) { throw TBadAnyCast{}; } @@ -320,13 +320,23 @@ public: using TWrapped = TOwningWrapper<TDecayed, TStorage, EnableCopy, TCpos...>; const auto& vtable = GetVTable(); - if (!vtable.IsValid() || !vtable.template IsCurrentlyStored<TWrapped>()) { + if (!vtable.IsValid() || !vtable.template HoldsType<TWrapped>()) { throw TBadAnyCast{}; } return Storage_.template As<TWrapped>().Unwrap(); } + template <class T> + Y_FORCE_INLINE bool Holds() const + { + using TDecayed = std::remove_cvref_t<T>; + using TWrapped = TOwningWrapper<TDecayed, TStorage, EnableCopy, TCpos...>; + + const auto& vtable = GetVTable(); + return vtable.IsValid() && vtable.template HoldsType<TWrapped>(); + } + 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 <class T> - Y_FORCE_INLINE bool IsCurrentlyStored() const noexcept + Y_FORCE_INLINE bool HoldsType() const noexcept { return Function_ == &TVTableEntry::StaticInvoke<T>; } @@ -358,9 +358,9 @@ public: } template <class T> - Y_FORCE_INLINE bool IsCurrentlyStored() const noexcept + Y_FORCE_INLINE bool HoldsType() const noexcept { - return TVTableEntry<TStorage, TCpo>::template IsCurrentlyStored<T>(); + return TVTableEntry<TStorage, TCpo>::template HoldsType<T>(); } 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<TestCpo>, 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<TOverload<TestCpo, int(const TErasedThis&)>>; + + TAnyObject any{TCustomized{.Value = 42}}; + EXPECT_TRUE(any.Holds<TCustomized>()); + EXPECT_FALSE(any.Holds<TOtherCustomized>()); + + TAnyObject other{TOtherCustomized{}}; + EXPECT_TRUE(other.Holds<TOtherCustomized>()); + EXPECT_FALSE(other.Holds<TCustomized>()); + + TAnyObject empty; + EXPECT_FALSE(empty.Holds<TCustomized>()); +} + TEST(TAnyObjectTest, CvRefCorrectness) { using TAnyObject = TAnyObject< |
