Skip to content

Instantly share code, notes, and snippets.

@ldionne
Created July 30, 2021 16:24
Show Gist options
  • Save ldionne/a8ca54b04a158748ddb8a7696d701ef1 to your computer and use it in GitHub Desktop.
Save ldionne/a8ca54b04a158748ddb8a7696d701ef1 to your computer and use it in GitHub Desktop.
Diff to get Zoe's suggestion for bind_back
diff --git a/libcxx/include/__functional/bind_back.h b/libcxx/include/__functional/bind_back.h
index fd4d0ea75ade..110cab61f8d6 100644
--- a/libcxx/include/__functional/bind_back.h
+++ b/libcxx/include/__functional/bind_back.h
@@ -26,36 +26,22 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17
-// Passes the provided arguments to std::invoke in the order specified by the given index_sequence.
-template <size_t ..._Ip, class ..._Args, class _AsTuple = tuple<_Args&&...>>
-_LIBCPP_HIDE_FROM_ABI
-constexpr auto __invoke_shuffle(index_sequence<_Ip...>, _Args&& ...__args)
- noexcept(is_nothrow_invocable_v<tuple_element_t<_Ip, _AsTuple>...>)
- -> typename invoke_result<tuple_element_t<_Ip, _AsTuple>...>::type
-{
- _AsTuple __as_tuple = _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...);
- return _VSTD::invoke(_VSTD::forward<tuple_element_t<_Ip, _AsTuple>>(_VSTD::get<_Ip>(__as_tuple))...);
-}
+template <size_t _NBound, class = make_index_sequence<_NBound>>
+struct __bind_back_op;
-template <size_t _NBound>
-struct __bind_back_op {
- template <class _Fn, class ..._Args,
- size_t _NUnbound = sizeof...(_Args) - _NBound,
- class _Sequence = __join_integer_sequences<
- index_sequence<0>, // [0, 1) = the function object to invoke
- __shift_index_sequence_by<_NBound+1, make_index_sequence<_NUnbound>>, // [_NBound+1, _NUnbound) = the passed arguments, which go first
- __shift_index_sequence_by<1, make_index_sequence<_NBound>> // [1, _NBound) = the bound arguments, which go last
- >>
+template <size_t _NBound, size_t ..._Ip>
+struct __bind_back_op<_NBound, index_sequence<_Ip...>> {
+ template <class _Fn, class _Bound, class ..._Args>
_LIBCPP_HIDE_FROM_ABI
- static constexpr auto __call(_Fn&& __f, _Args&& ...__args)
- noexcept(noexcept(_VSTD::__invoke_shuffle(_Sequence{}, _VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...)))
- -> decltype( _VSTD::__invoke_shuffle(_Sequence{}, _VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...))
- { return _VSTD::__invoke_shuffle(_Sequence{}, _VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); }
+ static constexpr auto __call(_Fn&& __f, _Bound&& __bound, _Args&& ...__args)
+ noexcept(noexcept(_VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...)))
+ -> decltype( _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...))
+ { return _VSTD::invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)..., _VSTD::get<_Ip>(_VSTD::forward<_Bound>(__bound))...); }
};
-template <class _Fn, class ..._BoundArgs>
-struct __bind_back_t : __perfect_forward<__bind_back_op<sizeof...(_BoundArgs)>, _Fn, _BoundArgs...> {
- using __perfect_forward<__bind_back_op<sizeof...(_BoundArgs)>, _Fn, _BoundArgs...>::__perfect_forward;
+template <class _Fn, class _BoundArgs>
+struct __bind_back_t : __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs> {
+ using __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs>::__perfect_forward;
};
template <class _Fn, class ..._Args, class = _EnableIf<
@@ -68,9 +54,9 @@ template <class _Fn, class ..._Args, class = _EnableIf<
>>
_LIBCPP_HIDE_FROM_ABI
constexpr auto __bind_back(_Fn&& __f, _Args&&... __args)
-noexcept(noexcept(__bind_back_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...)))
--> decltype( __bind_back_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...))
-{ return __bind_back_t<decay_t<_Fn>, decay_t<_Args>...>(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); }
+noexcept(noexcept(__bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::make_tuple(_VSTD::forward<_Args>(__args)...))))
+-> decltype( __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::make_tuple(_VSTD::forward<_Args>(__args)...)))
+{ return __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(_VSTD::forward<_Fn>(__f), _VSTD::make_tuple(_VSTD::forward<_Args>(__args)...)); }
#endif // _LIBCPP_STD_VER > 17
diff --git a/libcxx/include/__utility/integer_sequence.h b/libcxx/include/__utility/integer_sequence.h
index 00d2fd51af6e..963c4a967070 100644
--- a/libcxx/include/__utility/integer_sequence.h
+++ b/libcxx/include/__utility/integer_sequence.h
@@ -74,39 +74,6 @@ template<size_t _Np>
template<class... _Tp>
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
-
-template<class ..._Sequences>
-struct __join_integer_sequences_impl;
-
-template<class _S1>
-struct __join_integer_sequences_impl<_S1> {
- using type = _S1;
-};
-
-template<class _Tp, _Tp ..._Ip1, _Tp ..._Ip2>
-struct __join_integer_sequences_impl<integer_sequence<_Tp, _Ip1...>, integer_sequence<_Tp, _Ip2...>> {
- using type = integer_sequence<_Tp, _Ip1..., _Ip2...>;
-};
-
-template<class _S1, class _S2, class ..._Sn>
-struct __join_integer_sequences_impl<_S1, _S2, _Sn...>
- : __join_integer_sequences_impl<typename __join_integer_sequences_impl<_S1, _S2>::type, _Sn...>
-{ };
-
-template<class ..._Sequences>
-using __join_integer_sequences = typename __join_integer_sequences_impl<_Sequences...>::type;
-
-template<size_t _Np, class _Sequence>
-struct __shift_index_sequence_by_impl;
-
-template<size_t _Np, size_t ..._Ips>
-struct __shift_index_sequence_by_impl<_Np, index_sequence<_Ips...>> {
- using type = index_sequence<(_Np + _Ips)...>;
-};
-
-template<size_t _Np, class _Sequence>
-using __shift_index_sequence_by = typename __shift_index_sequence_by_impl<_Np, _Sequence>::type;
-
#endif // _LIBCPP_STD_VER > 11
_LIBCPP_END_NAMESPACE_STD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment