[libc++] Implement ranges::for_each{, _n}

Reviewed By: var-const, #libc

Spies: libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D124332

NOKEYCHECK=True
GitOrigin-RevId: 80045e9afa2f3545d3b1f2d06090a9a053a90307
diff --git a/include/algorithm b/include/algorithm
index 2c1474e..13b3064 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -238,6 +238,24 @@
     requires indirectly_copyable<iterator_t<R>, I>
     constexpr ranges::copy_backward_result<borrowed_iterator_t<R>, I>
       ranges::copy_backward(R&& r, I result);                                               // since C++20
+
+  template<class I, class F>
+    using for_each_result = in_fun_result<I, F>;                                            // since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+           indirectly_unary_invocable<projected<I, Proj>> Fun>
+    constexpr ranges::for_each_result<I, Fun>
+      ranges::for_each(I first, S last, Fun f, Proj proj = {});                             // since C++20
+
+  template<input_range R, class Proj = identity,
+           indirectly_unary_invocable<projected<iterator_t<R>, Proj>> Fun>
+    constexpr ranges::for_each_result<borrowed_iterator_t<R>, Fun>
+      ranges::for_each(R&& r, Fun f, Proj proj = {});                                       // since C++20
+
+  template<input_iterator I, class Proj = identity,
+           indirectly_unary_invocable<projected<I, Proj>> Fun>
+    constexpr ranges::for_each_n_result<I, Fun>
+      ranges::for_each_n(I first, iter_difference_t<I> n, Fun f, Proj proj = {});           // since C++20
 }
 
     constexpr bool     // constexpr in C++20
@@ -963,6 +981,8 @@
 #include <__algorithm/ranges_find.h>
 #include <__algorithm/ranges_find_if.h>
 #include <__algorithm/ranges_find_if_not.h>
+#include <__algorithm/ranges_for_each.h>
+#include <__algorithm/ranges_for_each_n.h>
 #include <__algorithm/ranges_max.h>
 #include <__algorithm/ranges_max_element.h>
 #include <__algorithm/ranges_min.h>