[libcxx-commits] [libcxx] [libcxx] replaces SFINAE with requires-expressions in `bind_front` and `bind_back` (PR #68249)

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Wed Oct 4 14:19:05 PDT 2023


https://github.com/cjdb updated https://github.com/llvm/llvm-project/pull/68249

>From 6c00d3aef1b0ec410e2c3392ceb8622d8b088e99 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Wed, 4 Oct 2023 19:29:17 +0000
Subject: [PATCH] [libcxx] replaces SFINAE with requires-expressions in
 `bind_front` and `bind_back`

The diagnostics for `enable_if_t` are extremely opaque:

```
error: no matching function for call to 'bind_front'
note: candidate template ignored: requirement 'integral_constant<bool, false>::value' was not satisfied
```

Using requires-expressions gives us a little more context:

```
error: no matching function for call to 'bind_front'
note: candidate template ignored: constraints not satisfied
note: because 'is_constructible_v<decay_t<T &>, T &>' evaluated to false
```
---
 libcxx/include/__functional/bind_back.h  | 11 +++--------
 libcxx/include/__functional/bind_front.h | 11 +++--------
 2 files changed, 6 insertions(+), 16 deletions(-)

diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h
index 71dc63c86bdbeed..0dd2befb5240946 100644
--- a/libcxx/include/__functional/bind_back.h
+++ b/libcxx/include/__functional/bind_back.h
@@ -43,14 +43,9 @@ struct __bind_back_t : __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>
     using __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs>::__perfect_forward;
 };
 
-template <class _Fn, class ..._Args, class = enable_if_t<
-    _And<
-        is_constructible<decay_t<_Fn>, _Fn>,
-        is_move_constructible<decay_t<_Fn>>,
-        is_constructible<decay_t<_Args>, _Args>...,
-        is_move_constructible<decay_t<_Args>>...
-    >::value
->>
+template <class _Fn, class... _Args>
+  requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
+           (is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
 _LIBCPP_HIDE_FROM_ABI
 constexpr auto __bind_back(_Fn&& __f, _Args&&... __args)
     noexcept(noexcept(__bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))))
diff --git a/libcxx/include/__functional/bind_front.h b/libcxx/include/__functional/bind_front.h
index 72bb66480959626..7ccd6e563b6e19e 100644
--- a/libcxx/include/__functional/bind_front.h
+++ b/libcxx/include/__functional/bind_front.h
@@ -42,14 +42,9 @@ struct __bind_front_t : __perfect_forward<__bind_front_op, _Fn, _BoundArgs...> {
     using __perfect_forward<__bind_front_op, _Fn, _BoundArgs...>::__perfect_forward;
 };
 
-template <class _Fn, class... _Args, class = enable_if_t<
-    _And<
-        is_constructible<decay_t<_Fn>, _Fn>,
-        is_move_constructible<decay_t<_Fn>>,
-        is_constructible<decay_t<_Args>, _Args>...,
-        is_move_constructible<decay_t<_Args>>...
-    >::value
->>
+template <class _Fn, class... _Args>
+  requires is_constructible_v<decay_t<_Fn>, _Fn> && is_move_constructible_v<decay_t<_Fn>> &&
+           (is_constructible_v<decay_t<_Args>, _Args> && ...) && (is_move_constructible_v<decay_t<_Args>> && ...)
 _LIBCPP_HIDE_FROM_ABI
 constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
     return __bind_front_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);



More information about the libcxx-commits mailing list