[libcxx-commits] [libcxx] [libc++][pstl] Implementation of parallel std::is_heap_until() based on __parallel_find() (PR #218603)

Michael G. Kazakov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 2 01:16:46 PDT 2026


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

>From 2a6ed769973f17b78e86f6f8573af5f033b22385 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Tue, 25 Aug 2026 14:00:24 +0700
Subject: [PATCH 1/5] Implementation of parallel is_heap_until

---
 libcxx/include/CMakeLists.txt                 |    1 +
 libcxx/include/__algorithm/pstl.h             |   25 +
 libcxx/include/__pstl/backend_fwd.h           |    7 +
 libcxx/include/__pstl/backends/libdispatch.h  |    5 +
 libcxx/include/__pstl/backends/serial.h       |   10 +
 libcxx/include/__pstl/backends/std_thread.h   |    5 +
 .../include/__pstl/cpu_algos/is_heap_until.h  |  101 ++
 libcxx/include/module.modulemap.in            |    3 +
 .../is.heap/pstl.is_heap_until.pass.cpp       | 1064 +++++++++++++++++
 9 files changed, 1221 insertions(+)
 create mode 100644 libcxx/include/__pstl/cpu_algos/is_heap_until.h
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index d717a7354c62b..b0c9181211f43 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -697,6 +697,7 @@ set(files
   __pstl/cpu_algos/fill.h
   __pstl/cpu_algos/find_if.h
   __pstl/cpu_algos/for_each.h
+  __pstl/cpu_algos/is_heap_until.h
   __pstl/cpu_algos/merge.h
   __pstl/cpu_algos/mismatch.h
   __pstl/cpu_algos/reverse.h
diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index a8ef6ddae9b63..79790ad429daa 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -988,6 +988,31 @@ _LIBCPP_HIDE_FROM_ABI _ForwardOutIterator transform(
       std::move(__op));
 }
 
+template <class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
+is_heap_until(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "is_heap_until requires RandomAccessIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_heap_until, __pstl::__current_configuration, _RawPolicy>;
+  return __pstl::__handle_exception<_Implementation>(
+      std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), less{});
+}
+
+template <class _ExecutionPolicy,
+          class _RandomAccessIterator,
+          class _Comp,
+          class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
+          enable_if_t<is_execution_policy_v<_RawPolicy>, int> = 0>
+[[nodiscard]] _LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
+is_heap_until(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "is_heap_until requires RandomAccessIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_heap_until, __pstl::__current_configuration, _RawPolicy>;
+  return __pstl::__handle_exception<_Implementation>(
+      std::forward<_ExecutionPolicy>(__policy), std::move(__first), std::move(__last), std::move(__comp));
+}
+
 template <class _ExecutionPolicy,
           class _ForwardIterator,
           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index 45e570c51aed9..3383ec0c0058a 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -331,6 +331,13 @@ struct __reduce;
 // operator()(_Policy&&, _ForwardIterator __first, _ForwardIterator __last,
 //                       _Tp __init, _BinaryOperation __op) const noexcept;
 
+template <class _Backend, class _ExecutionPolicy>
+struct __is_heap_until;
+// template <class _Policy, class _RandomAccessIterator, class _Comp>
+// optional<bool>
+// operator()(_Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last,
+//                                _Comp __comp) const noexcept;
+
 template <class _Backend, class _ExecutionPolicy>
 struct __is_sorted;
 // template <class _Policy, class _ForwardIterator, class _Comp>
diff --git a/libcxx/include/__pstl/backends/libdispatch.h b/libcxx/include/__pstl/backends/libdispatch.h
index c5efbd46298fb..a93f5170e427f 100644
--- a/libcxx/include/__pstl/backends/libdispatch.h
+++ b/libcxx/include/__pstl/backends/libdispatch.h
@@ -39,6 +39,7 @@
 #include <__pstl/cpu_algos/fill.h>
 #include <__pstl/cpu_algos/find_if.h>
 #include <__pstl/cpu_algos/for_each.h>
+#include <__pstl/cpu_algos/is_heap_until.h>
 #include <__pstl/cpu_algos/merge.h>
 #include <__pstl/cpu_algos/mismatch.h>
 #include <__pstl/cpu_algos/reverse.h>
@@ -370,6 +371,10 @@ template <class _ExecutionPolicy>
 struct __for_each<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_for_each<__libdispatch_backend_tag, _ExecutionPolicy> {};
 
+template <class _ExecutionPolicy>
+struct __is_heap_until<__libdispatch_backend_tag, _ExecutionPolicy>
+    : __cpu_parallel_is_heap_until<__libdispatch_backend_tag, _ExecutionPolicy> {};
+
 template <class _ExecutionPolicy>
 struct __merge<__libdispatch_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_merge<__libdispatch_backend_tag, _ExecutionPolicy> {};
