[Bf-blender-cvs] [328b39335ef] master: BLI: add call_safe method for FunctionRef
Jacques Lucke
noreply at git.blender.org
Thu Apr 1 12:44:37 CEST 2021
Commit: 328b39335ef82248eb4a8af16251247763be5a2f
Author: Jacques Lucke
Date: Thu Apr 1 12:33:41 2021 +0200
Branches: master
https://developer.blender.org/rB328b39335ef82248eb4a8af16251247763be5a2f
BLI: add call_safe method for FunctionRef
This is useful to avoid nullity checks in some places.
===================================================================
M source/blender/blenlib/BLI_function_ref.hh
M source/blender/blenlib/tests/BLI_function_ref_test.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh
index 57fffdc09b4..38e1ba593c5 100644
--- a/source/blender/blenlib/BLI_function_ref.hh
+++ b/source/blender/blenlib/BLI_function_ref.hh
@@ -16,6 +16,7 @@
#pragma once
+#include <optional>
#include <type_traits>
#include <utility>
@@ -139,6 +140,29 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
return callback_(callable_, std::forward<Params>(params)...);
}
+ using OptionalReturnValue = std::conditional_t<std::is_void_v<Ret>, void, std::optional<Ret>>;
+
+ /**
+ * Calls the referenced function if it is available.
+ * The return value is of type `std::optional<Ret>` if `Ret` is not `void`.
+ * Otherwise the return type is `void`.
+ */
+ OptionalReturnValue call_safe(Params... params) const
+ {
+ if constexpr (std::is_void_v<Ret>) {
+ if (callback_ == nullptr) {
+ return;
+ }
+ callback_(callable_, std::forward<Params>(params)...);
+ }
+ else {
+ if (callback_ == nullptr) {
+ return {};
+ }
+ return callback_(callable_, std::forward<Params>(params)...);
+ }
+ }
+
/**
* Returns true, when the `FunctionRef` references a function currently.
* If this returns false, the `FunctionRef` must not be called.
diff --git a/source/blender/blenlib/tests/BLI_function_ref_test.cc b/source/blender/blenlib/tests/BLI_function_ref_test.cc
index cdcbccc72e8..74f5014142c 100644
--- a/source/blender/blenlib/tests/BLI_function_ref_test.cc
+++ b/source/blender/blenlib/tests/BLI_function_ref_test.cc
@@ -99,4 +99,29 @@ TEST(function_ref, ReferenceAnotherFunctionRef)
EXPECT_EQ(y(), 2);
}
+TEST(function_ref, CallSafe)
+{
+ FunctionRef<int()> f;
+ EXPECT_FALSE(f.call_safe().has_value());
+ auto func = []() { return 10; };
+ f = func;
+ EXPECT_TRUE(f.call_safe().has_value());
+ EXPECT_EQ(*f.call_safe(), 10);
+ f = {};
+ EXPECT_FALSE(f.call_safe().has_value());
+ BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), std::optional<int>>), "");
+}
+
+TEST(function_ref, CallSafeVoid)
+{
+ FunctionRef<void()> f;
+ BLI_STATIC_ASSERT((std::is_same_v<decltype(f.call_safe()), void>), "");
+ f.call_safe();
+ int value = 0;
+ auto func = [&]() { value++; };
+ f = func;
+ f.call_safe();
+ EXPECT_EQ(value, 1);
+}
+
} // namespace blender::tests
More information about the Bf-blender-cvs
mailing list