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

Michael G. Kazakov via libcxx-commits libcxx-commits at lists.llvm.org
Sun Sep 6 04:07:43 PDT 2026


https://github.com/mikekazakov created https://github.com/llvm/llvm-project/pull/221556

None

>From 7c11fc9c657e91cdfca1cf72311dfa2f3dc8e25b Mon Sep 17 00:00:00 2001
From: Michael Kazakov <mike.kazakov at gmail.com>
Date: Sun, 6 Sep 2026 12:04:03 +0100
Subject: [PATCH] Implementation of parallel is_heap() based on is_heap_until()

---
 libcxx/include/__algorithm/pstl.h             |   25 +
 libcxx/include/__pstl/backend_fwd.h           |    9 +-
 libcxx/include/__pstl/backends/default.h      |   16 +-
 .../pstl.iterator-requirements.verify.cpp     |    5 +
 .../algorithms/pstl.nodiscard.verify.cpp      |    4 +
 .../is.heap/pstl.is_heap.pass.cpp             | 1064 ++++++++++++++++
 .../is.heap/pstl.is_heap_comp.pass.cpp        | 1067 +++++++++++++++++
 .../is.heap/pstl.is_heap_until_comp.pass.cpp  |    4 +-
 .../pstl.exception_handling.pass.cpp          |    6 +
 9 files changed, 2196 insertions(+), 4 deletions(-)
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap.pass.cpp
 create mode 100644 libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_comp.pass.cpp

