tomaszkam / date

A date and time library based on the C++11/14/17 <chrono> header
Other
0 stars 0 forks source link

[LWG3269] Parse manipulators do not specify the result of the extraction from stream #20

Closed tomaszkam closed 5 years ago

tomaszkam commented 5 years ago

Original comment:

Add to parse manipulators:

The expression is >> parse(...) shall have type ... and value is.

tomaszkam commented 5 years ago

@HowardHinnant: Do you think these could be addressed by just adding 'and returns is' to the all Remarks clauses:

Returns: A manipulator that, when extracted from a basic_­istream<charT, traits> is, calls from_stream(is, fmt.c_­str(), tp, addressof(abbrev), &offset) and returns is.

HowardHinnant commented 5 years ago

It would be safer to mimic existing wording: http://eel.is/c++draft/std.manip#2

We need to be clear that we're returning is by lvalue-reference.

tomaszkam commented 5 years ago

Discussion: All parse manipulators for the chrono types does not specify the result of the extraction from the stream, as consequence they cannot be chained with the other read operations (at least portably). For example the following code is not required to work:

std::chrono::sys_stime s; int x;
std::cin >> std::chrono::parse("%X", s) >> x;

Drafting note: As a drive-by fix the Remarks element is also converted to a Constraints element. The wording integrates resolution for LWG 3186.

Proposed resolution: Apply following changes to [time.parse] Parsing: template<class charT, class traits, class Alloc, class Parsable> unspecified parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp);

Let is be an object of type basic_­istream<charT, traits>.

RemarksConstraints: This function shall not participate in overload resolution unlessThe expression from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp) is a valid expressionwell-formed expression when treated as an unevaluated operand.

Returns: A manipulator that, when extracted from a basic­istream<charT, traits> is,the expression is >> parse(fmt, tp) have a type basic­istream<charT, traits>&, value is, and calls from­stream(is, fmt.c­str(), tp).

template<class charT, class traits, class Alloc, class Parsable> unspecified parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp, basic_string<charT, traits, Alloc>& abbrev);

Let is be an object of type basic_­istream<charT, traits>.

RemarksConstraints: This function shall not participate in overload resolution unlessThe expression from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, addressof(abbrev)) is a valid expressionwell-formed expression when treated as an unevaluated operand.

Returns: A manipulator that, when extracted from a basic_­istream<charT, traits> is,the expression is >> parse(fmt, tp, abbrev) have a type basicistream<charT, traits>&, value is, and calls from­stream(is, fmt.c_­str(), tp, addressof(abbrev)).

template<class charT, class traits, class Alloc, class Parsable> unspecified parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp, minutes& offset);

Let is be an object of type basic_­istream<charT, traits>.

RemarksConstraints: This function shall not participate in overload resolution unlessThe expression from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, nullptrdeclval<basic_string<charT, traits, Alloc>*>(), &offset) is a valid expressionwell-formed expression when treated as an unevaluated operand.

Returns: A manipulator that, when extracted from a basic_­istream<charT, traits> is,the expression is >> parse(fmt, tp, offset) have a type basicstream<charT, traits>&, value is, and calls from­stream(is, fmt.c_­str(), tp, nullptrstatic_cast<basic_string<charT, traits, Alloc>*>(nullptr), &offset).

template<class charT, class traits, class Alloc, class Parsable> unspecified parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp, basic_string<charT, traits, Alloc>& abbrev, minutes& offset);

RemarksConstraints: This function shall not participate in overload resolution unlessThe expression from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, addressof(abbrev), &offset) is a valid expressionwell-formed expression when treated as an unevaluated operand.

Returns: A manipulator that, when extracted from a basic_­istream<charT, traits> is,the expression is >> parse(fmt, tp, abbrev, offset) have a type basic_stream<charT, traits>&, value is, and calls fromstream(is, fmt.c­str(), tp, addressof(abbrev), &offset).

HowardHinnant commented 5 years ago

Missing & on each "have a type basic_stream<charT, traits>".

tomaszkam commented 5 years ago

Thanks, updated the wording here and also in the submission.