<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2250: Follow-up On Library Issue 2207</title>
<meta property="og:title" content="Issue 2250: Follow-up On Library Issue 2207">
<meta property="og:description" content="C++ library issue. Status: C++17">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2250.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#C++17">C++17</a> status.</em></p>
<h3 id="2250"><a href="lwg-defects.html#2250">2250</a>. Follow-up On Library Issue 2207</h3>
<p><b>Section:</b> 22.9.2.2 <a href="https://wg21.link/bitset.cons">[bitset.cons]</a>, 22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a>, 27.4.3.3 <a href="https://wg21.link/string.cons">[string.cons]</a>, 27.4.3.7 <a href="https://wg21.link/string.modifiers">[string.modifiers]</a>, 27.4.3.8 <a href="https://wg21.link/string.ops">[string.ops]</a> <b>Status:</b> <a href="lwg-active.html#C++17">C++17</a>
 <b>Submitter:</b> Frank Birbacher <b>Opened:</b> 2013-04-18 <b>Last modified:</b> 2017-07-30</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#bitset.cons">issues</a> in [bitset.cons].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++17">C++17</a> status.</p>
<p><b>Discussion:</b></p>

<p>
Similar to LWG <a href="lwg-defects.html#2207" title="basic_string::at should not have a Requires clause (Status: C++14)">2207</a><sup><a href="https://cplusplus.github.io/LWG/issue2207" title="Latest snapshot">(i)</a></sup> there are several other places where the "Requires" clause precludes the "Throws" condition. 
Searching for the <code>out_of_range</code> exception to be thrown, the following have been found (based on the working draft
N3485):
</p>

<ol>
<li><p>22.9.2.2 <a href="https://wg21.link/bitset.cons">[bitset.cons]</a> p3+4</p></li>
<li><p>22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a> p13+14 (<code>set</code>)</p></li>
<li><p>22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a> p19+20 (<code>reset</code>)</p></li>
<li><p>22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a> p27+28 (<code>flip</code>)</p></li>
<li><p>22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a> p41+42 (<code>test</code>)</p></li>
<li><p>27.4.3.3 <a href="https://wg21.link/string.cons">[string.cons]</a> p3+4</p></li>
<li><p>27.4.3.7.2 <a href="https://wg21.link/string.append">[string.append]</a> p3+4</p></li>
<li><p>27.4.3.7.3 <a href="https://wg21.link/string.assign">[string.assign]</a> p4+5</p></li>
<li><p>27.4.3.7.4 <a href="https://wg21.link/string.insert">[string.insert]</a> p1+2, p5+6, p9+10 (partially)</p></li>
<li><p>27.4.3.7.5 <a href="https://wg21.link/string.erase">[string.erase]</a> p1+2</p></li>
<li><p>27.4.3.7.6 <a href="https://wg21.link/string.replace">[string.replace]</a> p1+2, p5+6, p9+10 (partially)</p></li>
<li><p>27.4.3.7.7 <a href="https://wg21.link/string.copy">[string.copy]</a> p1+2</p></li>
<li><p>27.4.3.8.3 <a href="https://wg21.link/string.substr">[string.substr]</a> p1+2</p></li>
</ol>

<p><i>[2013-10-15: Daniel provides wording]</i></p>


<p>
In addition to the examples mentioned in the discussion, a similar defect exists for <code>thread</code>'s <code>join()</code> 
and <code>detach</code> functions (see 32.4.3.6 <a href="https://wg21.link/thread.thread.member">[thread.thread.member]</a>). The suggested wording applies a similar fix for these
as well.
</p>

<p><i>[2015-05, Lenexa]</i></p>

<p>
STL : likes it<br/>
DK : does it change behavior?<br/>
Multiple : no<br/>
Move to ready? Unanimous 
</p>


<p id="res-2250"><b>Proposed resolution:</b></p>
<p>This wording is relative to N3936.</p>