diff --git a/libcxx/include/__algorithm/pstl.h b/libcxx/include/__algorithm/pstl.h
index 14b81ed0ade4f..9b4de5de5d36f 100644
--- a/libcxx/include/__algorithm/pstl.h
+++ b/libcxx/include/__algorithm/pstl.h
@@ -1086,6 +1086,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 bool
+is_heap(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last) {
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "is_heap requires RandomAccessIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_heap, __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 bool
+is_heap(_ExecutionPolicy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp __comp) {
+  _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(_RandomAccessIterator, "is_heap requires RandomAccessIterators");
+  using _Implementation = __pstl::__dispatch<__pstl::__is_heap, __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 _RandomAccessIterator,
           class _RawPolicy                                    = __remove_cvref_t<_ExecutionPolicy>,
diff --git a/libcxx/include/__pstl/backend_fwd.h b/libcxx/include/__pstl/backend_fwd.h
index bec595449b40c..bd8ea25f4f70b 100644
--- a/libcxx/include/__pstl/backend_fwd.h
+++ b/libcxx/include/__pstl/backend_fwd.h
@@ -351,12 +351,19 @@ struct __reduce;
 //                       _Tp __init, _BinaryOperation __op) const noexcept;
 
 template <class _Backend, class _ExecutionPolicy>
-struct __is_heap_until;
+struct __is_heap;
 // 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_heap_until;
+// template <class _Policy, class _RandomAccessIterator, class _Comp>
+// optional<_RandomAccessIterator>
+// 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/default.h b/libcxx/include/__pstl/backends/default.h
index e63c3802538de..a26d29b5d81db 100644
--- a/libcxx/include/__pstl/backends/default.h
+++ b/libcxx/include/__pstl/backends/default.h
@@ -66,7 +66,7 @@ namespace __pstl {
 //
 // is_heap_until family
 // --------------
-// No other algorithms based on is_heap_until
+// - is_heap
 //
 // find_if family
 // --------------
@@ -379,6 +379,20 @@ struct __adjacent_find<__default_backend_tag, _ExecutionPolicy> {
   }
 };
 
+template <class _ExecutionPolicy>
+struct __is_heap<__default_backend_tag, _ExecutionPolicy> {
+  template <class _Policy, class _RandomAccessIterator, class _Comp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<bool> operator()(
+      _Policy&& __policy, _RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) const noexcept {
+    using _IsHeapUntil = __dispatch<__is_heap_until, __current_configuration, _ExecutionPolicy>;
+    auto __res         = _IsHeapUntil()(__policy, std::move(__first), __last, std::forward<_Comp>(__comp));
+    if (!__res) {
+      return nullopt; // Failed to run the algorithm, propagate the error.
+    }
+    return *__res == __last; // is_heap_until returns the last iterator when no heap violations are found in the range.
+  }
+};
+
 template <class _ExecutionPolicy>
 struct __is_sorted_until<__default_backend_tag, _ExecutionPolicy> {
   template <class _Policy, class _ForwardIterator, class _Comp>
diff --git a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
index d67770cedc944..5bc435dfb9103 100644
--- a/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.iterator-requirements.verify.cpp
@@ -157,6 +157,11 @@ void f(non_forward_iterator non_fwd,
         pol, non_fwd, non_fwd, pred); // expected-error@*:* {{static assertion failed: is_partitioned}}
   }
 
+  {
+    (void)std::is_heap(pol, non_random, non_random);       // expected-error@*:* {{static assertion failed: is_heap}}
+    (void)std::is_heap(pol, non_random, non_random, pred); // expected-error@*:* {{static assertion failed: is_heap}}
+  }
+
   {
     (void)std::is_heap_until(
         pol, non_random, non_random); // expected-error@*:* {{static assertion failed: is_heap_until}}
diff --git a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
index 1dbb100792d4e..55f2a1f93376e 100644
--- a/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
+++ b/libcxx/test/libcxx/algorithms/pstl.nodiscard.verify.cpp
@@ -56,6 +56,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(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(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_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);
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap.pass.cpp
new file mode 100644
index 0000000000000..246ba22dc9f0a
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap.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>
+//   bool
+//   is_heap(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);
+
+static_assert(sfinae_test_is_heap<int, int*, int*>);
+static_assert(!sfinae_test_is_heap<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(policy, Iter(std::begin(a)), Iter(std::end(a)));
+      static_assert(std::is_same_v<decltype(res), bool>);
+    }
+    { // Empty
+      int a[] = {0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::begin(a))));
+    }
+    { // Single
+      int a[] = {0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=2, heap
+      int a[] = {0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=2, not heap
+      int a[] = {0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=2, heap
+      int a[] = {1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, not heap
+      int a[] = {0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, heap
+      int a[] = {1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, heap
+      int a[] = {1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=3, heap
+      int a[] = {1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {1, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=4, heap
+      int a[] = {1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=5, heap
+      int a[] = {1, 1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 0, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=6, heap
+      int a[] = {1, 1, 1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a))));
+    }
+    { // Size=7, heap
+      int a[] = {1, 1, 1, 1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(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(policy, Iter(std::begin(a)), Iter(std::end(a))));
+        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(policy, Iter(std::begin(a)), Iter(std::begin(a) + i)));
+      });
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::random_access_iterator_list<const int*>{}, TestIteratorWithPolicies<Test>{});
+  return 0;
+}
diff --git a/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_comp.pass.cpp b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_comp.pass.cpp
new file mode 100644
index 0000000000000..425c6e44e56b3
--- /dev/null
+++ b/libcxx/test/std/algorithms/alg.sorting/alg.heap.operations/is.heap/pstl.is_heap_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>
+//   bool
+//   is_heap(ExecutionPolicy&& exec,
+//           RandomAccessIterator first, RandomAccessIterator last,
+//           Compare comp);
+
+#include <cstddef>
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#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);
+
+static_assert(sfinae_test_is_heap<int, int*, int*, bool (*)(int, int)>);
+static_assert(!sfinae_test_is_heap<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(policy, Iter(std::begin(a)), Iter(std::end(a)), comp);
+      static_assert(std::is_same_v<decltype(res), bool>);
+    }
+    { // Empty
+      int a[] = {0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::begin(a)), comp));
+    }
+    { // Single
+      int a[] = {0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=2, heap
+      int a[] = {0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=2, heap
+      int a[] = {0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=2, not heap
+      int a[] = {1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, heap
+      int a[] = {0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, heap
+      int a[] = {0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, heap
+      int a[] = {0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=3, not heap
+      int a[] = {1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, heap
+      int a[] = {0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=4, not heap
+      int a[] = {1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, heap
+      int a[] = {0, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=5, not heap
+      int a[] = {1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 0, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 1, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 1, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, heap
+      int a[] = {0, 1, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=6, not heap
+      int a[] = {1, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 0, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 0, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 0, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 1, 0, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 0, 1, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 0, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 0, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 1, 0};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 0, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {0, 1, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, heap
+      int a[] = {0, 1, 1, 1, 1, 1, 1};
+      assert(std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 0, 1, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 0, 1, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 0, 1, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 0, 1, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 0, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 0, 1};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // Size=7, not heap
+      int a[] = {1, 1, 1, 1, 1, 1, 0};
+      assert(!std::is_heap(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+    }
+    { // 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(policy, Iter(std::begin(a)), Iter(std::end(a)), comp));
+        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(policy, Iter(std::begin(a)), Iter(std::begin(a) + i), comp));
+      });
+    }
+  }
+};
+
+int main(int, char**) {
+  types::for_each(types::random_access_iterator_list<const int*>{}, TestIteratorWithPolicies<Test>{});
+  return 0;
+}
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 186e53995e1e7..170e1c3b77758 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
@@ -158,7 +158,7 @@ struct Test {
       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
+    { // Size=5, 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)));
     }
@@ -370,7 +370,7 @@ struct Test {
       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
+    { // Size=6, 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)));
     }
diff --git a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
index 6c652c8918f63..0c6da3b9a9a09 100644
--- a/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
+++ b/libcxx/test/std/algorithms/pstl.exception_handling.pass.cpp
@@ -264,6 +264,12 @@ int main(int, char**) {
       {
         auto comp = maybe_throw(tokens[5], [](int x, int y) -> bool { return x < y; });
 
+        // is_heap(first, last)
+        assert_non_throwing([=, &policy] { (void)std::is_heap(policy, std::move(first1), std::move(last1)); });
+
+        // is_heap(first, last, comp)
+        assert_non_throwing([=, &policy] { (void)std::is_heap(policy, std::move(first1), std::move(last1), comp); });
+
         // is_heap_until(first, last)
         assert_non_throwing([=, &policy] { (void)std::is_heap_until(policy, std::move(first1), std::move(last1)); });
 



More information about the libcxx-commits mailing list