aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorionagamed <ionagamed@yandex-team.com>2023-06-10 13:55:54 +0300
committerionagamed <ionagamed@yandex-team.com>2023-06-10 13:55:54 +0300
commit824bccde520021cc23441f3f0d01bdd791ff6790 (patch)
treeb1b84d730f4359a45ffb16623bc625706e57ceea
parentd570836295decdb827b4f95d75ebf2d8d9232b9b (diff)
downloadydb-824bccde520021cc23441f3f0d01bdd791ff6790.tar.gz
util/saveload: implement default saveload for std::optional
-rw-r--r--util/ysaveload.h22
-rw-r--r--util/ysaveload_ut.cpp21
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() {