This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++17 status.

### 2250. Follow-up On Library Issue 2207

Section: 20.9.2.2 [bitset.cons], 20.9.2.3 [bitset.members], 21.3.3.3 [string.cons], 21.3.3.7 [string.modifiers], 21.3.3.8 [string.ops] Status: C++17 Submitter: Frank Birbacher Opened: 2013-04-18 Last modified: 2017-07-30

Priority: 3

View all other issues in [bitset.cons].

View all issues with C++17 status.

Discussion:

Similar to LWG 2207 there are several other places where the "Requires" clause precludes the "Throws" condition. Searching for the `out_of_range` exception to be thrown, the following have been found (based on the working draft N3485):

1. 20.9.2.2 [bitset.cons] p3+4

2. 20.9.2.3 [bitset.members] p13+14 (`set`)

3. 20.9.2.3 [bitset.members] p19+20 (`reset`)

4. 20.9.2.3 [bitset.members] p27+28 (`flip`)

5. 20.9.2.3 [bitset.members] p41+42 (`test`)

6. 21.3.3.3 [string.cons] p3+4

7. 21.3.3.7.2 [string.append] p3+4

8. 21.3.3.7.3 [string.assign] p4+5

9. 21.3.3.7.4 [string.insert] p1+2, p5+6, p9+10 (partially)

10. 21.3.3.7.5 [string.erase] p1+2

11. 21.3.3.7.6 [string.replace] p1+2, p5+6, p9+10 (partially)

12. 21.3.3.7.7 [string.copy] p1+2

13. 21.3.3.8.3 [string.substr] p1+2

[2013-10-15: Daniel provides wording]

In addition to the examples mentioned in the discussion, a similar defect exists for `thread`'s `join()` and `detach` functions (see 32.4.3.6 [thread.thread.member]). The suggested wording applies a similar fix for these as well.

[2015-05, Lenexa]

STL : likes it
DK : does it change behavior?
Multiple : no
Move to ready? Unanimous

Proposed resolution:

This wording is relative to N3936.

1. Modify 20.9.2.2 [bitset.cons] as indicated: [Editorial comment: The wording form used to ammend the Throws element is borrowed from a similar style used in 21.3.3.7.6 [string.replace] p10]

   >     template <class charT, class traits, class Allocator>
   >     explicit
   >     bitset(const basic_string<charT, traits, Allocator>& str,
   >            typename basic_string<charT, traits, Allocator>::size_type pos = 0,
   >            typename basic_string<charT, traits, Allocator>::size_type n =
   >              basic_string<charT, traits, Allocator>::npos,
   >              charT zero = charT('0'), charT one = charT('1'));

   > > -3- Requires: `pos <= str.size()`.

   > > -4- Throws: `out_of_range` if `pos > str.size()` or `invalid_argument` if an invalid character is found (see below).

   > > -5- Effects: Determines the effective length `rlen` of the initializing string as the smaller of `n` and `str.size() - pos`.

   > > The function then throws `invalid_argument` if any of the `rlen` characters in `str` beginning at position `pos` is other than `zero` or `one`. The function uses `traits::eq()` to compare the character values.

   > > […]

2. Modify 20.9.2.3 [bitset.members] as indicated:

   >     bitset<N>& set(size_t pos, bool val = true);

   > > -13- Requires: `pos` is valid

   > > -14- Throws: `out_of_range` if `pos` does not correspond to a valid bit position.

   > > […]

   >     bitset<N>& reset(size_t pos);

   > > -19- Requires: `pos` is valid

   > > -20- Throws: `out_of_range` if `pos` does not correspond to a valid bit position.

   > > […]

   >     bitset<N>& flip(size_t pos);

   > > -27- Requires: `pos` is valid

   > > -28- Throws: `out_of_range` if `pos` does not correspond to a valid bit position.

   > > […]

   >     bool test(size_t pos) const;

   > > -41- Requires: `pos` is valid

   > > -42- Throws: `out_of_range` if `pos` does not correspond to a valid bit position.

   > > […]

3. Modify 21.3.3.3 [string.cons] as indicated:

   >     basic_string(const basic_string& str,
   >                  size_type pos, size_type n = npos,
   >                  const Allocator& a = Allocator());

   > > -3- Requires: `pos <= str.size()`

   > > -4- Throws: `out_of_range` if `pos > str.size()`.

4. Modify 21.3.3.5 [string.capacity] as indicated:

   >     void resize(size_type n, charT c);

   > > -6- Requires: `n <= max_size()`

   > > -7- Throws: `length_error` if `n > max_size()`.

5. Modify 21.3.3.7.2 [string.append] as indicated:

   >     basic_string&
   >       append(const basic_string& str, size_type pos, size_type n = npos);

   > > -3- Requires: `pos <= str.size()`

   > > -4- Throws: `out_of_range` if `pos > str.size()`.

