[libc++][ranges] Implement `ranges::replace_copy{,_if}`.

Co-authored-by: Konstantin Varlamov <[email protected]>

Differential Revision: https://reviews.llvm.org/D129806
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index b4e1b82..0a40778 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -944,6 +944,43 @@
     constexpr remove_copy_if_result<borrowed_iterator_t<R>, O>
       remove_copy_if(R&& r, O result, Pred pred, Proj proj = {});                                  // Since C++20
 
+  template<class I, class O>
+      using replace_copy_result = in_out_result<I, O>;                                             // Since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class T1, class T2,
+           output_iterator<const T2&> O, class Proj = identity>
+    requires indirectly_copyable<I, O> &&
+             indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T1*>
+    constexpr replace_copy_result<I, O>
+      replace_copy(I first, S last, O result, const T1& old_value, const T2& new_value,
+                   Proj proj = {});                                                                // Since C++20
+
+  template<input_range R, class T1, class T2, output_iterator<const T2&> O,
+           class Proj = identity>
+    requires indirectly_copyable<iterator_t<R>, O> &&
+             indirect_binary_predicate<ranges::equal_to,
+                                       projected<iterator_t<R>, Proj>, const T1*>
+    constexpr replace_copy_result<borrowed_iterator_t<R>, O>
+      replace_copy(R&& r, O result, const T1& old_value, const T2& new_value,
+                   Proj proj = {});                                                                // Since C++20
+
+  template<class I, class O>
+      using replace_copy_if_result = in_out_result<I, O>;                                          // Since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class T, output_iterator<const T&> O,
+           class Proj = identity, indirect_unary_predicate<projected<I, Proj>> Pred>
+    requires indirectly_copyable<I, O>
+    constexpr replace_copy_if_result<I, O>
+      replace_copy_if(I first, S last, O result, Pred pred, const T& new_value,
+                      Proj proj = {});                                                             // Since C++20
+
+  template<input_range R, class T, output_iterator<const T&> O, class Proj = identity,
+           indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+    requires indirectly_copyable<iterator_t<R>, O>
+    constexpr replace_copy_if_result<borrowed_iterator_t<R>, O>
+      replace_copy_if(R&& r, O result, Pred pred, const T& new_value,
+                      Proj proj = {});                                                             // Since C++20
+
 }
 
     constexpr bool     // constexpr in C++20
@@ -1730,6 +1767,8 @@
 #include <__algorithm/ranges_remove_copy_if.h>
 #include <__algorithm/ranges_remove_if.h>
 #include <__algorithm/ranges_replace.h>
+#include <__algorithm/ranges_replace_copy.h>
+#include <__algorithm/ranges_replace_copy_if.h>
 #include <__algorithm/ranges_replace_if.h>
 #include <__algorithm/ranges_reverse.h>
 #include <__algorithm/ranges_reverse_copy.h>