[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