[PATCH] D123576: Support constructing empty function_ref from other callables that can be "empty"

Mehdi AMINI via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 12 01:54:52 PDT 2022


mehdi_amini updated this revision to Diff 422142.
mehdi_amini marked 2 inline comments as done.
mehdi_amini added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D123576/new/

https://reviews.llvm.org/D123576

Files:
  llvm/include/llvm/ADT/STLFunctionalExtras.h
  llvm/unittests/ADT/FunctionRefTest.cpp


Index: llvm/unittests/ADT/FunctionRefTest.cpp
===================================================================
--- llvm/unittests/ADT/FunctionRefTest.cpp
+++ llvm/unittests/ADT/FunctionRefTest.cpp
@@ -59,4 +59,11 @@
   EXPECT_EQ("string", returns([] { return "hello"; }));
 }
 
+TEST(FunctionRefTest, std_function) {
+  // Check that function_ref constructed from an empty std::function is empty.
+  std::function<void()> f;
+  function_ref<void()> f_ref(f);
+  ASSERT_FALSE((bool)f_ref);
+}
+
 } // namespace
Index: llvm/include/llvm/ADT/STLFunctionalExtras.h
===================================================================
--- llvm/include/llvm/ADT/STLFunctionalExtras.h
+++ llvm/include/llvm/ADT/STLFunctionalExtras.h
@@ -46,6 +46,22 @@
         std::forward<Params>(params)...);
   }
 
+  // Handles construction from an empty callable (for example a default
+  // constructed std::function) and ensure that bool conversion to `false` is
+  // propagated.
+  template <typename Callable,
+            std::enable_if_t<std::is_constructible<bool, Callable>::value> * =
+                nullptr>
+  static decltype(callback) get_callback(const Callable &callable) {
+    return callable ? callback_fn<std::remove_reference_t<Callable>> : nullptr;
+  }
+  template <typename Callable,
+            std::enable_if_t<!std::is_constructible<bool, Callable>::value> * =
+                nullptr>
+  static decltype(callback) get_callback(const Callable &callable) {
+    return callback_fn<std::remove_reference_t<Callable>>;
+  }
+
 public:
   function_ref() = default;
   function_ref(std::nullptr_t) {}
@@ -61,7 +77,7 @@
                        std::is_convertible<decltype(std::declval<Callable>()(
                                                std::declval<Params>()...)),
                                            Ret>::value> * = nullptr)
-      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
+      : callback(get_callback<Callable>(callable)),
         callable(reinterpret_cast<intptr_t>(&callable)) {}
 
   Ret operator()(Params ...params) const {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D123576.422142.patch
Type: text/x-patch
Size: 2093 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220412/78042d3a/attachment.bin>


More information about the llvm-commits mailing list