diff options
author | babenko <babenko@yandex-team.com> | 2024-08-22 15:35:59 +0300 |
---|---|---|
committer | babenko <babenko@yandex-team.com> | 2024-08-22 15:46:30 +0300 |
commit | f9fbb65f64b68c5de5cf257c04e06ac6aeaeb1e8 (patch) | |
tree | a4dab5ac21a6f2f190889537b9693c226a0eec8f /yt | |
parent | 1475372a2d8a1ace4610a95415eb1cfe97fc26d1 (diff) | |
download | ydb-f9fbb65f64b68c5de5cf257c04e06ac6aeaeb1e8.tar.gz |
YT-21993: Fix duplicate type tag on derive from template
7ec29a7b370f343f910075ff9fd87ea9469d2aa0
Diffstat (limited to 'yt')
-rw-r--r-- | yt/yt/core/phoenix/descriptors.cpp | 16 | ||||
-rw-r--r-- | yt/yt/core/phoenix/descriptors.h | 2 | ||||
-rw-r--r-- | yt/yt/core/phoenix/type_decl-inl.h | 6 | ||||
-rw-r--r-- | yt/yt/core/phoenix/type_def-inl.h | 49 | ||||
-rw-r--r-- | yt/yt/core/phoenix/type_registry.cpp | 17 | ||||
-rw-r--r-- | yt/yt/core/phoenix/unittests/phoenix_ut.cpp | 33 |
6 files changed, 102 insertions, 21 deletions
diff --git a/yt/yt/core/phoenix/descriptors.cpp b/yt/yt/core/phoenix/descriptors.cpp index 90ee72f7fc..eb1f22a472 100644 --- a/yt/yt/core/phoenix/descriptors.cpp +++ b/yt/yt/core/phoenix/descriptors.cpp @@ -136,15 +136,29 @@ const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTagOrThrow(TTypeT return *descriptor; } +const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTag(TTypeTag tag) const +{ + const auto* descriptor = FindTypeDescriptorByTag(tag); + YT_VERIFY(descriptor); + return *descriptor; +} + const TTypeDescriptor* TUniverseDescriptor::FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const { auto it = TypeIndexToDescriptor_.find(typeIndex); return it == TypeIndexToDescriptor_.end() ? nullptr : it->second; } +const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const +{ + const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex); + YT_VERIFY(descriptor); + return *descriptor; +} + const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const { - const auto& descriptor = FindTypeDescriptorByTypeIndex(typeIndex); + const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex); if (!descriptor) { THROW_ERROR_EXCEPTION("Type %v is not registered", CppDemangle(typeIndex.name())); diff --git a/yt/yt/core/phoenix/descriptors.h b/yt/yt/core/phoenix/descriptors.h index 1ec630a75d..854ae0caf1 100644 --- a/yt/yt/core/phoenix/descriptors.h +++ b/yt/yt/core/phoenix/descriptors.h @@ -91,9 +91,11 @@ public: const NYson::TYsonString& GetSchemaYson() const; const TTypeDescriptor* FindTypeDescriptorByTag(TTypeTag tag) const ; + const TTypeDescriptor& GetTypeDescriptorByTag(TTypeTag tag) const; const TTypeDescriptor& GetTypeDescriptorByTagOrThrow(TTypeTag tag) const; const TTypeDescriptor* FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const ; + const TTypeDescriptor& GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const; const TTypeDescriptor& GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const; private: diff --git a/yt/yt/core/phoenix/type_decl-inl.h b/yt/yt/core/phoenix/type_decl-inl.h index fb6c2f5c19..2e5d62fd3c 100644 --- a/yt/yt/core/phoenix/type_decl-inl.h +++ b/yt/yt/core/phoenix/type_decl-inl.h @@ -83,7 +83,7 @@ private: \ public: \ static const ::NYT::NPhoenix2::TTypeDescriptor& GetTypeDescriptor() \ { \ - static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ true>(); \ + static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \ return descriptor; \ } \ \ @@ -136,4 +136,8 @@ public: \ //////////////////////////////////////////////////////////////////////////////// +const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag); + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT::NPhoenix2::NDetail diff --git a/yt/yt/core/phoenix/type_def-inl.h b/yt/yt/core/phoenix/type_def-inl.h index 9b40b0f703..166909e178 100644 --- a/yt/yt/core/phoenix/type_def-inl.h +++ b/yt/yt/core/phoenix/type_def-inl.h @@ -18,6 +18,8 @@ #include <concepts> +namespace NYT::NPhoenix2::NDetail { + //////////////////////////////////////////////////////////////////////////////// #undef PHOENIX_DEFINE_TYPE @@ -26,22 +28,10 @@ //////////////////////////////////////////////////////////////////////////////// -#define PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs) \ - template <class T> \ - struct TPhoenixTypeInitializer__; \ - \ - template <> \ - struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \ - { \ - [[maybe_unused]] static inline const void* Dummy = &type PP_DEPAREN(parenthesizedTypeArgs)::GetTypeDescriptor(); \ - } - #define PHOENIX_DEFINE_TYPE(type) \ - PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \ - \ const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \ { \ - static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ false>(); \ + static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \ return descriptor; \ } \ \ @@ -79,23 +69,46 @@ YT_VERIFY(context.IsLoad()); \ type::LoadImpl(context.LoadContext()); \ } \ + } \ + \ + template <class T> \ + struct TPhoenixTypeInitializer__; \ + \ + template <> \ + struct TPhoenixTypeInitializer__<type> \ + { \ + [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, false>(); \ } #define PHOENIX_DEFINE_TEMPLATE_TYPE(type, parenthesizedTypeArgs) \ - PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs) + template <class T> \ + struct TPhoenixTypeInitializer__; \ + \ + template <> \ + struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \ + { \ + [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type PP_DEPAREN(parenthesizedTypeArgs), true>(); \ + } #define PHOENIX_DEFINE_OPAQUE_TYPE(type) \ - PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \ - \ const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \ { \ - static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \ + static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \ return descriptor; \ + } \ + \ + template <class T> \ + struct TPhoenixTypeInitializer__; \ + \ + template <> \ + struct TPhoenixTypeInitializer__<type> \ + { \ + [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \ } //////////////////////////////////////////////////////////////////////////////// -namespace NYT::NPhoenix2::NDetail { +const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag); //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/phoenix/type_registry.cpp b/yt/yt/core/phoenix/type_registry.cpp index 11c1ca2f26..e4a9d46780 100644 --- a/yt/yt/core/phoenix/type_registry.cpp +++ b/yt/yt/core/phoenix/type_registry.cpp @@ -80,6 +80,11 @@ public: if (!Sealed_.exchange(true)) { YT_LOG_INFO("Type registry is sealed"); } + return GetUniverseDescriptorUnchecked(); + } + + const TUniverseDescriptor& GetUniverseDescriptorUnchecked() + { return UniverseDescriptor_; } @@ -88,13 +93,23 @@ private: std::atomic<bool> Sealed_; }; +TTypeRegistry* GetTypeRegistry() +{ + return LeakySingleton<NDetail::TTypeRegistry>(); +} + +const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag) +{ + return GetTypeRegistry()->GetUniverseDescriptorUnchecked().GetTypeDescriptorByTag(tag); +} + } // namespace NDetail //////////////////////////////////////////////////////////////////////////////// ITypeRegistry* ITypeRegistry::Get() { - return LeakySingleton<NDetail::TTypeRegistry>(); + return NDetail::GetTypeRegistry(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp index b93bf8868b..e55261ba18 100644 --- a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp +++ b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp @@ -1578,5 +1578,38 @@ TEST(TPhoenixTest, PrivateInner) //////////////////////////////////////////////////////////////////////////////// +namespace NSeveralSpecializationsOfOneTemplate { + +struct TDerivedFromTemplate + : public TPair<double, double> +{ + bool operator==(const TDerivedFromTemplate&) const = default; + + PHOENIX_DECLARE_TYPE(TDerivedFromTemplate, 0xf09c298f); +}; + +void TDerivedFromTemplate::RegisterMetadata(auto&& registrar) +{ + registrar.template BaseType<TPair<double, double>>(); +} + +PHOENIX_DEFINE_TYPE(TDerivedFromTemplate); + +} // namespace NSeveralSpecializationsOfOneTemplate + +TEST(TPhoenixTest, SeveralSpecializationsOfOneTemplate) +{ + using namespace NSeveralSpecializationsOfOneTemplate; + + TDerivedFromTemplate tp1; + tp1.First = 1.1; + tp1.Second = 2.2; + + auto tp2 = Deserialize<TDerivedFromTemplate>(Serialize(tp1)); + EXPECT_EQ(tp1, tp2); +} + +//////////////////////////////////////////////////////////////////////////////// + } // namespace } // namespace NYT::NPhoenix2 |