[libc++][ranges] P1223R5: `find_last` (#99312)

Implements [P1223R5][] completely.

Includes an implementation of `find_last`, `find_last_if`, and
`find_last_if_not`.

[P1223R5]: https://wg21.link/p1223r5
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index a522a60..698e6f5 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -102,6 +102,31 @@
     constexpr borrowed_iterator_t<R>
       find_if_not(R&& r, Pred pred, Proj proj = {});                                                      // since C++20
 
+  template<forward_iterator I, sentinel_for<I> S, class T, class Proj = identity>
+    requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+    constexpr subrange<I> find_last(I first, S last, const T& value, Proj proj = {});                     // since C++23
+
+  template<forward_range R, class T, class Proj = identity>
+    requires
+      indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+    constexpr borrowed_subrange_t<R> find_last(R&& r, const T& value, Proj proj = {});                   // since C++23
+
+  template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+           indirect_unary_predicate<projected<I, Proj>> Pred>
+    constexpr subrange<I> find_last_if(I first, S last, Pred pred, Proj proj = {});                      // since C++23
+
+  template<forward_range R, class Proj = identity,
+           indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+    constexpr borrowed_subrange_t<R> find_last_if(R&& r, Pred pred, Proj proj = {});                     // since C++23
+
+  template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
+           indirect_unary_predicate<projected<I, Proj>> Pred>
+    constexpr subrange<I> find_last_if_not(I first, S last, Pred pred, Proj proj = {});                  // since C++23
+
+  template<forward_range R, class Proj = identity,
+           indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+    constexpr borrowed_subrange_t<R> find_last_if_not(R&& r, Pred pred, Proj proj = {});                 // since C++23
+
   template<class T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
     constexpr const T& min(const T& a, const T& b, Comp comp = {}, Proj proj = {});                       // since C++20
@@ -1989,6 +2014,7 @@
 #  include <__algorithm/fold.h>
 #  include <__algorithm/ranges_contains_subrange.h>
 #  include <__algorithm/ranges_ends_with.h>
+#  include <__algorithm/ranges_find_last.h>
 #  include <__algorithm/ranges_starts_with.h>
 #endif // _LIBCPP_STD_VER >= 23