[PATCH] D96794: [ADT] Add SFINAE guards to unique_function constructor.

Sam McCall via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 13:16:56 PST 2021


sammccall updated this revision to Diff 324092.
sammccall marked 2 inline comments as done.
sammccall added a comment.

fix test


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D96794

Files:
  llvm/include/llvm/ADT/FunctionExtras.h
  llvm/unittests/ADT/FunctionExtrasTest.cpp


Index: llvm/unittests/ADT/FunctionExtrasTest.cpp
===================================================================
--- llvm/unittests/ADT/FunctionExtrasTest.cpp
+++ llvm/unittests/ADT/FunctionExtrasTest.cpp
@@ -262,4 +262,15 @@
   EXPECT_EQ("const", X());
 }
 
+// Test that overloads on unique_functions are resolved as expected.
+std::string returns(StringRef) { return "not a function"; }
+std::string returns(unique_function<double()> F) { return "number"; }
+std::string returns(unique_function<StringRef()> F) { return "string"; }
+
+TEST(UniqueFunctionTest, SFINAE) {
+  EXPECT_EQ("not a function", returns("boo!"));
+  EXPECT_EQ("number", returns([] { return 42; }));
+  EXPECT_EQ("string", returns([] { return "hello"; }));
+}
+
 } // anonymous namespace
Index: llvm/include/llvm/ADT/FunctionExtras.h
===================================================================
--- llvm/include/llvm/ADT/FunctionExtras.h
+++ llvm/include/llvm/ADT/FunctionExtras.h
@@ -59,6 +59,15 @@
 using EnableIfTrivial =
     std::enable_if_t<llvm::is_trivially_move_constructible<T>::value &&
                      std::is_trivially_destructible<T>::value>;
+template <typename CallableT, typename ThisT>
+using EnableUnlessSameType = std::enable_if_t<!std::is_same<
+    std::remove_cv_t<std::remove_reference_t<CallableT>>, ThisT>::value>;
+template <typename CallableT, typename Ret, typename... Params>
+using EnableIfCallable =
+    std::enable_if_t<std::is_void<Ret>::value ||
+                     std::is_convertible<decltype(std::declval<CallableT>()(
+                                             std::declval<Params>()...)),
+                                         Ret>::value>;
 
 template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
 protected:
@@ -346,7 +355,10 @@
   unique_function &operator=(const unique_function &) = delete;
 
   template <typename CallableT>
-  unique_function(CallableT Callable)
+  unique_function(
+      CallableT Callable,
+      detail::EnableUnlessSameType<CallableT, unique_function> * = nullptr,
+      detail::EnableIfCallable<CallableT, R, P...> * = nullptr)
       : Base(std::forward<CallableT>(Callable),
              typename Base::template CalledAs<CallableT>{}) {}
 
@@ -369,7 +381,10 @@
   unique_function &operator=(const unique_function &) = delete;
 
   template <typename CallableT>
-  unique_function(CallableT Callable)
+  unique_function(
+      CallableT Callable,
+      detail::EnableUnlessSameType<CallableT, unique_function> * = nullptr,
+      detail::EnableIfCallable<const CallableT, R, P...> * = nullptr)
       : Base(std::forward<CallableT>(Callable),
              typename Base::template CalledAs<const CallableT>{}) {}
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D96794.324092.patch
Type: text/x-patch
Size: 2713 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210216/6d5c286c/attachment.bin>


More information about the llvm-commits mailing list