summaryrefslogtreecommitdiffstats
path: root/library/cpp
diff options
context:
space:
mode:
authorbabenko <[email protected]>2026-07-03 16:17:12 +0300
committerbabenko <[email protected]>2026-07-03 16:51:23 +0300
commit137013265ea10fd8a99ae76e9d075592bc05d953 (patch)
tree3cb3cbda6396bb902387f1c21e55702c3ac52f5d /library/cpp
parent884f6fd0f34672f34e071dfa8df8b02720d5715e (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.h18
-rw-r--r--library/cpp/yt/memory/type_erasure_detail.h6
-rw-r--r--library/cpp/yt/memory/unittests/type_erasure_ut.cpp24
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<