diff options
author | ionagamed <ionagamed@yandex-team.com> | 2023-06-10 13:55:54 +0300 |
---|---|---|
committer | ionagamed <ionagamed@yandex-team.com> | 2023-06-10 13:55:54 +0300 |
commit | 824bccde520021cc23441f3f0d01bdd791ff6790 (patch) | |
tree | b1b84d730f4359a45ffb16623bc625706e57ceea | |
parent | d570836295decdb827b4f95d75ebf2d8d9232b9b (diff) | |
download | ydb-824bccde520021cc23441f3f0d01bdd791ff6790.tar.gz |
util/saveload: implement default saveload for std::optional
-rw-r--r-- | util/ysaveload.h | 22 | ||||
-rw-r--r-- | util/ysaveload_ut.cpp | 21 |
2 files changed, 43 insertions, 0 deletions
diff --git a/util/ysaveload.h b/util/ysaveload.h index f3451e2ad5..8771f1e4a1 100644 --- a/util/ysaveload.h +++ b/util/ysaveload.h @@ -12,6 +12,7 @@ #ifndef __NVCC__ // cuda is compiled in C++14 mode at the time + #include <optional> #include <variant> #endif @@ -642,6 +643,27 @@ public: #ifndef __NVCC__ +template <typename T> +struct TSerializer<std::optional<T>> { + static inline void Save(IOutputStream* os, const std::optional<T>& v) { + ::Save(os, v.has_value()); + if (v.has_value()) { + ::Save(os, *v); + } + } + + static inline void Load(IInputStream* is, std::optional<T>& v) { + v.reset(); + + bool hasValue; + ::Load(is, hasValue); + + if (hasValue) { + ::Load(is, v.emplace()); + } + } +}; + namespace NPrivate { template <class Variant, class T, size_t I> void LoadVariantAlternative(IInputStream* is, Variant& v) { diff --git a/util/ysaveload_ut.cpp b/util/ysaveload_ut.cpp index 7656f8e941..23152ed929 100644 --- a/util/ysaveload_ut.cpp +++ b/util/ysaveload_ut.cpp @@ -27,6 +27,7 @@ class TSaveLoadTest: public TTestBase { UNIT_TEST(TestList) UNIT_TEST(TestTuple) UNIT_TEST(TestVariant) + UNIT_TEST(TestOptional) UNIT_TEST(TestInheritNonVirtualClass) UNIT_TEST(TestInheritVirtualClass) UNIT_TEST_SUITE_END(); @@ -429,6 +430,26 @@ private: UNIT_ASSERT_EXCEPTION(::Load(&s, v2), TLoadEOF); } + template <class T> + void TestOptionalImpl(const std::optional<T>& v) { + std::optional<T> loaded; + TBufferStream s; + ::Save(&s, v); + ::Load(&s, loaded); + + UNIT_ASSERT_VALUES_EQUAL(v.has_value(), loaded.has_value()); + if (v.has_value()) { + UNIT_ASSERT_VALUES_EQUAL(*v, *loaded); + } + } + + void TestOptional() { + TestOptionalImpl(std::optional<ui64>(42ull)); + TestOptionalImpl(std::optional<bool>(true)); + TestOptionalImpl(std::optional<TString>("abacaba")); + TestOptionalImpl(std::optional<ui64>(std::nullopt)); + } + // tests serialization of class with three public string members template <class TDerived, class TInterface = TDerived> void TestInheritClassImpl() { |