<ol>
<li><p>Modify 22.9.2.2 <a href="https://wg21.link/bitset.cons">[bitset.cons]</a> as indicated: <em>[Editorial comment: The wording form used to ammend the 
<i>Throws</i> element is borrowed from a similar style used in 27.4.3.7.6 <a href="https://wg21.link/string.replace">[string.replace]</a> p10]</em></p>

<blockquote><pre>
template &lt;class charT, class traits, class Allocator&gt;
explicit
bitset(const basic_string&lt;charT, traits, Allocator&gt;&amp; str,
       typename basic_string&lt;charT, traits, Allocator&gt;::size_type pos = 0,
       typename basic_string&lt;charT, traits, Allocator&gt;::size_type n =
         basic_string&lt;charT, traits, Allocator&gt;::npos,
         charT zero = charT('0'), charT one = charT('1'));
</pre><blockquote>
<p>
<del>-3- <i>Requires:</i> <code>pos &lt;= str.size()</code>.</del>
<p/>
-4- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; str.size()</code> <ins>or <code>invalid_argument</code> if an
invalid character is found (see below)</ins>.
<p/>
-5- <i>Effects:</i> Determines the effective length <code>rlen</code> of the initializing string as the smaller of <code>n</code> and 
<code>str.size() - pos</code>.
<p/>
The function then throws <code>invalid_argument</code> if any of the <code>rlen</code> characters in <code>str</code> beginning at position
<code>pos</code> is other than <code>zero</code> or <code>one</code>. The function uses <code>traits::eq()</code> to compare the character values.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 22.9.2.3 <a href="https://wg21.link/bitset.members">[bitset.members]</a> as indicated:</p>

<blockquote><pre>
bitset&lt;N&gt;&amp; set(size_t pos, bool val = true);
</pre><blockquote>
<p>
<del>-13- <i>Requires:</i> <code>pos</code> is valid</del>
<p/>
-14- <i>Throws:</i> <code>out_of_range</code> if <code>pos</code> does not correspond to a valid bit position.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
bitset&lt;N&gt;&amp; reset(size_t pos);
</pre><blockquote>
<p>
<del>-19- <i>Requires:</i> <code>pos</code> is valid</del>
<p/>
-20- <i>Throws:</i> <code>out_of_range</code> if <code>pos</code> does not correspond to a valid bit position.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
bitset&lt;N&gt;&amp; flip(size_t pos);
</pre><blockquote>
<p>
<del>-27- <i>Requires:</i> <code>pos</code> is valid</del>
<p/>
-28- <i>Throws:</i> <code>out_of_range</code> if <code>pos</code> does not correspond to a valid bit position.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
bool test(size_t pos) const;
</pre><blockquote>
<p>
<del>-41- <i>Requires:</i> <code>pos</code> is valid</del>
<p/>
-42- <i>Throws:</i> <code>out_of_range</code> if <code>pos</code> does not correspond to a valid bit position.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

</li>

<li><p>Modify 27.4.3.3 <a href="https://wg21.link/string.cons">[string.cons]</a> as indicated:</p>

<blockquote><pre>
basic_string(const basic_string&amp; str,
             size_type pos, size_type n = npos,
             const Allocator&amp; a = Allocator());
</pre><blockquote>
<p>
<del>-3- <i>Requires:</i> <code>pos &lt;= str.size()</code></del>
<p/>
-4- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; str.size()</code>.
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.5 <a href="https://wg21.link/string.capacity">[string.capacity]</a> as indicated:</p>

<blockquote><pre>
void resize(size_type n, charT c);
</pre><blockquote>
<p>
<del>-6- <i>Requires:</i> <code>n &lt;= max_size()</code></del>
<p/>
-7- <i>Throws:</i> <code>length_error</code> if <code>n &gt; max_size()</code>.
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.7.2 <a href="https://wg21.link/string.append">[string.append]</a> as indicated:</p>

<blockquote><pre>
basic_string&amp;
  append(const basic_string&amp; str, size_type pos, size_type n = npos);
