Title
complex stream extraction underspecified
Status
new
Section
[complex.ops]
Submitter
Tim Song

Created on 2016-05-23.00:00:00 last changed 85 months ago

Messages

Date: 2017-12-16.10:24:57

Proposed resolution:

Drafting note: the following wording assumes that:
  • Characters are extracted using operator>> and compared using traits::eq.
  • Mismatched characters are not extracted.
  • x is assigned a value-initialized complex on failure for consistency with the arithmetic extractors (compare LWG 696).

This wording is relative to N4778.

  1. Replace [complex.ops]/12-16 with the following paragraphs:

    template<class T, class charT, class traits>
    basic_istream<charT, traits>&
    operator>>(basic_istream<charT, traits>& is, complex<T>& x);
    

    -?- Effects: Let PEEK(is) be a formatted input function ([istream.formatted.reqmts]) of is that returns the next character that would be extracted from is by operator>>. [Note: The sentry object is constructed and destroyed, but the returned character is not extracted from the stream. — end note]

    • If PEEK(is) is not equal to is.widen('('), extracts an object u of type T from is, and assigns complex<T>(u) to x.
    • Otherwise, extracts that character from is, then extracts an object u of type T from is, then:
      • If PEEK(is) is equal to is.widen(')'), then extracts that character from is and assigns complex<T>(u) to x.
      • Otherwise, if it is equal to is.widen(','), then extracts that character from is and then extracts an object v of type T from is, then:
        • If PEEK(is) is equal to is.widen(')'), then extracts that character from is and assigns complex<T>(u, v) to x.
        • Otherwise, the extraction fails.
      • Otherwise, the extraction fails.
    In the description above, characters are extracted from is as if by operator>> ([istream.extractors]), character equality is determined using traits::eq, and an object t of type T is extracted from is as if by is >> t.

    If any extraction operation fails, no further operation is performed and the whole extraction fails.

    On failure, assigns complex<T>() to x and calls is.setstate(ios_base::failbit) (which may throw ios::failure ([iostate.flags])).

    -?- Returns: is.

    -?- [Note: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions. — end note]

Date: 2017-12-13.00:00:00

[ 2017-12-13 Tim Song adjusts the P/R to avoid relying on putback. ]

Date: 2017-12-13.21:52:47

The specification of operator>>(istream&, complex<T>&) is extremely short on details. It currently reads, in its entirety ([complex.ops]/12-15):

template<class T, class charT, class traits>
basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, complex<T>& x);

Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part ([istream.formatted]).

Requires: The input values shall be convertible to T.

If bad input is encountered, calls is.setstate(ios_base::failbit) (which may throw ios::failure ([iostate.flags])).

Returns: is.

Remarks: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions.

It is completely unclear:

  • which "simpler extractions" are performed,
  • how the extracted characters are matched to the special characters '(', ')' and ',' (by ==, or by traits::eq),
  • what is left in the stream on failure. (For example, with "(0, 0]", libstdc++ extracts the ] while libc++ leaves it in the stream.)

Previous resolution [SUPERSEDED]:

Drafting note: the following wording is based on:
  • Characters are extracted using operator>> and compared using traits::eq.
  • Mismatched characters are returned to the stream.

This wording is relative to N4582.

  1. Replace [complex.ops]/12-15 with the following paragraphs:

    template<class T, class charT, class traits>
    basic_istream<charT, traits>&
    operator>>(basic_istream<charT, traits>& is, complex<T>& x);
    

    -?- Effects: First, extracts a character from is.

    • If the character extracted is equal to is.widen('('), extracts an object u of type T from is, then extracts a character from is.
      • If this character is equal to is.widen(')'), then assigns complex<T>(u) to x.
      • Otherwise, if this character is equal to is.widen(','), extracts an object v of type T from is, then extracts a character from is. If this character is equal to is.widen(')'), then assigns complex<T>(u, v) to x; otherwise returns the character to is and the extraction fails.
      • Otherwise, returns the character to is and the extraction fails.
    • Otherwise, returns the character to is, extracts an object u of type T from is, and assigns complex<T>(u) to x.
    In the description above, characters are extracted from is as if by operator>> ([istream.extractors]), and returned to the stream as if by basic_istream::putback ([istream.unformatted]). Character equality is determined using traits::eq. An object t of type T is extracted from is as if by is >> t.

    If any extraction operation fails, no further operation is performed and the whole extraction fails.

    On failure, calls is.setstate(ios_base::failbit) (which may throw ios::failure ([iostate.flags])).

    -?- Returns: is.

    -?- [Note: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions. — end note]

History
Date User Action Args
2017-12-13 21:52:47adminsetmessages: + msg9590
2016-05-25 19:37:55adminsetmessages: + msg8151
2016-05-23 00:00:00admincreate