Skip to content

Commit 44e4880

Browse files
committed
[libc++][functional] Implement bind_front<NTTP>
1 parent f248010 commit 44e4880

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

libcxx/include/__functional/bind_front.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include <__type_traits/decay.h>
1818
#include <__type_traits/enable_if.h>
1919
#include <__type_traits/is_constructible.h>
20+
#include <__type_traits/is_member_pointer.h>
21+
#include <__type_traits/is_pointer.h>
2022
#include <__utility/forward.h>
2123

2224
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -49,6 +51,38 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
4951

5052
#endif // _LIBCPP_STD_VER >= 20
5153

54+
#if _LIBCPP_STD_VER >= 26
55+
56+
template <auto _Fn>
57+
struct __nttp_bind_front_op {
58+
template <class... _Args>
59+
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const
60+
noexcept(noexcept(std::invoke(_Fn, std::forward<_Args>(__args)...)))
61+
-> decltype(std::invoke(_Fn, std::forward<_Args>(__args)...)) {
62+
return std::invoke(_Fn, std::forward<_Args>(__args)...);
63+
}
64+
};
65+
66+
template <auto _Fn, class... _BoundArgs>
67+
struct __nttp_bind_front_t : __perfect_forward<__nttp_bind_front_op<_Fn>, _BoundArgs...> {
68+
using __perfect_forward<__nttp_bind_front_op<_Fn>, _BoundArgs...>::__perfect_forward;
69+
};
70+
71+
template <auto _Fn, class... _Args>
72+
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Args&&... __args) {
73+
static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
74+
"bind_front requires all decay_t<Args> to be constructible from respective Args");
75+
static_assert((is_move_constructible_v<decay_t<_Args>> && ...),
76+
"bind_front requires all decay_t<Args> to be move constructible");
77+
if constexpr (using _Ty = decltype(_Fn); is_pointer_v<_Ty> || is_member_pointer_v<_Ty>) {
78+
static_assert(_Fn != nullptr, "f cannot be equal to nullptr");
79+
}
80+
81+
return __nttp_bind_front_t<_Fn, decay_t<_Args>...>(std::forward<_Args>(__args)...);
82+
}
83+
84+
#endif // _LIBCPP_STD_VER >= 26
85+
5286
_LIBCPP_END_NAMESPACE_STD
5387

5488
#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H

libcxx/include/functional

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ template <auto f>
221221
// [func.bind.partial], function templates bind_front and bind_back
222222
template<class F, class... Args>
223223
constexpr unspecified bind_front(F&&, Args&&...); // C++20
224+
template<auto f, class... Args>
225+
constexpr unspecified bind_front(Args&&...); // C++26
224226
template<class F, class... Args>
225227
constexpr unspecified bind_back(F&&, Args&&...); // C++23
226228

0 commit comments

Comments
 (0)