</pre><blockquote>
<p>
<del>-3- <i>Requires:</i> <code>pos &lt;= str.size()</code></del>
<p/>
-4- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; str.size()</code>.
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.7.3 <a href="https://wg21.link/string.assign">[string.assign]</a> as indicated:</p>

<blockquote><pre>
basic_string&amp;
  assign(const basic_string&amp; str, size_type pos, 
         size_type n = npos);
</pre><blockquote>
<p>
<del>-5- <i>Requires:</i> <code>pos &lt;= str.size()</code></del>
<p/>
-6- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; str.size()</code>.
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.7.4 <a href="https://wg21.link/string.insert">[string.insert]</a> as indicated: <em>[Editorial note: The first change suggestion is also a bug fix
of the current wording, because (a) the function has parameter <code>pos1</code> but the semantics refers to <code>pos</code> and (b) 
it is possible that this function can throw <code>length_error</code>, see p10]</em></p>

<blockquote><pre>
basic_string&amp;
  insert(size_type pos<del>1</del>, const basic_string&amp; str);
</pre><blockquote>
<p>
<del>-1- <i>Requires:</i> <code>pos &lt;= size()</code>.</del>
<p/>
<del>-2- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; size()</code>.</del>
<p/>
-3- <i>Effects:</i> <del>Calls</del><ins>Equivalent to:</ins> <code><ins>return</ins> insert(pos, str.data(), str.size())<ins>;</ins></code><del>.</del>
<p/>
<del>-4- <i>Returns:</i> <code>*this</code>.</del>
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  insert(size_type pos1, const basic_string&amp; str,
         size_type pos2, size_type n = npos);
</pre><blockquote>
<p>
<del>-5- <i>Requires:</i> <code>pos1 &lt;= size()</code> and <code>pos2 &lt;= str.size()</code>.</del>
<p/>
-6- <i>Throws:</i> <code>out_of_range</code> if <code>pos1 &gt; size()</code> or <code>pos2 &gt; str.size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  insert(size_type pos, const charT* s, size_type n);
</pre><blockquote>
<p>
-9- <i>Requires:</i> <code>s</code> points to an array of at least <code>n</code> elements of <code>charT</code> <del>and 
<code>pos &lt;= size()</code></del>.
<p/>
-10- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; size()</code> or <code>length_error</code> if <code>size() + n &gt; max_size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  insert(size_type pos, const charT* s);
</pre><blockquote>
<p>
-13- <i>Requires:</i> <del><code>pos &lt;= size()</code> and</del> <code>s</code> points to an array of at least 
<code>traits::length(s) + 1</code> elements of <code>charT</code>.
<p/>
-14- <i>Effects:</i> Equivalent to <code><ins>return</ins> insert(pos, s, traits::length(s))<ins>;</ins></code><del>.</del>
<p/>
<del>-15- <i>Returns:</i> <code>*this</code>.</del>
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.7.5 <a href="https://wg21.link/string.erase">[string.erase]</a> as indicated:</p>

<blockquote><pre>
basic_string&amp; erase(size_type pos = 0, size_type n = npos);
</pre><blockquote>
<p>
<del>-1- <i>Requires:</i> <code>pos &lt;= size()</code></del>
<p/>
-2- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.7.6 <a href="https://wg21.link/string.replace">[string.replace]</a> as indicated: <em>[Editorial note: The first change suggestion is also a bug fix
of the current wording, because it is possible that this function can throw <code>length_error</code>, see p10]</em></p>

<blockquote><pre>
basic_string&amp;
  replace(size_type pos1, size_type n1,
          const basic_string&amp; str);
</pre><blockquote>
<p>
<del>-1- <i>Requires:</i> <code>pos1 &lt;= size()</code>.</del>
<p/>
<del>-2- <i>Throws:</i> <code>out_of_range</code> if <code>pos1 &gt; size()</code>.</del>
<p/>
-3- <i>Effects:</i> <del>Calls</del><ins>Equivalent to</ins> <code><ins>return</ins> replace(pos1, n1, str.data(), str.size())<ins>;</ins></code><del>.</del>
<p/>
<del>-4- <i>Returns:</i> <code>*this</code>.</del>
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  replace(size_type pos1, size_type n1,
          const basic_string&amp; str,
          size_type pos2, size_type n = npos);
