[libc++] Implement the underlying mechanism for range adaptors

This patch implements the underlying mechanism for range adaptors. It
does so based on http://wg21.link/p2387, even though that paper hasn't
been adopted yet. In the future, if p2387 is adopted, it would suffice
to rename `__bind_back` to `std::bind_back` and `__range_adaptor_closure`
to `std::range_adaptor_closure` to implement that paper by the spec.

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

NOKEYCHECK=True
GitOrigin-RevId: ee44dd8062a26541808fc0d3fd5c6703e19f6016
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index a757449..3189651 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -227,6 +227,7 @@
   __ranges/iota_view.h
   __ranges/join_view.h
   __ranges/non_propagating_cache.h
+  __ranges/range_adaptor.h
   __ranges/ref_view.h
   __ranges/reverse_view.h
   __ranges/take_view.h
diff --git a/include/__ranges/all.h b/include/__ranges/all.h
index f44beaa..144ecdf 100644
--- a/include/__ranges/all.h
+++ b/include/__ranges/all.h
@@ -14,6 +14,7 @@
 #include <__iterator/iterator_traits.h>
 #include <__ranges/access.h>
 #include <__ranges/concepts.h>
+#include <__ranges/range_adaptor.h>
 #include <__ranges/ref_view.h>
 #include <__ranges/subrange.h>
 #include <__utility/__decay_copy.h>
@@ -35,10 +36,10 @@
 namespace ranges::views {
 
 namespace __all {
-  struct __fn {
+  struct __fn : __range_adaptor_closure<__fn> {
     template<class _Tp>
       requires ranges::view<decay_t<_Tp>>
-    _LIBCPP_HIDE_FROM_ABI
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
     constexpr auto operator()(_Tp&& __t) const
       noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t))))
     {
@@ -48,7 +49,7 @@
     template<class _Tp>
       requires (!ranges::view<decay_t<_Tp>>) &&
                requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; }
-    _LIBCPP_HIDE_FROM_ABI
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
     constexpr auto operator()(_Tp&& __t) const
       noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)}))
     {
@@ -59,7 +60,7 @@
       requires (!ranges::view<decay_t<_Tp>> &&
                 !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } &&
                  requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; })
-    _LIBCPP_HIDE_FROM_ABI
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
     constexpr auto operator()(_Tp&& __t) const
       noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)}))
     {
diff --git a/include/__ranges/range_adaptor.h b/include/__ranges/range_adaptor.h
new file mode 100644
index 0000000..74aea31
--- /dev/null
+++ b/include/__ranges/range_adaptor.h
@@ -0,0 +1,73 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_RANGE_ADAPTOR_H
+#define _LIBCPP___RANGES_RANGE_ADAPTOR_H
+
+#include <__config>
+#include <__functional/compose.h>
+#include <__functional/invoke.h>
+#include <__ranges/concepts.h>
+#include <__utility/forward.h>
+#include <__utility/move.h>
+#include <concepts>
+#include <type_traits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_RANGES)
+
+// CRTP base that one can derive from in order to be considered a range adaptor closure
+// by the library. When deriving from this class, a pipe operator will be provided to
+// make the following hold:
+// - `x | f` is equivalent to `f(x)`
+// - `f1 | f2` is an adaptor closure `g` such that `g(x)` is equivalent to `f2(f1(x))`
+template <class _Tp>
+struct __range_adaptor_closure;
+
+// Type that wraps an arbitrary function object and makes it into a range adaptor closure,
+// i.e. something that can be called via the `x | f` notation.
+template <class _Fn>
+struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
+    constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(_VSTD::move(__f)) { }
+};
+
+template <class _Tp>
+concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>;
+
+template <class _Tp>
+struct __range_adaptor_closure {
+    template <ranges::viewable_range _View, _RangeAdaptorClosure _Closure>
+        requires same_as<_Tp, remove_cvref_t<_Closure>> &&
+                 invocable<_Closure, _View>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+    friend constexpr decltype(auto) operator|(_View&& __view, _Closure&& __closure)
+        noexcept(is_nothrow_invocable_v<_Closure, _View>)
+    { return _VSTD::invoke(_VSTD::forward<_Closure>(__closure), _VSTD::forward<_View>(__view)); }
+
+    template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
+        requires same_as<_Tp, remove_cvref_t<_Closure>> &&
+                 constructible_from<decay_t<_Closure>, _Closure> &&
+                 constructible_from<decay_t<_OtherClosure>, _OtherClosure>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+    friend constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2)
+        noexcept(is_nothrow_constructible_v<decay_t<_Closure>, _Closure> &&
+                 is_nothrow_constructible_v<decay_t<_OtherClosure>, _OtherClosure>)
+    { return __range_adaptor_closure_t(_VSTD::__compose(_VSTD::forward<_OtherClosure>(__c2), _VSTD::forward<_Closure>(__c1))); }
+};
+
+#endif // !defined(_LIBCPP_HAS_NO_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H
diff --git a/include/__ranges/transform_view.h b/include/__ranges/transform_view.h
index 9aee8fc..b892e5a 100644
--- a/include/__ranges/transform_view.h
+++ b/include/__ranges/transform_view.h
@@ -10,6 +10,7 @@
 #define _LIBCPP___RANGES_TRANSFORM_VIEW_H
 
 #include <__config>
