# 27 Algorithms library [algorithms]

## 27.8 Sorting and related operations [alg.sorting]

### 27.8.8 Heap operations [alg.heap.operations]

#### 27.8.8.1 General [alg.heap.operations.general]

A random access range [a, b) is a heap with respect to comp and proj for a comparator and projection comp and proj if its elements are organized such that:
• With N = b - a, for all i, , bool(invoke(comp, invoke(proj, a[]), invoke(​proj, a[i]))) is false.
• *a may be removed by pop_heap, or a new element added by push_heap, in time.
These properties make heaps useful as priority queues.
make_heap converts a range into a heap and sort_heap turns a heap into a sorted sequence.

#### 27.8.8.2push_heap[push.heap]

```template<class RandomAccessIterator> constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> constexpr void push_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less, class Proj = identity> requires sortable<I, Comp, Proj> constexpr I ranges::push_heap(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Comp = ranges::less, class Proj = identity> requires sortable<iterator_t<R>, Comp, Proj> constexpr borrowed_iterator_t<R> ranges::push_heap(R&& r, Comp comp = {}, Proj proj = {}); ```
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
Preconditions: The range [first, last - 1) is a valid heap with respect to comp and proj.
For the overloads in namespace std, RandomAccessIterator meets the Cpp17ValueSwappable requirements ([swappable.requirements]) and the type of *first meets the Cpp17MoveConstructible requirements (Table 31) and the Cpp17MoveAssignable requirements (Table 33).
Effects: Places the value in the location last - 1 into the resulting heap [first, last).
Returns: last for the overloads in namespace ranges.
Complexity: At most comparisons and twice as many projections.

#### 27.8.8.3pop_heap[pop.heap]

```template<class RandomAccessIterator> constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> constexpr void pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less, class Proj = identity> requires sortable<I, Comp, Proj> constexpr I ranges::pop_heap(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Comp = ranges::less, class Proj = identity> requires sortable<iterator_t<R>, Comp, Proj> constexpr borrowed_iterator_t<R> ranges::pop_heap(R&& r, Comp comp = {}, Proj proj = {}); ```
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
Preconditions: The range [first, last) is a valid non-empty heap with respect to comp and proj.
For the overloads in namespace std, RandomAccessIterator meets the Cpp17ValueSwappable requirements ([swappable.requirements]) and the type of *first meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements.
Effects: Swaps the value in the location first with the value in the location last - 1 and makes [first, last - 1) into a heap with respect to comp and proj.
Returns: last for the overloads in namespace ranges.
Complexity: At most comparisons and twice as many projections.

#### 27.8.8.4make_heap[make.heap]

```template<class RandomAccessIterator> constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> constexpr void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less, class Proj = identity> requires sortable<I, Comp, Proj> constexpr I ranges::make_heap(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Comp = ranges::less, class Proj = identity> requires sortable<iterator_t<R>, Comp, Proj> constexpr borrowed_iterator_t<R> ranges::make_heap(R&& r, Comp comp = {}, Proj proj = {}); ```
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
Preconditions: For the overloads in namespace std, RandomAccessIterator meets the Cpp17ValueSwappable requirements ([swappable.requirements]) and the type of *first meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements.
Effects: Constructs a heap with respect to comp and proj out of the range [first, last).
Returns: last for the overloads in namespace ranges.
Complexity: At most 3(last - first) comparisons and twice as many projections.

#### 27.8.8.5sort_heap[sort.heap]

```template<class RandomAccessIterator> constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> constexpr void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<random_access_iterator I, sentinel_for<I> S, class Comp = ranges::less, class Proj = identity> requires sortable<I, Comp, Proj> constexpr I ranges::sort_heap(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Comp = ranges::less, class Proj = identity> requires sortable<iterator_t<R>, Comp, Proj> constexpr borrowed_iterator_t<R> ranges::sort_heap(R&& r, Comp comp = {}, Proj proj = {}); ```
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
Preconditions: The range [first, last) is a valid heap with respect to comp and proj.
For the overloads in namespace std, RandomAccessIterator meets the Cpp17ValueSwappable requirements ([swappable.requirements]) and the type of *first meets the Cpp17MoveConstructible (Table 31) and Cpp17MoveAssignable (Table 33) requirements.
Effects: Sorts elements in the heap [first, last) with respect to comp and proj.
Returns: last for the overloads in namespace ranges.
Complexity: At most comparisons, where , and twice as many projections.

#### 27.8.8.6is_heap[is.heap]

```template<class RandomAccessIterator> constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last); ```
Effects: Equivalent to: return is_heap_until(first, last) == last;
```template<class ExecutionPolicy, class RandomAccessIterator> bool is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); ```
Effects: Equivalent to: return is_heap_until(std::forward<ExecutionPolicy>(exec), first, last) == last;
```template<class RandomAccessIterator, class Compare> constexpr bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp); ```
Effects: Equivalent to: return is_heap_until(first, last, comp) == last;
```template<class ExecutionPolicy, class RandomAccessIterator, class Compare> bool is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); ```
Effects: Equivalent to: return is_heap_until(std::forward<ExecutionPolicy>(exec), first, last, comp) == last;
```template<random_access_iterator I, sentinel_for<I> S, class Proj = identity, indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> constexpr bool ranges::is_heap(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Proj = identity, indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> constexpr bool ranges::is_heap(R&& r, Comp comp = {}, Proj proj = {}); ```
Effects: Equivalent to: return ranges​::​is_heap_until(first, last, comp, proj) == last;
```template<class RandomAccessIterator> constexpr RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last); template<class ExecutionPolicy, class RandomAccessIterator> RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); template<class RandomAccessIterator, class Compare> constexpr RandomAccessIterator is_heap_until(RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<class ExecutionPolicy, class RandomAccessIterator, class Compare> RandomAccessIterator is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); template<random_access_iterator I, sentinel_for<I> S, class Proj = identity, indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less> constexpr I ranges::is_heap_until(I first, S last, Comp comp = {}, Proj proj = {}); template<random_access_range R, class Proj = identity, indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less> constexpr borrowed_iterator_t<R> ranges::is_heap_until(R&& r, Comp comp = {}, Proj proj = {}); ```
Let comp be less{} and proj be identity{} for the overloads with no parameters by those names.
Returns: The last iterator i in [first, last] for which the range [first, i) is a heap with respect to comp and proj.
Complexity: Linear.