<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 233: Insertion hints in associative containers</title>
<meta property="og:title" content="Issue 233: Insertion hints in associative containers">
<meta property="og:description" content="C++ library issue. Status: CD1">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue233.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#CD1">CD1</a> status.</em></p>
<h3 id="233"><a href="lwg-defects.html#233">233</a>. Insertion hints in associative containers</h3>
<p><b>Section:</b> 23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a> <b>Status:</b> <a href="lwg-active.html#CD1">CD1</a>
 <b>Submitter:</b> Andrew Koenig <b>Opened:</b> 2000-04-30 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="lwg-index-open.html#associative.reqmts">active issues</a> in [associative.reqmts].</p>
<p><b>View all other</b> <a href="lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#CD1">CD1</a> status.</p>
<p><b>Duplicate of:</b> <a href="lwg-closed.html#192" title="a.insert(p,t) is inefficient and overconstrained (Status: NAD)">192</a>, <a href="lwg-closed.html#246" title="a.insert(p,t) is incorrectly specified (Status: Dup)">246</a></p>
<p><b>Discussion:</b></p>
<p>
If <code>mm</code> is a multimap and <code>p</code> is an iterator
into the multimap, then <code>mm.insert(p, x)</code> inserts
<code>x</code> into <code>mm</code> with <code>p</code> as a hint as
to where it should go.  Table 69 claims that the execution time is
amortized constant if the insert winds up taking place adjacent to
<code>p</code>, but does not say when, if ever, this is guaranteed to
happen.  All it says it that <code>p</code> is a hint as to where to
insert.
</p>
<p>
The question is whether there is any guarantee about the relationship
between <code>p</code> and the insertion point, and, if so, what it
is.
</p>
<p>
I believe the present state is that there is no guarantee: The user
can supply <code>p</code>, and the implementation is allowed to
disregard it entirely.
</p>

<p><b>Additional comments from Nathan:</b><br/>

The vote [in Redmond] was on whether to elaborately specify the use of
the hint, or to require behavior only if the value could be inserted
adjacent to the hint.  I would like to ensure that we have a chance to
vote for a deterministic treatment: "before, if possible, otherwise
after, otherwise anywhere appropriate", as an alternative to the
proposed "before or after, if possible, otherwise [...]".
</p>

<p><i>[Toronto: there was general agreement that this is a real defect:
when inserting an element x into a multiset that already contains
several copies of x, there is no way to know whether the hint will be
used.  The proposed resolution was that the new element should always
be inserted as close to the hint as possible.  So, for example, if
there is a subsequence of equivalent values, then providing a.begin()
as the hint means that the new element should be inserted before the
subsequence even if a.begin() is far away.  JC van Winkel supplied
precise wording for this proposed resolution, and also for an
alternative resolution in which hints are only used when they are
adjacent to the insertion point.]</i></p>


<p><i>[Copenhagen: the LWG agreed to the original proposed resolution,
in which an insertion hint would be used even when it is far from the
insertion point.  This was contingent on seeing a example
implementation showing that it is possible to implement this
requirement without loss of efficiency.  John Potter provided such a
example implementation.]</i></p>


<p><i>[Redmond: The LWG was reluctant to adopt the proposal that
emerged from Copenhagen: it seemed excessively complicated, and went
beyond fixing the defect that we identified in Toronto.  PJP provided
the new wording described in this issue.  Nathan agrees that we
shouldn't adopt the more detailed semantics, and notes: "we know that
you can do it efficiently enough with a red-black tree, but there are
other (perhaps better) balanced tree techniques that might differ
enough to make the detailed semantics hard to satisfy."]</i></p>


<p><i>[Cura&ccedil;ao: Nathan should give us the alternative wording he
suggests so the LWG can decide between the two options.]</i></p>


<p><i>[Lillehammer: The LWG previously rejected the more detailed
  semantics, because it seemed more loike a new feature than like
  defect fixing.  We're now more sympathetic to it, but we (especially
  Bill) are still worried about performance.  N1780 describes a naive
  algorithm, but it's not clear whether there is a non-naive
  implementation. Is it possible to implement this as efficently as
  the current version of insert?]</i></p>


<p><i>[Post Lillehammer:
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">N1780</a>
updated in post meeting mailing with
feedback from Lillehammer with more information regarding performance.
]</i></p>


<p><i>[
Batavia:
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a>
accepted with minor wording changes in the proposed wording (reflected in the
proposed resolution below).  Concerns about the performance of the algorithm
were satisfactorily met by
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a>.
<a href="lwg-defects.html#371" title="Stability of multiset and multimap member functions (Status: CD1)">371</a><sup><a href="https://cplusplus.github.io/LWG/issue371" title="Latest snapshot">(i)</a></sup> already handles the stability of equal ranges
and so that part of the resolution from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a>
is no longer needed (or reflected in the proposed wording below).
]</i></p>




<p id="res-233"><b>Proposed resolution:</b></p>

<p>
Change the indicated rows of the "Associative container requirements" Table in
23.2.7 <a href="https://wg21.link/associative.reqmts">[associative.reqmts]</a> to:
</p>

<table border="1">
<caption>Associative container requirements</caption>
<tr><th>expression</th> <th>return type</th>
<th>assertion&#47;note<br/>pre&#47;post-condition</th>
<th>complexity</th></tr>
<tr><td><code>a_eq.insert(t)</code></td>
<td><code>iterator</code></td>
<td>
inserts <code>t</code> and returns the iterator pointing to the newly inserted
element. <ins>If a range containing elements equivalent to <code>t</code> exists in
<code>a_eq</code>, <code>t</code> is inserted at the end of that range.</ins>
</td>
<td>
logarithmic
</td></tr>
<tr><td><code>a.insert(p,t)</code></td>
<td><code>iterator</code></td>
<td>
inserts <code>t</code> if and only if there is no element with key equivalent to the
key of <code>t</code> in containers with unique keys; always inserts <code>t</code> in containers
with equivalent keys. always returns the iterator pointing to the element with key
equivalent to the key of <code>t</code>. <del>iterator <code>p</code> is a hint pointing to where
the insert should start to search.</del> <ins><code>t</code> is inserted as close as possible
to the position just prior to <code>p</code>.</ins>
</td>
<td>
logarithmic in general, but amortized constant if <code>t</code> is inserted right <del>after</del>
 <ins>before</ins> <code>p</code>.
</td></tr>
</table>






</body>
</html>