+#include <__functional/bind_back.h>
 #include <__functional/invoke.h>
 #include <__iterator/concepts.h>
 #include <__iterator/iter_swap.h>
@@ -20,8 +21,10 @@
 #include <__ranges/concepts.h>
 #include <__ranges/copyable_box.h>
 #include <__ranges/empty.h>
+#include <__ranges/range_adaptor.h>
 #include <__ranges/size.h>
 #include <__ranges/view_interface.h>
+#include <__utility/forward.h>
 #include <__utility/in_place.h>
 #include <__utility/move.h>
 #include <concepts>
@@ -401,6 +404,30 @@
   }
 };
 
+namespace views {
+namespace __transform {
+  struct __fn {
+    template<class _Range, class _Fn>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+    constexpr auto operator()(_Range&& __range, _Fn&& __f) const
+      noexcept(noexcept(transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f))))
+      -> decltype(      transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f)))
+      { return          transform_view(_VSTD::forward<_Range>(__range), _VSTD::forward<_Fn>(__f)); }
+
+    template<class _Fn>
+      requires constructible_from<decay_t<_Fn>, _Fn>
+    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+    constexpr auto operator()(_Fn&& __f) const
+      noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>)
+    { return __range_adaptor_closure_t(_VSTD::__bind_back(*this, _VSTD::forward<_Fn>(__f))); }
+  };
+}
+
+inline namespace __cpo {
+  inline constexpr auto transform = __transform::__fn{};
+}
+} // namespace views
+
 } // namespace ranges
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
diff --git a/include/module.modulemap b/include/module.modulemap
index 98ba8d3..b6a39a0 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -647,7 +647,11 @@
 
     module __ranges {
       module access                 { private header "__ranges/access.h"                }
-      module all                    { private header "__ranges/all.h"                   }
+      module all                    {
+        private header "__ranges/all.h"
+        export functional.__functional.compose
+        export functional.__functional.perfect_forward
+      }
       module common_view            { private header "__ranges/common_view.h"           }
       module concepts               { private header "__ranges/concepts.h"              }
       module copyable_box           { private header "__ranges/copyable_box.h"          }
@@ -662,13 +666,18 @@
       module iota_view              { private header "__ranges/iota_view.h"             }
       module join_view              { private header "__ranges/join_view.h"             }
       module non_propagating_cache  { private header "__ranges/non_propagating_cache.h" }
+      module range_adaptor          { private header "__ranges/range_adaptor.h"         }
       module ref_view               { private header "__ranges/ref_view.h"              }
       module reverse_view           { private header "__ranges/reverse_view.h"          }
       module size                   { private header "__ranges/size.h"                  }
       module single_view            { private header "__ranges/single_view.h"           }
       module subrange               { private header "__ranges/subrange.h"              }
       module take_view              { private header "__ranges/take_view.h"             }
-      module transform_view         { private header "__ranges/transform_view.h"        }
+      module transform_view         {
+        private header "__ranges/transform_view.h"
+        export functional.__functional.bind_back
+        export functional.__functional.perfect_forward
+      }
       module view_interface         { private header "__ranges/view_interface.h"        }
     }
   }