aboutsummaryrefslogtreecommitdiffstats
path: root/yt
diff options
context:
space:
mode:
authorrobot-ydb-importer <robot-ydb-importer@yandex-team.com>2024-01-24 10:59:00 +0300
committerrobot-ydb-importer <robot-ydb-importer@yandex-team.com>2024-01-24 11:17:10 +0300
commit12ee01cc75a602474e67b43170f0f6570204e251 (patch)
tree87945b3ce0ea5b243d25b10f7fc63d605cf9fac7 /yt
parent4b956569448d92db799238c8c8284c380d5719a4 (diff)
downloadydb-12ee01cc75a602474e67b43170f0f6570204e251.tar.gz
YDB Import 550
Diffstat (limited to 'yt')
-rw-r--r--yt/yt/core/concurrency/config.h4
-rw-r--r--yt/yt/core/misc/backoff_strategy_config.h4
-rw-r--r--yt/yt/core/ytree/serialization_traits.h2
-rw-r--r--yt/yt/core/ytree/serialize-inl.h4
-rw-r--r--yt/yt/core/ytree/unittests/yson_struct_ut.cpp196
-rw-r--r--yt/yt/core/ytree/yson_struct-inl.h95
-rw-r--r--yt/yt/core/ytree/yson_struct.h14
7 files changed, 278 insertions, 41 deletions
diff --git a/yt/yt/core/concurrency/config.h b/yt/yt/core/concurrency/config.h
index fb963fbe83..24d5383e60 100644
--- a/yt/yt/core/concurrency/config.h
+++ b/yt/yt/core/concurrency/config.h
@@ -40,7 +40,7 @@ namespace NDetail {
////////////////////////////////////////////////////////////////////////////////
class TPeriodicExecutorOptionsSerializer
- : public NYTree::TExternalizedYsonStruct<TPeriodicExecutorOptions>
+ : public NYTree::TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TPeriodicExecutorOptions, TPeriodicExecutorOptionsSerializer);
@@ -51,7 +51,7 @@ public:
////////////////////////////////////////////////////////////////////////////////
class TRetryingPeriodicExecutorOptionsSerializer
- : public NYTree::TExternalizedYsonStruct<TRetryingPeriodicExecutorOptions>
+ : public NYTree::TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TRetryingPeriodicExecutorOptions, TRetryingPeriodicExecutorOptionsSerializer);
diff --git a/yt/yt/core/misc/backoff_strategy_config.h b/yt/yt/core/misc/backoff_strategy_config.h
index c9788c8135..47038589ff 100644
--- a/yt/yt/core/misc/backoff_strategy_config.h
+++ b/yt/yt/core/misc/backoff_strategy_config.h
@@ -9,7 +9,7 @@ namespace NYT {
////////////////////////////////////////////////////////////////////////////////
class TExponentialBackoffOptionsSerializer
- : public NYTree::TExternalizedYsonStruct<TExponentialBackoffOptions>
+ : public NYTree::TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TExponentialBackoffOptions, TExponentialBackoffOptionsSerializer);
@@ -22,7 +22,7 @@ ASSIGN_EXTERNAL_YSON_SERIALIZER(TExponentialBackoffOptions, TExponentialBackoffO
////////////////////////////////////////////////////////////////////////////////
class TConstantBackoffOptionsSerializer
- : public NYTree::TExternalizedYsonStruct<TConstantBackoffOptions>
+ : public NYTree::TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TConstantBackoffOptions, TConstantBackoffOptionsSerializer);
diff --git a/yt/yt/core/ytree/serialization_traits.h b/yt/yt/core/ytree/serialization_traits.h
index c2fa2076e2..f73a3ba475 100644
--- a/yt/yt/core/ytree/serialization_traits.h
+++ b/yt/yt/core/ytree/serialization_traits.h
@@ -25,7 +25,7 @@ concept CSerializableByTraits = TSerializationTraits<T>::IsSerializable;
template <> \
struct ::NYT::NYTree::TSerializationTraits<Type> \
{ \
- static constexpr bool IsSerializable = true; \
+ [[maybe_unused]] static constexpr bool IsSerializable = true; \
using TSerializer = SerializerType; \
}; \
diff --git a/yt/yt/core/ytree/serialize-inl.h b/yt/yt/core/ytree/serialize-inl.h
index d5ae31ebba..74a1ad9c4d 100644
--- a/yt/yt/core/ytree/serialize-inl.h
+++ b/yt/yt/core/ytree/serialize-inl.h
@@ -467,7 +467,7 @@ template <class T>
void Serialize(const T& value, NYson::IYsonConsumer* consumer)
{
using TSerializer = typename TSerializationTraits<T>::TSerializer;
- auto serializer = TSerializer::template CreateReadOnly<TSerializer>(value);
+ auto serializer = TSerializer::template CreateReadOnly<T, TSerializer>(value);
Serialize(serializer, consumer);
}
@@ -666,7 +666,7 @@ template <class T>
void Deserialize(T& value, INodePtr node)
{
using TSerializer = typename TSerializationTraits<T>::TSerializer;
- auto serializer = TSerializer::template CreateWritable<TSerializer>(value);
+ auto serializer = TSerializer::template CreateWritable<T, TSerializer>(value);
Deserialize(serializer, node);
}
diff --git a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
index 568a6e8d06..027b367991 100644
--- a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
+++ b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
@@ -30,7 +30,7 @@ struct TTestTraitConfig
};
class TTestTraitConfigSerializer
- : public TExternalizedYsonStruct<TTestTraitConfig>
+ : public virtual TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TTestTraitConfig, TTestTraitConfigSerializer);
@@ -54,7 +54,7 @@ struct TTestProcessorsTraitConfig
};
class TTestProcessorsTraitConfigSerializer
- : public TExternalizedYsonStruct<TTestProcessorsTraitConfig>
+ : public TExternalizedYsonStruct
{
public:
REGISTER_EXTERNALIZED_YSON_STRUCT(TTestProcessorsTraitConfig, TTestProcessorsTraitConfigSerializer);
@@ -88,12 +88,97 @@ public:
}
};
+////////////////////////////////////////////////////////////////////////////////
+
+struct TTestDerivedPodConfig
+ : public TTestTraitConfig
+{
+ int Field3;
+};
+
+class TTestDerivedPodConfigSerializer
+ : public TTestTraitConfigSerializer
+{
+public:
+ REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(TTestDerivedPodConfig, TTestDerivedPodConfigSerializer, (TTestTraitConfigSerializer));
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.ExternalClassParameter("field_3", &TThat::Field3);
+ }
+};
+
+struct TTestDoubleDerivedPodConfig
+ : public TTestDerivedPodConfig
+{
+ int Field4;
+};
+
+class TTestDoubleDerivedPodConfigSerializer
+ : public TTestDerivedPodConfigSerializer
+{
+public:
+ REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(TTestDoubleDerivedPodConfig, TTestDoubleDerivedPodConfigSerializer, (TTestDerivedPodConfigSerializer));
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.ExternalClassParameter("field_4", &TThat::Field4);
+ }
+};
+
+struct TTestDerivedSecondBase
+{
+ int Field5;
+ int Field6;
+};
+
+class TTestDerivedSecondBaseSerializer
+ : public virtual TExternalizedYsonStruct
+{
+public:
+ REGISTER_EXTERNALIZED_YSON_STRUCT(TTestDerivedSecondBase, TTestDerivedSecondBaseSerializer);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.ExternalClassParameter("field_5", &TThat::Field5);
+ registrar.ExternalClassParameter("field_6", &TThat::Field6);
+ }
+};
+
+struct TTestDerivedTwoBasesConfig
+ : public TTestDoubleDerivedPodConfig
+ , public TTestDerivedSecondBase
+{ };
+
+class TTestDerivedTwoBasesConfigSerializer
+ : public TTestDoubleDerivedPodConfigSerializer
+ , public TTestDerivedSecondBaseSerializer
+{
+public:
+ REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(
+ TTestDerivedTwoBasesConfig,
+ TTestDerivedTwoBasesConfigSerializer,
+ (TTestDoubleDerivedPodConfigSerializer)
+ (TTestDerivedSecondBaseSerializer));
+
+ static void Register(TRegistrar)
+ { }
+};
+
} // namespace
ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestTraitConfig, TTestTraitConfigSerializer);
ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestProcessorsTraitConfig, TTestProcessorsTraitConfigSerializer);
+ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestDerivedPodConfig, TTestDerivedPodConfigSerializer);
+
+ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestDoubleDerivedPodConfig, TTestDoubleDerivedPodConfigSerializer);
+
+ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestDerivedSecondBase, TTestDerivedSecondBaseSerializer);
+
+ASSIGN_EXTERNAL_YSON_SERIALIZER(TTestDerivedTwoBasesConfig, TTestDerivedTwoBasesConfigSerializer);
+
////////////////////////////////////////////////////////////////////////////////
namespace {
@@ -1830,6 +1915,113 @@ TEST(TYsonStructTest, SerializableByTraitsPostPreprocessors)
EXPECT_EQ(reader.Field.Field2, 33);
}
+class TDerivedFieldTester
+ : public NYT::NYTree::TYsonStructLite
+{
+public:
+ TTestDerivedPodConfig Field;
+
+ REGISTER_YSON_STRUCT_LITE(TDerivedFieldTester);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.Parameter("field", &TThis::Field);
+ }
+};
+
+TEST(TYsonStructTest, SerializableByTraitsDerivedFromExternalized)
+{
+ TDerivedFieldTester writer = {};
+ writer.Field = {{55, 34}, 37};
+
+ TBufferStream stream;
+
+ ::Save(&stream, writer);
+
+ TDerivedFieldTester reader = {};
+ ::Load(&stream, reader);
+ EXPECT_EQ(writer.Field.Field1, 55);
+ EXPECT_EQ(writer.Field.Field2, 34);
+ EXPECT_EQ(writer.Field.Field3, 37);
+ EXPECT_EQ(reader.Field.Field1, 55);
+ EXPECT_EQ(reader.Field.Field2, 34);
+ EXPECT_EQ(reader.Field.Field3, 37);
+}
+
+class TDoubleDerivedFieldTester
+ : public NYT::NYTree::TYsonStructLite
+{
+public:
+ TTestDoubleDerivedPodConfig Field;
+
+ REGISTER_YSON_STRUCT_LITE(TDoubleDerivedFieldTester);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.Parameter("field", &TThis::Field);
+ }
+};
+
+TEST(TYsonStructTest, SerializableByTraitsDoubleDerivedFromExternalized)
+{
+ TDoubleDerivedFieldTester writer = {};
+ writer.Field = {{{55, 34}, 37}, 77};
+
+ TBufferStream stream;
+
+ ::Save(&stream, writer);
+
+ TDoubleDerivedFieldTester reader = {};
+ ::Load(&stream, reader);
+ EXPECT_EQ(writer.Field.Field1, 55);
+ EXPECT_EQ(writer.Field.Field2, 34);
+ EXPECT_EQ(writer.Field.Field3, 37);
+ EXPECT_EQ(writer.Field.Field4, 77);
+ EXPECT_EQ(reader.Field.Field1, 55);
+ EXPECT_EQ(reader.Field.Field2, 34);
+ EXPECT_EQ(reader.Field.Field3, 37);
+ EXPECT_EQ(reader.Field.Field4, 77);
+}
+
+class TTwoBasesFieldTester
+ : public NYT::NYTree::TYsonStructLite
+{
+public:
+ TTestDerivedTwoBasesConfig Field;
+
+ REGISTER_YSON_STRUCT_LITE(TTwoBasesFieldTester);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.Parameter("field", &TThis::Field);
+ }
+};
+
+TEST(TYsonStructTest, SerializableByTraitsDerivedFromTwoExternalizedBases)
+{
+ TTwoBasesFieldTester writer = {};
+ writer.Field = {{{{55, 34}, 37}, 77}, {7, 8}};
+
+ TBufferStream stream;
+
+ ::Save(&stream, writer);
+
+ TTwoBasesFieldTester reader = {};
+ ::Load(&stream, reader);
+ EXPECT_EQ(writer.Field.Field1, 55);
+ EXPECT_EQ(writer.Field.Field2, 34);
+ EXPECT_EQ(writer.Field.Field3, 37);
+ EXPECT_EQ(writer.Field.Field4, 77);
+ EXPECT_EQ(writer.Field.Field5, 7);
+ EXPECT_EQ(writer.Field.Field6, 8);
+ EXPECT_EQ(reader.Field.Field1, 55);
+ EXPECT_EQ(reader.Field.Field2, 34);
+ EXPECT_EQ(reader.Field.Field3, 37);
+ EXPECT_EQ(reader.Field.Field4, 77);
+ EXPECT_EQ(reader.Field.Field5, 7);
+ EXPECT_EQ(reader.Field.Field6, 8);
+}
+
////////////////////////////////////////////////////////////////////////////////
} // namespace
diff --git a/yt/yt/core/ytree/yson_struct-inl.h b/yt/yt/core/ytree/yson_struct-inl.h
index 1b864cd8c2..60ea056feb 100644
--- a/yt/yt/core/ytree/yson_struct-inl.h
+++ b/yt/yt/core/ytree/yson_struct-inl.h
@@ -53,30 +53,28 @@ const std::type_info& CallCtor()
//! Creates TSerializer object which has preprocessors applied
//! to a TStruct object referred to by writable.
-template <std::default_initializable TStruct>
-template <class TSerializer>
-TSerializer TExternalizedYsonStruct<TStruct>::CreateWritable(TStruct& writable)
+template <std::default_initializable TStruct, class TSerializer>
+TSerializer TExternalizedYsonStruct::CreateWritable(TStruct& writable)
{
- static_assert(std::derived_from<TSerializer, TExternalizedYsonStruct<TStruct>>);
+ static_assert(std::derived_from<TSerializer, TExternalizedYsonStruct>);
return TSerializer(&writable);
}
//! Creates TSerializer object which has preprocessors applied
//! to a dummy object and has pointer to readOnly assigned afterwards.
-template <std::default_initializable TStruct>
-template <class TSerializer>
-TSerializer TExternalizedYsonStruct<TStruct>::CreateReadOnly(const TStruct& readOnly)
+template <std::default_initializable TStruct, class TSerializer>
+TSerializer TExternalizedYsonStruct::CreateReadOnly(const TStruct& readOnly)
{
- static_assert(std::derived_from<TSerializer, TExternalizedYsonStruct<TStruct>>);
+ static_assert(std::derived_from<TSerializer, TExternalizedYsonStruct>);
auto ret = TSerializer();
- ret.That = const_cast<TStruct*>(&readOnly);
+ ret.SetThat(const_cast<TStruct*>(&readOnly));
return ret;
}
//! We need some writable instance of TStruct to refer to in order
//! to have a default constructor required by TYsonStructRegistry::InitializeStruct.
template <std::default_initializable TStruct>
-TStruct* TExternalizedYsonStruct<TStruct>::GetDefault() noexcept
+TStruct* TExternalizedYsonStruct::GetDefault() noexcept
{
thread_local TStruct defaultThat = {};
//! NB: We reset default after every invocation
@@ -211,9 +209,10 @@ template <class TExternal, class TValue>
// requires std::derived_from<TStruct, TExternalizedYsonStruct<TExternal, TStruct>>
TYsonStructParameter<TValue>& TYsonStructRegistrar<TStruct>::ExternalClassParameter(const TString& key, TValue(TExternal::*field))
{
- static_assert(std::derived_from<TStruct, TExternalizedYsonStruct<TExternal>>);
+ static_assert(std::derived_from<TStruct, TExternalizedYsonStruct>);
+ static_assert(std::same_as<typename TStruct::TExternal, TExternal>);
auto universalAccessor = [field] (TStruct* serializer) -> auto& {
- return serializer->That->*field;
+ return serializer->That_->*field;
};
return ParameterWithUniversalAccessor<TValue>(key, universalAccessor);
@@ -226,7 +225,7 @@ void TYsonStructRegistrar<TStruct>::ExternalPreprocessor(TExternalPreprocessor p
{
static_assert(CInvocable<TExternalPreprocessor, void(typename TStruct::TExternal*)>);
Meta_->RegisterPreprocessor([preprocessor = std::move(preprocessor)] (TYsonStructBase* target) {
- preprocessor(TYsonStructRegistry::Get()->template CachedDynamicCast<TStruct>(target)->That);
+ preprocessor(TYsonStructRegistry::Get()->template CachedDynamicCast<TStruct>(target)->That_);
});
}
@@ -237,7 +236,7 @@ void TYsonStructRegistrar<TStruct>::ExternalPostprocessor(TExternalPostprocessor
{
static_assert(CInvocable<TExternalPostprocessor, void(typename TStruct::TExternal*)>);
Meta_->RegisterPostprocessor([postprocessor = std::move(postprocessor)] (TYsonStructBase* target) {
- postprocessor(TYsonStructRegistry::Get()->template CachedDynamicCast<TStruct>(target)->That);
+ postprocessor(TYsonStructRegistry::Get()->template CachedDynamicCast<TStruct>(target)->That_);
});
}
@@ -381,6 +380,7 @@ void UpdateYsonStructField(TIntrusivePtr<TDst>& dst, const TIntrusivePtr<TSrc>&
#undef DEFINE_YSON_STRUCT
#undef DEFINE_YSON_STRUCT_LITE
#undef REGISTER_EXTERNALIZED_YSON_STRUCT
+#undef REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT
#define YSON_STRUCT_IMPL__DECLARE_ALIASES(TStruct) \
private: \
@@ -397,12 +397,16 @@ private: \
this->SetDefaults(); \
} \
+//! NB(arkady-e1ppa): Alias is used by registrar postprocessors
+//! in order to properly infer template argument.
#define YSON_STRUCT_EXTERNAL_SERIALIZER_IMPL__DECLARE_ALIASES(TStruct, TSerializer) \
+public: \
+ using TExternal = TStruct; \
+ TStruct* That_ = nullptr; \
private: \
using TRegistrar = ::NYT::NYTree::TYsonStructRegistrar<TSerializer>; \
using TThat = TStruct; \
friend class ::NYT::NYTree::TYsonStructRegistry; \
- template <std::default_initializable T> \
friend class ::NYT::NYTree::TExternalizedYsonStruct; \
template <class T> \
friend const std::type_info& ::NYT::NYTree::CallCtor(); \
@@ -453,25 +457,70 @@ TStruct::TStruct() \
YSON_STRUCT_IMPL__CTOR_BODY(TStruct) \
}
-
//! NB(arkady-e1ppa): These constructors are only used internally.
//! Default one is required by TYsonStructRegistry::InitializeStruct.
//! If you want to create an instance of a TStruct then:
//! 1) Unless you are working with some serialization logic you shouldn't.
//! 2) Use TExternalizedYsonStruct::CreateWritable and TExternalizedYsonStruct::CreateReadOnly
//! instead to guarantee proper initialization as well as const-correctness.
-#define REGISTER_EXTERNALIZED_YSON_STRUCT(TStruct, TSerializer) \
-private: \
+#define EXTERNALIZED_YSON_STRUCT_IMPL__CTORS(TStruct, TSerializer) \
+public: \
+ TSerializer() \
+ : TSerializer(::NYT::NYTree::TExternalizedYsonStruct::template GetDefault<TStruct>()) \
+ { }; \
explicit TSerializer(TStruct* ptr) \
: ::NYT::NYTree::TYsonStructFinalClassHolder(std::type_index(typeid(TSerializer))) \
{ \
- static_assert(std::derived_from<TSerializer, ::NYT::NYTree::TExternalizedYsonStruct<TStruct>>, "Class must inherit from TExternalizedYsonStruct"); \
- ::NYT::NYTree::TExternalizedYsonStruct<TStruct>::That = ptr; \
+ static_assert(std::derived_from<TSerializer, ::NYT::NYTree::TExternalizedYsonStruct>, "Class must inherit from TExternalizedYsonStruct"); \
+ SetThat(ptr); \
YSON_STRUCT_LITE_IMPL__CTOR_BODY(TSerializer); \
} \
- TSerializer() \
- : TSerializer(::NYT::NYTree::TExternalizedYsonStruct<TStruct>::GetDefault()) \
- { }; \
+
+#define REGISTER_EXTERNALIZED_YSON_STRUCT(TStruct, TSerializer) \
+ EXTERNALIZED_YSON_STRUCT_IMPL__CTORS(TStruct, TSerializer) \
+public: \
+ void SetThat(TStruct* ptr) \
+ { \
+ That_ = ptr; \
+ } \
+ YSON_STRUCT_EXTERNAL_SERIALIZER_IMPL__DECLARE_ALIASES(TStruct, TSerializer) \
+
+//! TODO(arkady-e1ppa):
+/*
+ Code below is terrible both in terms of internal implementation and user experience.
+ Ideally we would want to abolish the macro below and instead use magic method
+ "GetThat" whenever we want to assign That_. Properly implementing CreateReadOnly
+ is likely to require some more tinkering but should ultimately be possible to do.
+
+ Magic GetThat should be something along the lines
+ static TStruct* GetThat(this auto& self)
+ {
+ return self.That_;
+ }
+
+ and called as TSerializer::GetThat(*this) which would trigger the correct overload of it and
+ deduce the most derived type in auto which would resolve .That_ as a field of the most derived
+ class.
+
+ This "deducing this" feature will come in C++23 and is likely to be properly supported in clang-18 or 19.
+
+ Another thing to consider is using some method (which is likely outside of standard) to list all
+ direct bases of the type so we can at least remove explicit enumeration of them in the user code.
+
+ Perhaps, there is another approach to consider?
+*/
+
+#define BASE_SET_THAT_ENTRY(TBase) \
+ TBase::SetThat(ptr); \
+
+#define REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(TStruct, TSerializer, TBases) \
+ EXTERNALIZED_YSON_STRUCT_IMPL__CTORS(TStruct, TSerializer) \
+public: \
+ void SetThat(TStruct* ptr) \
+ { \
+ That_ = ptr; \
+ PP_FOR_EACH(BASE_SET_THAT_ENTRY, TBases) \
+ } \
YSON_STRUCT_EXTERNAL_SERIALIZER_IMPL__DECLARE_ALIASES(TStruct, TSerializer) \
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/ytree/yson_struct.h b/yt/yt/core/ytree/yson_struct.h
index 41b93142f6..a3cf015a89 100644
--- a/yt/yt/core/ytree/yson_struct.h
+++ b/yt/yt/core/ytree/yson_struct.h
@@ -147,17 +147,10 @@ class TYsonStructLite
////////////////////////////////////////////////////////////////////////////////
-template <std::default_initializable TStruct>
class TExternalizedYsonStruct
: public TYsonStructLite
{
public:
- //! NB(arkady-e1ppa): Alias is used by registrar postprocessors
- //! in order to properly infer template argument.
- using TExternal = TStruct;
-
- TStruct* That = nullptr;
-
//! NB(arkady-e1ppa): Due to still present bug in clang which makes it
//! incapable of processing constraints, which refer to class template
//! parameters, we cannot properly constraint TSerializer here and
@@ -167,15 +160,16 @@ public:
//! replace class with std::derived_from<TExternalizedYsonStruct<TStruct>>
//! and remove exposition-only "requires" statements
- template <class TSerializer>
+ template <std::default_initializable TStruct, class TSerializer>
// requires std::derived_from<TSerializer, TExternalizedYsonStruct<TStruct>>
static TSerializer CreateWritable(TStruct& writable);
- template <class TSerializer>
+ template <std::default_initializable TStruct, class TSerializer>
// requires std::derived_from<TSerializer, TExternalizedYsonStruct<TStruct>>
static TSerializer CreateReadOnly(const TStruct& readOnly);
protected:
+ template <std::default_initializable TStruct>
static TStruct* GetDefault() noexcept;
};
@@ -356,6 +350,8 @@ void UpdateYsonStructField(TIntrusivePtr<TDst>& dst, const TIntrusivePtr<TSrc>&
//! Define non-ref-counted Yson external serializer methods and fields.
#define REGISTER_EXTERNALIZED_YSON_STRUCT(TStruct, TSerializer)
+#define REGISTER_DERIVED_EXTERNALIZED_YSON_STRUCT(TStruct, TSerializer, TBases)
+
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT::NYTree