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