This is an automated email from the ASF dual-hosted git repository. twice pushed a commit to branch unstable in repository https://gitbox.apache.org/repos/asf/kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push: new a7d5f4fa feat(status): support rocksdb::Status fowarding in GET_OR_RET (#2630) a7d5f4fa is described below commit a7d5f4fa3d069c196fd75135642289e3e7967f02 Author: Twice <twice.m...@gmail.com> AuthorDate: Thu Oct 31 15:42:24 2024 +0800 feat(status): support rocksdb::Status fowarding in GET_OR_RET (#2630) --- src/common/status.h | 33 +++++++++++++++++++++++++++------ tests/cppunit/status_test.cc | 28 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/common/status.h b/src/common/status.h index aef74033..b4b228a0 100644 --- a/src/common/status.h +++ b/src/common/status.h @@ -29,6 +29,7 @@ #include <type_traits> #include <utility> +#include "rocksdb/status.h" #include "type_util.h" class [[nodiscard]] Status { @@ -369,10 +370,30 @@ struct [[nodiscard]] StatusOr { friend struct StatusOr; }; +template <typename T, + std::enable_if_t<IsStatusOr<RemoveCVRef<T>>::value || std::is_same_v<RemoveCVRef<T>, Status>, int> = 0> +decltype(auto) StatusGetValue(T&& v) { + return std::forward<T>(v).GetValue(); +} + +template <typename T, std::enable_if_t<std::is_same_v<RemoveCVRef<T>, rocksdb::Status>, int> = 0> +void StatusGetValue(T&&) {} + +template <typename T, + std::enable_if_t<IsStatusOr<RemoveCVRef<T>>::value || std::is_same_v<RemoveCVRef<T>, Status>, int> = 0> +bool StatusIsOK(const T& v) { + return v.IsOK(); +} + +template <typename T, std::enable_if_t<std::is_same_v<RemoveCVRef<T>, rocksdb::Status>, int> = 0> +bool StatusIsOK(const T& v) { + return v.ok(); +} + // NOLINTNEXTLINE -#define GET_OR_RET(...) \ - ({ \ - auto&& status = (__VA_ARGS__); \ - if (!status) return std::forward<decltype(status)>(status); \ - std::forward<decltype(status)>(status); \ - }).GetValue() +#define GET_OR_RET(...) \ + StatusGetValue(({ \ + auto&& status = (__VA_ARGS__); \ + if (!StatusIsOK(status)) return std::forward<decltype(status)>(status); \ + std::forward<decltype(status)>(status); \ + })) diff --git a/tests/cppunit/status_test.cc b/tests/cppunit/status_test.cc index 5c800c9e..192c5280 100644 --- a/tests/cppunit/status_test.cc +++ b/tests/cppunit/status_test.cc @@ -226,3 +226,31 @@ TEST(StatusOr, Prefixed) { ASSERT_EQ(g(-2).Msg(), "oh: hi"); ASSERT_EQ(*g(5), 36); } + +TEST(GetOrRet, RocksdbStatus) { + auto f = [](int x) -> Status { + if (x < 10) return {Status::NotOK}; + return Status::OK(); + }; + + auto g = [&f](int x) -> Status { + GET_OR_RET(f(x)); + return Status::OK(); + }; + + ASSERT_TRUE(g(10)); + ASSERT_FALSE(g(1)); + + auto f2 = [](int x) -> rocksdb::Status { + if (x < 10) return rocksdb::Status::InvalidArgument(""); + return rocksdb::Status::OK(); + }; + + auto g2 = [&f2](int x) -> rocksdb::Status { + GET_OR_RET(f2(x)); + return rocksdb::Status::OK(); + }; + + ASSERT_TRUE(g2(10).ok()); + ASSERT_FALSE(g2(1).ok()); +}