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());
+}

Reply via email to