[libc++][ranges] Implement ranges::find{, _if, _if_not}

Reviewed By: var-const, #libc, ldionne

Spies: ldionne, tcanens, libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D121248
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm
index 72fdb29..6fe66e42 100644
--- a/libcxx/include/algorithm
+++ b/libcxx/include/algorithm
@@ -56,6 +56,33 @@
     requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
   constexpr mismatch_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
   mismatch(R1&& r1, R2&& r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {})                           // since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class T, class Proj = identity>
+    requires indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>
+    constexpr I find(I first, S last, const T& value, Proj proj = {});              // since C++20
+
+  template<input_range R, class T, class Proj = identity>
+    requires indirect_binary_predicate<ranges::equal_to, projected<iterator_t<R>, Proj>, const T*>
+    constexpr borrowed_iterator_t<R>
+      find(R&& r, const T& value, Proj proj = {});                                  // since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+           indirect_unary_predicate<projected<I, Proj>> Pred>
+    constexpr I find_if(I first, S last, Pred pred, Proj proj = {});                // since C++20
+
+  template<input_range R, class Proj = identity,
+           indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+    constexpr borrowed_iterator_t<R>
+      find_if(R&& r, Pred pred, Proj proj = {});                                    // since C++20
+
+  template<input_iterator I, sentinel_for<I> S, class Proj = identity,
+           indirect_unary_predicate<projected<I, Proj>> Pred>
+    constexpr I find_if_not(I first, S last, Pred pred, Proj proj = {});            // since C++20
+
+  template<input_range R, class Proj = identity,
+           indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
+    constexpr borrowed_iterator_t<R>
+      find_if_not(R&& r, Pred pred, Proj proj = {});                                // since C++20
 }
 
 template <class InputIterator, class Predicate>
@@ -775,6 +802,9 @@
 #include <__algorithm/pop_heap.h>
 #include <__algorithm/prev_permutation.h>
 #include <__algorithm/push_heap.h>
+#include <__algorithm/ranges_find.h>
+#include <__algorithm/ranges_find_if.h>
+#include <__algorithm/ranges_find_if_not.h>
 #include <__algorithm/ranges_max_element.h>
 #include <__algorithm/ranges_min_element.h>
 #include <__algorithm/ranges_mismatch.h>