2295. Locale name when the provided Facet is a nullptr

Section: 28.3.3.1.3 [locale.cons] Status: C++23 Submitter: Juan Soulie Opened: 2013-09-04 Last modified: 2023-11-22

Priority: 3

View all other issues in [locale.cons].

View all issues with C++23 status.

Discussion:

28.3.3.1.3 [locale.cons] p14 ends with:

"[…] If f is null, the resulting object is a copy of other."

but the next line p15 says:

"Remarks: The resulting locale has no name."

But both can't be true when other has a name and f is null.

I've tried it on two implementations (MSVC,GCC) and they are inconsistent with each other on this.

Daniel Krügler:

As currently written, the Remarks element applies unconditionally for all cases and thus should "win". The question arises whether the introduction of this element by LWG 424 had actually intended to change the previous Note to a Remarks element. In either case the wording should be improved to clarify this special case.

[2022-02-14; Daniel comments]

This issue seems to have some overlap with LWG 3676 so both should presumably be resolved in a harmonized way.

[2022-11-01; Jonathan provides wording]

This also resolves 3673 and 3676.

[2022-11-04; Jonathan revises wording after feedback]

Revert an incorrect edit to p8, which was incorrectly changed to:

"If cats is equal to locale::none, the resulting locale has the same name as locale(std_name). Otherwise, the locale has a name if and only if other has a name."

[Kona 2022-11-08; Move to Ready status]

[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Modify 28.3.3.1.3 [locale.cons] as indicated:

    explicit locale(const char* std_name);
    

    -2- Effects: Constructs a locale using standard C locale names, e.g., "POSIX". The resulting locale implements semantics defined to be associated with that name.

    -3- Throws: runtime_error if the argument is not valid, or is null.

    -4- Remarks: The set of valid string argument values is "C", "", and any implementation-defined values.

    explicit locale(const string& std_name);
    

    -5- Effects: The same asEquivalent to locale(std_name.c_str()).

    locale(const locale& other, const char* std_name, category cats);
    

    -?- Preconditions: cats is a valid category value (28.3.3.1.2.1 [locale.category]).

    -6- Effects: Constructs a locale as a copy of other except for the facets identified by the category argument, which instead implement the same semantics as locale(std_name).

    -7- Throws: runtime_error if the second argument is not valid, or is null.

    -8- Remarks: The locale has a name if and only if other has a name.

    locale(const locale& other, const string& std_name, category cats);
    

    -9- Effects: The same asEquivalent to locale(other, std_name.c_str(), cats).

    template<class Facet> locale(const locale& other, Facet* f);
    

    -10- Effects: Constructs a locale incorporating all facets from the first argument except that of type Facet, and installs the second argument as the remaining facet. If f is null, the resulting object is a copy of other.

    -11- Remarks: If f is null, the resulting locale has the same name as other. Otherwise, the The resulting locale has no name.

    locale(const locale& other, const locale& one, category cats);
    

    -?- Preconditions: cats is a valid category value.

    -12- Effects: Constructs a locale incorporating all facets from the first argument except for those that implement cats, which are instead incorporated from the second argument.

    -13- Remarks: If cats is equal to locale::none, the resulting locale has a name if and only if the first argument has a name. Otherwise, the The locale has a name if and only if the first two arguments both have names.