</pre><blockquote>
<p>
<del>-5- <i>Requires:</i> <code>pos1 &lt;= size()</code> and <code>pos2 &lt;= str.size()</code>.</del>
<p/>
-6- <i>Throws:</i> <code>out_of_range</code> if <code>pos1 &gt; size()</code> or <code>pos2 &gt; str.size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  replace(size_type pos1, size_type n1, const charT* s, size_type n2);
</pre><blockquote>
<p>
-9- <i>Requires:</i> <del><code>pos1 &lt;= size()</code> and</del> <code>s</code> points to an array of at least <code>n2</code> elements 
of <code>charT</code>.
<p/>
-10- <i>Throws:</i> <code>out_of_range</code> if <code>pos1 &gt; size()</code> or <code>length_error</code> if the length of the resulting 
string would exceed <code>max_size()</code> (see below).
<p/>
[&hellip;]
</p>
</blockquote></blockquote>

<blockquote><pre>
basic_string&amp;
  replace(size_type pos, size_type n, const charT* s);
</pre><blockquote>
<p>
-13- <i>Requires:</i> <del><code>pos &lt;= size()</code> and</del> <code>s</code> points to an array of at least 
<code>traits::length(s) + 1</code> elements of <code>charT</code>.
<p/>
-14- <i>Effects:</i> Equivalent to <code><ins>return</ins> replace(pos, n, s, traits::length(s))<ins>;</ins></code><del>.</del>
<p/>
<del>-15- <i>Returns:</i> <code>*this</code>.</del>
</p>
</blockquote></blockquote>

</li>

<li><p>Modify 27.4.3.7.7 <a href="https://wg21.link/string.copy">[string.copy]</a> as indicated:</p>

<blockquote><pre>
size_type copy(charT* s, size_type n, size_type pos = 0) const;
</pre><blockquote>
<p>
<del>-1- <i>Requires:</i> <code>pos &lt;= size()</code></del>
<p/>
-2- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 27.4.3.8.3 <a href="https://wg21.link/string.substr">[string.substr]</a> as indicated:</p>

<blockquote><pre>
basic_string substr(size_type pos = 0, size_type n = npos) const;
</pre><blockquote>
<p>
<del>-1- <i>Requires:</i> <code>pos &lt;= size()</code></del>
<p/>
-2- <i>Throws:</i> <code>out_of_range</code> if <code>pos &gt; size()</code>.
<p/>
[&hellip;]
</p>
</blockquote></blockquote>
</li>

<li><p>Modify 32.4.3.6 <a href="https://wg21.link/thread.thread.member">[thread.thread.member]</a> as indicated:</p>

<blockquote><pre>
void join();
</pre><blockquote>
<p>
<del>-3- <i>Requires:</i> <code>joinable()</code> is true.</del>
<p/>
[&hellip;]
<p/>
-7- <i>Throws:</i> <code>system_error</code> when an exception is required (30.2.2).
<p/>
-8- <i>Error conditions:</i>
</p>
<ul>
<li><p>[&hellip;]</p></li>
<li><p><code>invalid_argument</code> &mdash; if the thread is not joinable.</p></li>
</ul>
</blockquote></blockquote>

<blockquote><pre>
void detach();
</pre><blockquote>
<p>
<del>-9- <i>Requires:</i> <code>joinable()</code> is true.</del>
<p/>
[&hellip;]
<p/>
-12- <i>Throws:</i> <code>system_error</code> when an exception is required (30.2.2).
<p/>
-13- <i>Error conditions:</i>
</p>
<ul>
<li><p>[&hellip;]</p></li>
<li><p><code>invalid_argument</code> &mdash; if the thread is not joinable.</p></li>
</ul>
</blockquote></blockquote>
</li>

</ol>





</body>
</html>