diff --git a/libcxx/include/__pstl/backends/serial.h b/libcxx/include/__pstl/backends/serial.h
index c67f0b3331ac2..085bc440b5e7b 100644
--- a/libcxx/include/__pstl/backends/serial.h
+++ b/libcxx/include/__pstl/backends/serial.h
@@ -12,6 +12,7 @@
 
 #include <__algorithm/find_if.h>
 #include <__algorithm/for_each.h>
+#include <__algorithm/is_heap_until.h>
 #include <__algorithm/merge.h>
 #include <__algorithm/mismatch.h>
 #include <__algorithm/reverse.h>
@@ -88,6 +89,15 @@ struct __for_each<__serial_backend_tag, _ExecutionPolicy> {
   }
 };
 
+template <class _Backend, class _RawExecutionPolicy>
+struct __is_heap_until {
+  template <class _Policy, class _RandomAccessIterator, class _Comp>
+  _LIBCPP_HIDE_FROM_ABI optional<_RandomAccessIterator>
+  operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept {
+    return std::is_heap_until(std::move(__first), std::move(__last), std::move(__comp));
+  }
+};
+
 template <class _ExecutionPolicy>
 struct __merge<__serial_backend_tag, _ExecutionPolicy> {
   template <class _Policy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardOutIterator, class _Comp>
diff --git a/libcxx/include/__pstl/backends/std_thread.h b/libcxx/include/__pstl/backends/std_thread.h
index 06beb04e4d885..aecc6b3af2a14 100644
--- a/libcxx/include/__pstl/backends/std_thread.h
+++ b/libcxx/include/__pstl/backends/std_thread.h
@@ -18,6 +18,7 @@
 #include <__pstl/cpu_algos/fill.h>
 #include <__pstl/cpu_algos/find_if.h>
 #include <__pstl/cpu_algos/for_each.h>
+#include <__pstl/cpu_algos/is_heap_until.h>
 #include <__pstl/cpu_algos/merge.h>
 #include <__pstl/cpu_algos/mismatch.h>
 #include <__pstl/cpu_algos/reverse.h>
@@ -101,6 +102,10 @@ template <class _ExecutionPolicy>
 struct __for_each<__std_thread_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_for_each<__std_thread_backend_tag, _ExecutionPolicy> {};
 
+template <class _ExecutionPolicy>
+struct __is_heap_until<__std_thread_backend_tag, _ExecutionPolicy>
+    : __cpu_parallel_is_heap_until<__std_thread_backend_tag, _ExecutionPolicy> {};
+
 template <class _ExecutionPolicy>
 struct __merge<__std_thread_backend_tag, _ExecutionPolicy>
     : __cpu_parallel_merge<__std_thread_backend_tag, _ExecutionPolicy> {};
diff --git a/libcxx/include/__pstl/cpu_algos/is_heap_until.h b/libcxx/include/__pstl/cpu_algos/is_heap_until.h
new file mode 100644
index 0000000000000..286cab97f2c97
--- /dev/null
+++ b/libcxx/include/__pstl/cpu_algos/is_heap_until.h
@@ -0,0 +1,101 @@
+//===----------------------------------------------------------------------===//
+//
+// 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___PSTL_CPU_ALGOS_IS_HEAP_UNTIL_H
+#define _LIBCPP___PSTL_CPU_ALGOS_IS_HEAP_UNTIL_H
+
+#include <__algorithm/is_heap_until.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__optional/optional.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__pstl/cpu_algos/find_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_is_heap_until {
+  template <class _Policy, class _RandomAccessIterator, class _Comp>
+  _LIBCPP_HIDE_FROM_ABI optional<_RandomAccessIterator>
+  operator()(_Policy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) const noexcept {
+    if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy>) {
+      if (__last - __first < 2)
+        return __last; // Any sequence with less than 2 elements is a heap
+      // Run a parallel find in chunks over [first+1, last) to validate every element excepting the root.
+      return __pstl::__parallel_find<_Backend>(
+          __first + 1,
+          __last,
+          [__first, &__comp](_RandomAccessIterator __child_first, _RandomAccessIterator __child_last) {
+            using _DifferenceType = typename std::iterator_traits<_RandomAccessIterator>::difference_type;
+
+            // Derive the indices of the children and the iterators of their parents
+            _DifferenceType __child_first_idx   = __child_first - __first;
+            _DifferenceType __child_last_idx    = __child_last - __first;
+            _RandomAccessIterator __parent      = __first + (__child_first_idx - 1) / 2;
+            _RandomAccessIterator __parent_last = __first + (__child_last_idx - 1) / 2;
+
+            // If we're starting from a right child => process this element separately in a prologue
+            if (__child_first_idx % 2 == 0) {
+              if (__comp(*__parent, *__child_first)) // Check the right child
+                return __child_first;
+              ++__parent;
+              ++__child_first;
+            }
+
+            // Iterate over the parents and check their left and right children
+            for (; __parent != __parent_last; ++__parent) {
+              if (__comp(*__parent, *__child_first)) // Check the left child
+                return __child_first;
+              ++__child_first;
+
+              if (__comp(*__parent, *__child_first)) // Check the right child
+                return __child_first;
+              ++__child_first;
+            }
+
+            // If we're ending with a right child => __parent_last also includes the left child.
+            // Process this accessible element separately in an epilogue.
+            if (__child_last_idx % 2 == 0) {
+              if (__comp(*__parent, *__child_first)) // Check the left child
+                return __child_first;
+            }
+
+            return __child_last; // No violations found
+          },
+          less<>{}, // `less` here means the lowest index among the matches
+          true      // `true` here means we want the first match, not the last
+      );
+    } else {
+      return std::is_heap_until(std::move(__first), std::move(__last), std::move(__comp));
+    }
+  }
+};
+
+} // namespace __pstl
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 17
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___PSTL_CPU_ALGOS_IS_HEAP_UNTIL_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 78f4e08d9c282..463afd164cd2b 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -2435,6 +2435,9 @@ module std {
         header "__pstl/cpu_algos/for_each.h"
         export std_core.utility_core.empty
       }
