Title
Inconsistency and potential infinity meta-recursion in std::chrono::zoned_time's constructors
Status
new
Section
[time.zone.zonedtime.ctor]
Submitter
Jiang An

Created on 2024-04-14.00:00:00 last changed 6 months ago

Messages

Date: 2024-06-24.12:43:36

Proposed resolution:

This wording is relative to N4971.

  1. Modify [time.zone.zonedtime.ctor] as indicated:

    [Drafting note: Add the following two paragraphs to the very beginning of subclause [time.zone.zonedtime.ctor]]

    -?- Let locatable-as-tzptr be true if given an lvalue sv of type string_view, traits::locate_zone(sv) is well-formed and TimeZonePtr is implicitly convertible from its return type, and false otherwise. Only the validity of the immediate context of the invocation and conversion is considered.

    -?- In every constructor that takes a string_view parameter name, let converted-tzptr be a variable of type TimeZonePtr that is copy-initialized from traits::locate_zone(name).

    […]

    explicit zoned_time(string_view name);
    

    -7- Constraints: traits::locate_zone(string_view{}) is a well-formed expression and zoned_time is constructible from the return type of traits::locate_zone(string_view{}) locatable-as-tzptr is true.

    -8- Effects: Initializes zone_ with traits::locate_zone(name) and default constructs tp_.

    […]

    zoned_time(string_view name, const sys_time<Duration>& st);
    

    -13- Constraints: zoned_time is constructible from the return type of traits::locate_zone(name) and stlocatable-as-tzptr is true.

    -14- Effects: Equivalent to construction with {traits::locate_zone(name)std::move(converted-tzptr), st}.

    […]

    zoned_time(string_view name, const local_time<Duration>& tp);
    

    -18- Constraints: locatable-as-tzptr is true and zoned_time is constructible from the return type of traits::locate_zone(name)TimeZonePtr and tp.

    -19- Effects: Equivalent to construction with {traits::locate_zone(name)std::move(converted-tzptr), tp}.

    […]

    zoned_time(string_view name, const local_time<Duration>& tp, choose c);
    

    -23- Constraints: locatable-as-tzptr is true and zoned_time is constructible from the return type of traits::locate_zone(name)TimeZonePtr, local_time<Duration>, and choose.

    -24- Effects: Equivalent to construction with {traits::locate_zone(name)std::move(converted-tzptr), tp, c}.

    […]

    template<class Duration2, class TimeZonePtr2>
      zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y);
    

    -32- Constraints: locatable-as-tzptr is true and zoned_time is constructible from the return type of traits::locate_zone(name)TimeZonePtr and the type zoned_time<Duration2, TimeZonePtr2>.

    -33- Effects: Equivalent to construction with {traits::locate_zone(name)std::move(converted-tzptr), y}.

    template<class Duration2, class TimeZonePtr2>
      zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y, choose c);
    

    -34- Constraints: locatable-as-tzptr is true and zoned_time is constructible from the return type of traits::locate_zone(name)TimeZonePtr, the type zoned_time<Duration2, TimeZonePtr2>, and the type choose.

    -35- Effects: Equivalent to construction with {traits::locate_zone(name)std::move(converted-tzptr), y, c}.

Date: 2024-06-15.00:00:00

[ 2024-06-24; Reflector poll ]

Set priority to 3 after reflector poll. "Such a `UserDefinedTzPtr` would be ridiculous and not useful, but it wouldn't hurt to tighten the spec a bit." "Would prefer a much simpler resolution saying 'dont do that'. I don't like that locatable-as-tzptr doesn't look like a dependent expression, but it is really. Saying '`TimeZonePtr` is implicit convertible from its return type' should be phrased in terms of converting to, and should talk about conversion from an expression to a type (see LWG 3105)."

Date: 2024-04-15.10:30:23

Currently, there are no requirements on a program-defined std::chrono::zoned_traits specialization. So a zoned_traits<UserDefinedTzPtr>::locate_zone possibly returns a string_view, which leads to infinite meta-recursion when checking the constraints of zoned_time's constructors that take a string_view.

Also, the constructor of zoned_time taking only one string_view is inconsistent with others and even self-inconsistent. For other constructors taking string_view, it is expected that the return value of locate_zone is only implicitly converted to a TimeZonePtr. But the return value is permitted to be convertible to zoned_time or sys_time<Duration> in this constructor. And given the locate_name function may be an overload set that distinguishes lvalues and rvalues of string_view, the use of locate_time(string_view{}) in the constraints doesn't always reflect locate_time(name) in the effects as the return types can be different.

History
Date User Action Args
2024-06-24 12:43:36adminsetmessages: + msg14196
2024-04-14 13:22:06adminsetmessages: + msg14060
2024-04-14 00:00:00admincreate