[libcxx-commits] [libcxx] [libc++][pstl] Generic implementation of parallel std::is_sorted (PR #176129)

Michael G. Kazakov via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 15 12:03:10 PST 2026


https://github.com/mikekazakov updated https://github.com/llvm/llvm-project/pull/176129

>From c2ada3b090bd2eb7c9f8d7609ba9b18231151644 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Jan 2026 10:27:20 +0000
Subject: [PATCH 1/2] Generic implementation of parallel std::is_sorted based
 on std::transform_reduce

---
 libcxx/include/__algorithm/pstl.h             |  24 +++
 libcxx/include/__pstl/backend_fwd.h           |   6 +
 libcxx/include/__pstl/backends/default.h      |  30 +++
 .../is.sorted/pstl.is_sorted.pass.cpp         | 188 +++++++++++++++++
 .../is.sorted/pstl.is_sorted_comp.pass.cpp    | 189 ++++++++++++++++++
 5 files changed, 437 insertions(+)
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted.pass.cpp
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted_comp.pass.cpp

diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index 7169dd85df602..a79bac3200d6b 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -654,6 +654,30 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
       std::move(__op));
 }
 
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool is_sorted(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_sorted requires ForwardIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_sorted, __pstl::__current_configuration, _RawPolicy>;
+  return __pstl::__handle_exception<_Implementation>(
+      std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
+}
+
+template <class _ExecutionPolicy,
+          class _ForwardIterator,
+          class _Comp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+_LIBCPP_HIDE_FROM_ABI bool
+is_sorted(_ExecutionPolicy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Comp __comp) {
+  _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(_ForwardIterator, "is_sorted requires ForwardIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_sorted, __pstl::__current_configuration, _RawPolicy>;
+  return __pstl::__handle_exception<_Implementation>(
+      std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
+}
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif // _LIBCPP_HAS_EXPERIMENTAL_PSTL && _LIBCPP_STD_VER >= 17
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index a7d53b6a1c989..a52e6db954d0c 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -297,6 +297,12 @@ struct __reduce;
 // operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
 //                       _Tp __init, _BinaryOperation __op) const noexcept;
 
+template <class _Backend, class _ExecutionPolicy>
+struct __is_sorted;
+// template <class _Policy, class _ForwardIterator, class _Comp>
+// optional<bool>
+// operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Comp&& __comp) const noexcept;
+
 } // namespace __pstl
 _LIBCPP_END_NAMESPACE_STD
 
diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index 43b1f1ce3870a..9fa642b080f64 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -13,6 +13,7 @@
 #include <__algorithm/equal.h>
 #include <__algorithm/fill_n.h>
 #include <__algorithm/for_each_n.h>
+#include <__algorithm/is_sorted.h>
 #include <__config>
 #include <__functional/identity.h>
 #include <__functional/not_fn.h>
@@ -388,6 +389,35 @@ struct __reduce<__default_backend_tag, _ExecutionPolicy> {
   }
 };
 
+template <class _ExecutionPolicy>
+struct __is_sorted<__default_backend_tag, _ExecutionPolicy> {
+  template <class _Policy, class _ForwardIterator, class _Comp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool>
+  operator()(_Policy&& __policy, _ForwardIterator __first, _ForwardIterator __last, _Comp&& __comp) const noexcept {
+    if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
+      if (__first == __last)
+        return true; // Empty, sorted by definition
+      _ForwardIterator __first2 = __first + 1;
+      if (__first2 == __last)
+        return true; // Only one element, sorted by definition
+      --__last;
+      using _TransformReduce = __dispatch<__transform_reduce_binary, __current_configuration, _ExecutionPolicy>;
+      using _Ref             = __iterator_reference<_ForwardIterator>;
+      return _TransformReduce()(
+          __policy,
+          std::move(__first),
+          std::move(__last),
+          std::move(__first2),
+          true,
+          std::logical_and{},
+          [&](_Ref __first, _Ref __second) -> bool { return !__comp(__second, __first); });
+    } else {
+      // Currently anything outside random access iterators has to be processed serially
+      return std::is_sorted(std::move(__first), std::move(__last), std::forward<_Comp>(__comp));
+    }
+  }
+};
+
 //////////////////////////////////////////////////////////////
 // transform family
 //////////////////////////////////////////////////////////////
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted.pass.cpp
new file mode 100644
index 0000000000000..9bffa588f0858
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted.pass.cpp
@@ -0,0 +1,188 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template<class ExecutionPolicy, class ForwardIterator,
+//   bool is_sorted(ExecutionPolicy&& exec,
+//                  ForwardIterator first, ForwardIterator last);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+struct Test {
+  template <class ExecutionPolicy>
+  void operator()(ExecutionPolicy&& policy) {
+    {
+      int a[]     = {0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a)));
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+
+    {
+      int a[]     = {0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+
+    {
+      int a[]     = {0, 0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {0, 1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+    {
+      int a[]     = {1, 1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa)));
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::concatenate_t<types::forward_iterator_list<int*>,
+                                       types::bidirectional_iterator_list<int*>,
+                                       types::random_access_iterator_list<int*>>{},
+                  TestIteratorWithPolicies<Test>{});
+
+  return 0;
+}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted_comp.pass.cpp
new file mode 100644
index 0000000000000..aa57678a5ec2a
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.sort/is.sorted/pstl.is_sorted_comp.pass.cpp
@@ -0,0 +1,189 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// template<class ExecutionPolicy, class ForwardIterator, class Comp>
+//   bool is_sorted(ExecutionPolicy&& exec,
+//                  ForwardIterator first, ForwardIterator last,
+//                  Comp comp);
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+template <class Iter>
+struct Test {
+  template <class ExecutionPolicy>
+  void operator()(ExecutionPolicy&& policy) {
+    {
+      int a[]     = {0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a)));
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+
+    {
+      int a[]     = {0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+
+    {
+      int a[]     = {0, 0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {0, 1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 0, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 0, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 0, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(!std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 1, 0};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+    {
+      int a[]     = {1, 1, 1, 1};
+      unsigned sa = sizeof(a) / sizeof(a[0]);
+      assert(std::is_sorted(policy, Iter(a), Iter(a + sa), std::greater<int>()));
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::concatenate_t<types::forward_iterator_list<int*>,
+                                       types::bidirectional_iterator_list<int*>,
+                                       types::random_access_iterator_list<int*>>{},
+                  TestIteratorWithPolicies<Test>{});
+
+  return 0;
+}

>From 855fe13f22e5786ac5617260a99ea0dfbd661194 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 15 Jan 2026 20:02:53 +0000
Subject: [PATCH 2/2] Changed the arguments names to prevent shadowing

---
 libcxx/include/__pstl/backends/default.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index 9fa642b080f64..a555a3f7878a7 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -410,7 +410,7 @@ struct __is_sorted<__default_backend_tag, _ExecutionPolicy> {
           std::move(__first2),
           true,
           std::logical_and{},
-          [&](_Ref __first, _Ref __second) -> bool { return !__comp(__second, __first); });
+          [&](_Ref __left, _Ref __right) -> bool { return !__comp(__right, __left); });
     } else {
       // Currently anything outside random access iterators has to be processed serially
       return std::is_sorted(std::move(__first), std::move(__last), std::forward<_Comp>(__comp));



More information about the libcxx-commits mailing list