+      module is_heap_until {
+        header "__pstl/cpu_algos/is_heap_until.h"
+      }
       module merge {
         header "__pstl/cpu_algos/merge.h"
       }
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until.pass.cpp
new file mode 100644
index 0000000000000..880dcce3d95d5
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until.pass.cpp
@@ -0,0 +1,1064 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <algorithm>
+
+// template<class ExecutionPolicy, class RandomAccessIterator>
+//   RandomAccessIterator
+//   is_heap_until(ExecutionPolicy&& exec,
+//                 RandomAccessIterator first, RandomAccessIterator last);
+
+#include <cstddef>
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(is_heap_until);
+
+static_assert(sfinae_test_is_heap_until<int, int*, int*>);
+static_assert(!sfinae_test_is_heap_until<std::execution::parallel_policy, int*, int*>);
+
+template <class Iter>
+struct Test {
+  template <class ExecutionPolicy>
+  void operator()(ExecutionPolicy&& policy) {
+    { // Check the return type
+      int a[]  = {0};
+      auto res = std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)));
+      static_assert(std::is_same_v<decltype(res), Iter>);
+    }
+    { // Empty
+      int a[] = {0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::begin(a))) == Iter(std::begin(a)));
+    }
+    { // Single
+      int a[] = {0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=2, heap
+      int a[] = {0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=2, not heap
+      int a[] = {0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=2, heap
+      int a[] = {1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=3, heap
+      int a[] = {1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, heap
+      int a[] = {1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=4, heap
+      int a[] = {1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, heap
+      int a[] = {1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, heap
+      int a[] = {1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::end(a)));
+    }
+    { // Break a heap at sampled locations
+      int a[1073];
+      std::iota(std::begin(a), std::end(a), 0);
+      std::make_heap(std::begin(a), std::end(a));
+      runway_sample(std::size(a), [&](size_t i) {
+        if (i == 0)
+          return;
+        int old = std::exchange(a[i], 10000);
+        assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a))) == Iter(std::begin(a) + i));
+        a[i] = old;
+      });
+    }
+    { // Check valid sub-heaps at sampled locations (to force different partitions)
+      int a[1073];
+      std::iota(std::begin(a), std::end(a), 0);
+      std::make_heap(std::begin(a), std::end(a));
+      runway_sample(std::size(a), [&](size_t i) {
+        assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::begin(a) + i)) == Iter(std::begin(a) + i));
+      });
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::random_access_iterator_list<const int*>{}, TestIteratorWithPolicies<Test>{});
+  return 0;
+}

>From 453c28bc563396f80c691b112554589191b3d765 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Wed, 26 Aug 2026 22:49:51 +0700
Subject: [PATCH 2/5] Added a test for is_heap_until() against a min heap

---
 .../is.heap/pstl.is_heap_until_comp.pass.cpp  | 1067 +++++++++++++++++
 1 file changed, 1067 insertions(+)
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp

diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp
new file mode 100644
index 0000000000000..441c96048adbf
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp
@@ -0,0 +1,1067 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++17
+
+// UNSUPPORTED: libcpp-has-no-incomplete-pstl
+
+// <algorithm>
+
+// template<class ExecutionPolicy, class RandomAccessIterator, class Compare>
+//   RandomAccessIterator
+//   is_heap_until(ExecutionPolicy&& exec,
+//                 RandomAccessIterator first, RandomAccessIterator last,
+//                 Compare comp);
+
+#include <cstddef>
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <numeric>
+
+#include "test_execution_policies.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+#include "type_algorithms.h"
+#include "runway_sample.h"
+
+EXECUTION_POLICY_SFINAE_TEST(is_heap_until);
+
+static_assert(sfinae_test_is_heap_until<int, int*, int*, bool (*)(int, int)>);
+static_assert(!sfinae_test_is_heap_until<std::execution::parallel_policy, int*, int*, bool (*)(int, int)>);
+
+template <class Iter>
+struct Test {
+  template <class ExecutionPolicy>
+  void operator()(ExecutionPolicy&& policy) {
+    std::greater<int> comp;
+    { // Check the return type
+      int a[]  = {0};
+      auto res = std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp);
+      static_assert(std::is_same_v<decltype(res), Iter>);
+    }
+    { // Empty
+      int a[] = {0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::begin(a)), comp) == Iter(std::begin(a)));
+    }
+    { // Single
+      int a[] = {0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=2, heap
+      int a[] = {0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=2, heap
+      int a[] = {0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=2, not heap
+      int a[] = {1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=3, heap
+      int a[] = {0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=4, heap
+      int a[] = {0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=4, heap
+      int a[] = {0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=5, heap
+      int a[] = {0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=5, heap
+      int a[] = {0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, heap
+      int a[] = {0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=6, heap
+      int a[] = {0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::end(a)));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 1));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 2));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 3));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 1, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 4));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 0, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 0, 1};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 5));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 1, 0};
+      assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + 6));
+    }
+    { // Break a heap at sampled locations
+      int a[1073];
+      std::iota(std::begin(a), std::end(a), 0);
+      std::make_heap(std::begin(a), std::end(a), comp);
+      runway_sample(std::size(a), [&](size_t i) {
+        if (i == 0)
+          return;
+        int old = std::exchange(a[i], -10000);
+        assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::end(a)), comp) == Iter(std::begin(a) + i));
+        a[i] = old;
+      });
+    }
+    { // Check valid sub-heaps at sampled locations (to force different partitions)
+      int a[1073];
+      std::iota(std::begin(a), std::end(a), 0);
+      std::make_heap(std::begin(a), std::end(a), comp);
+      runway_sample(std::size(a), [&](size_t i) {
+        assert(std::is_heap_until(policy, Iter(std::begin(a)), Iter(std::begin(a) + i), comp) ==
+               Iter(std::begin(a) + i));
+      });
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::random_access_iterator_list<const int*>{}, TestIteratorWithPolicies<Test>{});
+  return 0;
+}

>From 0022b84dc330546431ff33480837f3495ff57ed7 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Wed, 26 Aug 2026 23:04:48 +0700
Subject: [PATCH 3/5] Added iterators, nodiscard and exception tests

---
 .../algorithms/pstl.iterator-requirements.verify.cpp |  9 +++++++++
 .../test/libcxx/algorithms/pstl.nodiscard.verify.cpp |  4 ++++
 .../std/algorithms/pstl.exception_handling.pass.cpp  | 12 ++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
index 7e9fa5cfacc30..f4bcb34030f23 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -34,6 +34,7 @@
 
 using non_forward_iterator       = cpp17_input_iterator<int*>;
 using non_bidirectional_iterator = forward_iterator<int*>;
+using non_randomaccess_iterator  = bidirectional_iterator<int*>;
 struct non_output_iterator : forward_iterator<int*> {
   constexpr int const& operator*() const; // prevent it from being an output iterator
 };
@@ -41,6 +42,7 @@ struct non_output_iterator : forward_iterator<int*> {
 void f(non_forward_iterator non_fwd,
        non_output_iterator non_output,
        non_bidirectional_iterator non_bidir,
+       non_randomaccess_iterator non_random,
        std::execution::sequenced_policy pol) {
   auto pred     = [](auto&&...) -> bool { return true; };
   auto func     = [](auto&&...) -> int { return 1; };
@@ -146,6 +148,13 @@ void f(non_forward_iterator non_fwd,
         pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_partitioned}}
   }
 
