[libcxx-commits] [libcxx] [libc++] Implement `ranges::fold_right_last` (completes P2322R6) (PR #195580)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Sun May 10 19:16:06 PDT 2026


================
@@ -234,6 +235,30 @@ struct __fold_right {
 };
 
 inline constexpr auto fold_right = __fold_right();
+
+struct __fold_right_last {
+  template <bidirectional_iterator _Iter,
+            sentinel_for<_Iter> _Sp,
+            __indirectly_binary_right_foldable<iter_value_t<_Iter>, _Iter> _Func>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Iter __first, _Sp __last, _Func __func) {
+    using _Up = decltype(fold_right(__first, __last, iter_value_t<_Iter>(*__first), __func));
+
+    if (__first == __last)
+      return optional<_Up>();
+
+    _Iter __tail = ranges::prev(ranges::next(__first, __last));
+    return optional<_Up>(
+        in_place, ranges::fold_right(std::move(__first), __tail, iter_value_t<_Iter>(*__tail), std::move(__func)));
+  }
+
+  template <bidirectional_range _Range,
+            __indirectly_binary_right_foldable<range_value_t<_Range>, iterator_t<_Range>> _Func>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Range&& __range, _Func __func) {
+    return operator()(ranges::begin(__range), ranges::end(__range), std::ref(__func));
----------------
frederick-vs-ja wrote:

`std::ref` makes `__func` never moved when passed to `ranges::fold_right`, but IMO this should be fine. In any case, we may submit one or more LWG issues to allow implementations to perform less move/copy constructions for certain objects.

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


More information about the libcxx-commits mailing list