6. Modify 21.3.3.7.3 [string.assign] as indicated:

   >     basic_string&
   >       assign(const basic_string& str, size_type pos,
   >              size_type n = npos);

   > > -5- Requires: `pos <= str.size()`

   > > -6- Throws: `out_of_range` if `pos > str.size()`.

7. Modify 21.3.3.7.4 [string.insert] as indicated: [Editorial note: The first change suggestion is also a bug fix of the current wording, because (a) the function has parameter `pos1` but the semantics refers to `pos` and (b) it is possible that this function can throw `length_error`, see p10]

   >     basic_string&
   >       insert(size_type pos1, const basic_string& str);

   > > -1- Requires: `pos <= size()`.

   > > -2- Throws: `out_of_range` if `pos > size()`.

   > > -3- Effects: Calls Equivalent to: `return insert(pos, str.data(), str.size());`.

   > > -4- Returns: `*this`.

   >     basic_string&
   >       insert(size_type pos1, const basic_string& str,
   >              size_type pos2, size_type n = npos);

   > > -5- Requires: `pos1 <= size()` and `pos2 <= str.size()`.

   > > -6- Throws: `out_of_range` if `pos1 > size()` or `pos2 > str.size()`.

   > > […]

   >     basic_string&
   >       insert(size_type pos, const charT* s, size_type n);

   > > -9- Requires: `s` points to an array of at least `n` elements of `charT` and `pos <= size()`.

   > > -10- Throws: `out_of_range` if `pos > size()` or `length_error` if `size() + n > max_size()`.

   > > […]

   >     basic_string&
   >       insert(size_type pos, const charT* s);

   > > -13- Requires: `pos <= size()` and `s` points to an array of at least `traits::length(s) + 1` elements of `charT`.

   > > -14- Effects: Equivalent to `return insert(pos, s, traits::length(s));`.

   > > -15- Returns: `*this`.

8. Modify 21.3.3.7.5 [string.erase] as indicated:

   >     basic_string& erase(size_type pos = 0, size_type n = npos);

   > > -1- Requires: `pos <= size()`

   > > -2- Throws: `out_of_range` if `pos > size()`.

   > > […]

9. Modify 21.3.3.7.6 [string.replace] as indicated: [Editorial note: The first change suggestion is also a bug fix of the current wording, because it is possible that this function can throw `length_error`, see p10]

   >     basic_string&
   >       replace(size_type pos1, size_type n1,
   >               const basic_string& str);

   > > -1- Requires: `pos1 <= size()`.

   > > -2- Throws: `out_of_range` if `pos1 > size()`.

   > > -3- Effects: Calls Equivalent to `return replace(pos1, n1, str.data(), str.size());`.

   > > -4- Returns: `*this`.

   >     basic_string&
   >       replace(size_type pos1, size_type n1,
   >               const basic_string& str,
   >               size_type pos2, size_type n = npos);

   > > -5- Requires: `pos1 <= size()` and `pos2 <= str.size()`.

   > > -6- Throws: `out_of_range` if `pos1 > size()` or `pos2 > str.size()`.

   > > […]

   >     basic_string&
   >       replace(size_type pos1, size_type n1, const charT* s, size_type n2);

   > > -9- Requires: `pos1 <= size()` and `s` points to an array of at least `n2` elements of `charT`.

   > > -10- Throws: `out_of_range` if `pos1 > size()` or `length_error` if the length of the resulting string would exceed `max_size()` (see below).

   > > […]

   >     basic_string&
   >       replace(size_type pos, size_type n, const charT* s);

   > > -13- Requires: `pos <= size()` and `s` points to an array of at least `traits::length(s) + 1` elements of `charT`.

   > > -14- Effects: Equivalent to `return replace(pos, n, s, traits::length(s));`.

   > > -15- Returns: `*this`.

10. Modify 21.3.3.7.7 [string.copy] as indicated:

    >     size_type copy(charT* s, size_type n, size_type pos = 0) const;

    > > -1- Requires: `pos <= size()`

    > > -2- Throws: `out_of_range` if `pos > size()`.

    > > […]

11. Modify 21.3.3.8.3 [string.substr] as indicated:

    >     basic_string substr(size_type pos = 0, size_type n = npos) const;

    > > -1- Requires: `pos <= size()`

    > > -2- Throws: `out_of_range` if `pos > size()`.

    > > […]

12. Modify 32.4.3.6 [thread.thread.member] as indicated:

    >     void join();

    > > -3- Requires: `joinable()` is true.

    > > […]

    > > -7- Throws: `system_error` when an exception is required (30.2.2).

    > > -8- Error conditions:

    > > - […]

    > > - `invalid_argument` — if the thread is not joinable.

    >     void detach();

    > > -9- Requires: `joinable()` is true.

    > > […]

    > > -12- Throws: `system_error` when an exception is required (30.2.2).

    > > -13- Error conditions:

    > > - […]

    > > - `invalid_argument` — if the thread is not joinable.