<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3029: pop_heap over-constrains input</title>
<meta property="og:title" content="Issue 3029: pop_heap over-constrains input">
<meta property="og:description" content="C++ library issue. Status: Open">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3029.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#Open">Open</a> status.</em></p>
<h3 id="3029"><a href="lwg-active.html#3029">3029</a>. <code>pop_heap</code> over-constrains input</h3>
<p><b>Section:</b> 26.8.8.3 <a href="https://wg21.link/pop.heap">[pop.heap]</a> <b>Status:</b> <a href="lwg-active.html#Open">Open</a>
 <b>Submitter:</b> Mathias Stearn <b>Opened:</b> 2017-11-04 <b>Last modified:</b> 2020-09-06</p>
<p><b>Priority: </b>3
</p>
<p><b>View all issues with</b> <a href="lwg-status.html#Open">Open</a> status.</p>
<p><b>Discussion:</b></p>
<p>
The spec for <code>&lt;algorithms&gt;</code> <code>pop_heap</code> includes
</p>
<blockquote><p>
-1- <i>Requires:</i> The range <code>[first, last)</code> shall be a valid non-empty heap.
</p></blockquote>
<p>
This has the unfortunate consequence that to pop a value and push a new value is substantially less efficient than necessary. 
The popped value must be extracted by <code>pop_heap</code> (using up to 2 log <code><i>N</i></code> compares and swaps), and then, in 
<code>push_heap</code>, the new value must be inserted (for up to <code><i>N</i></code> compares and swaps, but more usually something 
like log <code><i>N</i></code>).
<p/>
Simply relaxing the requirement to
</p>
<blockquote><p>
-1- <i>Requires:</i> The range <code>[first, last - 1)</code> shall be a valid heap.
</p></blockquote>
<p>
enables use of <code>pop_heap</code> in an integrated push-and-pop operation, with less than half the number of expected compare 
and swap operations. Furthermore, if, as is often the case, the newly pushed value would have ended up at position <code>first</code>, 
the push/pop operation could complete in time <code>&#x1d4aa;(1)</code>, instead of (3 log <code><i>N</i></code>).
<p/>
The effect of the proposed relaxation on existing library implementations would be minimal in the extreme, and on existing user 
code nil. The base algorithm code remains exactly identical. The only changes needed would be to any instrumentation in a 
debugging version of the library, which would just need to relax its check, and to test suites that should exercise the newly 
tolerated input.
<p/>
Users today are tempted to get the improved performance by relying on existing implementations' tacit tolerance of input that 
only satisfies the proposed, relaxed requirements. In fact, the 
<a href="http://en.cppreference.com/w/cpp/algorithm/pop_heap">cppreference.com page on <code>pop_heap</code></a> offers no hint 
that this usage is not already allowed. This change would bless such reliance as formally permitted.
<p/>
After this change, minor extensions to <code>std::priority_queue</code> would enable it to take advantage of the newly efficient operation, 
perhaps:
</p>
<blockquote><pre>
void pop_push(const Type&amp;);
void pop_push(Type&amp;&amp;);
template &lt;class... Args&gt; void pop_emplace(Args&amp;&amp;... args);
</pre></blockquote>
<p>
These will appear in a formal proposal if the resolution is accepted.
</p>

<p><i>[2017-11 Albuquerque Wednesday night issues processing]</i></p>

<p>Priority set to 3</p>

<p><i>[2017-11 Albuquerque Saturday issues processing]</i></p>

<p>status to Open; Marshall to review</p>


<p id="res-3029"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4700">N4700</a>.</p>

<ol>
<li><p>Change 26.8.8.3 <a href="https://wg21.link/pop.heap">[pop.heap]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class RandomAccessIterator&gt;
  void pop_heap(RandomAccessIterator first, RandomAccessIterator last);
template&lt;class RandomAccessIterator, class Compare&gt;
  void pop_heap(RandomAccessIterator first, RandomAccessIterator last,
                Compare comp);
</pre>
<blockquote>
<p>
-1- <i>Requires:</i> The range <code>[first, last <ins>- 1</ins>)</code> shall be a valid <del>non-empty</del> heap. 
<code>RandomAccessIterator</code> shall satisfy the requirements of <code>ValueSwappable</code> (16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>). 
The type of <code>*first</code> shall satisfy the requirements of <code>MoveConstructible</code> (Table 23) and of <code>MoveAssignable</code> 
(Table 25).
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
