[PATCH] libstdc++: Optimize __make_comp_proj and __make_pred_proj for empty types

Patrick Palka ppalka@redhat.com
Thu Jun 12 15:56:29 GMT 2025


Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

I'm sure if introducing a new overload is preferable to
introducing a constexpr if branch in the existing overload.

-- >8 --

When composing a comparator/predicate and projection function, if both
are stateless (and default constructible) then we don't need to capture
them by reference; we can just return a captureless lambda and materialize
them on the spot.

libstdc++-v3/ChangeLog:

	* include/bits/ranges_algo.h (__detail::__make_comp_proj): New
	more specialized overload returning a stateless lambda if both
	the comparator/predicate and projection are stateless.
	(__detail::__make_pred_proj): Likewise.
---
 libstdc++-v3/include/bits/ranges_algo.h | 27 +++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 819316fa79c3..7dc84d639fbd 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -61,6 +61,21 @@ namespace ranges
 	};
       }
 
+    template<typename _Comp, typename _Proj>
+      requires is_empty_v<_Comp> && is_default_constructible_v<_Comp>
+	&& is_empty_v<_Proj> && is_default_constructible_v<_Proj>
+      constexpr auto
+      __make_comp_proj(_Comp& __comp, _Proj& __proj)
+      {
+	return [] (auto&& __lhs, auto&& __rhs) -> bool {
+	  using _TL = decltype(__lhs);
+	  using _TR = decltype(__rhs);
+	  return std::__invoke(_Comp{},
+			       std::__invoke(_Proj{}, std::forward<_TL>(__lhs)),
+			       std::__invoke(_Proj{}, std::forward<_TR>(__rhs)));
+	};
+      }
+
     template<typename _Pred, typename _Proj>
       constexpr auto
       __make_pred_proj(_Pred& __pred, _Proj& __proj)
@@ -70,6 +85,18 @@ namespace ranges
 			       std::__invoke(__proj, std::forward<_Tp>(__arg)));
 	};
       }
+
+    template<typename _Pred, typename _Proj>
+      requires is_empty_v<_Pred> && is_default_constructible_v<_Pred>
+	&& is_empty_v<_Proj> && is_default_constructible_v<_Pred>
+      constexpr auto
+      __make_pred_proj(_Pred& __pred, _Proj& __proj)
+      {
+	return [] <typename _Tp> (_Tp&& __arg) -> bool {
+	  return std::__invoke(_Pred{},
+			       std::__invoke(_Proj{}, std::forward<_Tp>(__arg)));
+	};
+      }
   } // namespace __detail
 
   struct __all_of_fn
-- 
2.50.0.rc2



More information about the Libstdc++ mailing list