+  {
+    (void)std::is_heap_until(
+        pol, non_random, non_random); // expected-error@*:* {{static assertion failed: is_heap_until}}
+    (void)std::is_heap_until(
+        pol, non_random, non_random, pred); // expected-error@*:* {{static assertion failed: is_heap_until}}
+  }
+
   {
     (void)std::is_sorted(pol, non_fwd, non_fwd);       // expected-error@*:* {{static assertion failed: is_sorted}}
     (void)std::is_sorted(pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_sorted}}
diff --git a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
index 61758770102f3..4dc4a221a2d10 100644
--- a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
@@ -52,6 +52,10 @@ void test() {
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::find_first_of(std::execution::par, std::begin(a), std::end(a), std::begin(b), std::end(b), pred2);
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::is_heap_until(std::execution::par, std::begin(a), std::end(a));
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
+  std::is_heap_until(std::execution::par, std::begin(a), std::end(a), pred2);
+  // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::is_partitioned(std::execution::par, std::begin(a), std::end(a), pred);
   // expected-warning at +1 {{ignoring return value of function declared with 'nodiscard' attribute}}
   std::is_sorted(std::execution::par, std::begin(a), std::end(a));
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
index b1d6d831ef61f..1d7385a155642 100644
--- a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -247,6 +247,18 @@ int main(int, char**) {
         });
       }
 
+      {
+        auto comp = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
+
+        // is_heap_until(first, last)
+        assert_non_throwing([=, &policy] { (void)std::is_heap_until(policy, std::move(first1), std::move(last1)); });
+
+        // is_heap_until(first, last, comp)
+        assert_non_throwing([=, &policy] {
+          (void)std::is_heap_until(policy, std::move(first1), std::move(last1), comp);
+        });
+      }
+
       {
         auto pred = maybe_throw(tokens[5], [](int x) -> bool { return x % 2 == 0; });
 

>From 2285ca838d36e61b791a63f0001ea479ec69a679 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Wed, 26 Aug 2026 23:15:46 +0700
Subject: [PATCH 4/5] A few more comments

---
 libcxx/include/__pstl/backends/default.h        | 4 ++++
 libcxx/include/__pstl/cpu_algos/is_heap_until.h | 5 +++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libcxx/include/__pstl/backends/default.h b/libcxx/include/__pstl/backends/default.h
index ecf5b3bc3d9eb..a54ed27c1c58f 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -60,6 +60,10 @@ namespace __pstl {
 //
 // This backend implements all the PSTL algorithms based on the following basis operations:
 //
+// is_heap_until family
+// --------------
+// No other algorithms based on is_heap_until
+//
 // find_if family
 // --------------
 // - find
diff --git a/libcxx/include/__pstl/cpu_algos/is_heap_until.h b/libcxx/include/__pstl/cpu_algos/is_heap_until.h
index 286cab97f2c97..9d881ea14cf94 100644
--- a/libcxx/include/__pstl/cpu_algos/is_heap_until.h
+++ b/libcxx/include/__pstl/cpu_algos/is_heap_until.h
@@ -12,7 +12,6 @@
 #include <__algorithm/is_heap_until.h>
 #include <__config>
 #include <__functional/operations.h>
-#include <__iterator/concepts.h>
 #include <__iterator/iterator_traits.h>
 #include <__optional/optional.h>
 #include <__pstl/backend_fwd.h>
@@ -46,6 +45,8 @@ struct __cpu_parallel_is_heap_until {
           __first + 1,
           __last,
           [__first, &__comp](_RandomAccessIterator __child_first, _RandomAccessIterator __child_last) {
+            // This algorithm assumes that __parallel_find() will never pass an empty brick,
+            // i.e. that __child_first != __child_last.
             using _DifferenceType = typename std::iterator_traits<_RandomAccessIterator>::difference_type;
 
             // Derive the indices of the children and the iterators of their parents
@@ -80,7 +81,7 @@ struct __cpu_parallel_is_heap_until {
                 return __child_first;
             }
 
-            return __child_last; // No violations found
+            return __child_last; // No violations found in this brick
           },
           less<>{}, // `less` here means the lowest index among the matches
           true      // `true` here means we want the first match, not the last

>From 9d47297e1c08c24d011e7fa2acc01317a5ba8059 Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Thu, 27 Aug 2026 00:26:02 +0700
Subject: [PATCH 5/5] Missing include

---
 .../alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp
index 441c96048adbf..186e53995e1e7 100644
--- a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_until_comp.pass.cpp
@@ -21,6 +21,7 @@
 #include <cstddef>
 #include <algorithm>
 #include <cassert>
+#include <functional>
 #include <iterator>
 #include <numeric>
 



More information about the libcxx-commits mailing list