[libcxx-commits] [libcxx] [libc++][functional] Implement `std::bind_front<NTTP>` (PR #165096)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Sun Oct 26 01:53:12 PDT 2025


================
@@ -49,6 +51,38 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) {
 
 #endif // _LIBCPP_STD_VER >= 20
 
+#if _LIBCPP_STD_VER >= 26
+
+template <auto _Fn>
+struct __nttp_bind_front_op {
+  template <class... _Args>
+  _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Args&&... __args) const
+      noexcept(noexcept(std::invoke(_Fn, std::forward<_Args>(__args)...)))
+          -> decltype(std::invoke(_Fn, std::forward<_Args>(__args)...)) {
+    return std::invoke(_Fn, std::forward<_Args>(__args)...);
+  }
+};
+
+template <auto _Fn, class... _BoundArgs>
+struct __nttp_bind_front_t : __perfect_forward<__nttp_bind_front_op<_Fn>, _BoundArgs...> {
+  using __perfect_forward<__nttp_bind_front_op<_Fn>, _BoundArgs...>::__perfect_forward;
+};
+
+template <auto _Fn, class... _Args>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Args&&... __args) {
+  static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
+                "bind_front requires all decay_t<Args> to be constructible from respective Args");
+  static_assert((is_move_constructible_v<decay_t<_Args>> && ...),
+                "bind_front requires all decay_t<Args> to be move constructible");
+  if constexpr (using _Ty = decltype(_Fn); is_pointer_v<_Ty> || is_member_pointer_v<_Ty>) {
+    static_assert(_Fn != nullptr, "f cannot be equal to nullptr");
+  }
+
+  return __nttp_bind_front_t<_Fn, decay_t<_Args>...>(std::forward<_Args>(__args)...);
----------------
frederick-vs-ja wrote:

When `sizeof...(_Args) == 0`, it seems better to return a functor with static `operator()`.

https://github.com/llvm/llvm-project/pull/165096


More information about the libcxx-commits mailing list