Section: 28.6.6 [re.traits], 28.3.3.1.2.2 [locale.facet] Status: Open Submitter: Sergey Zubkov Opened: 2013-10-15 Last modified: 2016-02-01
Priority: 3
View all other issues in [re.traits].
View all issues with Open status.
Discussion:
28.6.6 [re.traits]/7, begins with "if typeid(use_facet<collate<charT> >) == typeid(collate_byname<charT>)
",
which appears to be pseudocode with the intention to convey that the collate facet has not been replaced by the user. Cf. the wording in
N1429 "there is no portable way to implement
transform_primary
in terms of std::locale
, since even if the sort key format returned by
std::collate_byname<>::transform
is known and can be converted into a primary sort key, the user can still
install their own custom std::collate
implementation into the locale object used, and that can use any sort key
format they see fit.".
std::collate_byname<charT>
, which is in fact true in some implementations (e.g libc++), but not others
(e.g. libstdc++). This does not follow from the description of _byname
in 28.3.3.1.2.2 [locale.facet]/4, which is only
required to provide equivalent semantics, to the named locale's facet, not to actually be one.
[2015-05-06 Lenexa: Move to Open]
MC, RP: Consequence of failing to follow the rule is UB.
MC: Tightening of requirements.
RP: It should be this way, we just didn't impose it before.
MC: Second change is a bug fix, original code didn't work.
TK: Doesn't seem to make things worse.
Bring up in larger group tomorrow.
JW arrives.
JW: libstdc++ violates this due to two std::string ABIs.
JW: This prevents installing a type derived from Facet_byname, constrains the implementor from using a smarter derived class version.
JW: Can't look at facet id to detect replacement, because replacements have the same id.
RP: Can you give it multiple ids through multiple inheritance?
JW: No, the facet mechanism wouldn't like that.
JW: We should also ask Martin Sebor, he's implemented this stuff recently.
MC: Sounds like this resolution doesn't work, need a better solution.
JW: Write in words "if the facet has not been replaced by the user", the implementation knows how to detect that, but not like this.
RP: User RE traits need to detect this too.
JW: =(
Move to Open, JW will invite Martin Sebor to join LWG for discussion.
Later ...
JW: This is not needed for user specializations after all.
MC: Agree, [re.traits]/7 only applies to the stdlib traits.
NM: Effects: doesn't make sense.
JW, NM, Martin Sebor to come up with new wording.
Proposed resolution:
This wording is relative to N3691.
Modify 28.3.3.1.2.2 [locale.facet]/4 as indicated:
For some standard facets a standard "...
_byname
" class, derived from it, implements the virtual function semanticsequivalent toprovided by that facet of the locale constructed bylocale(const char*)
with the same name. Each such facet provides a constructor that takes aconst char*
argument, which names the locale, and arefs
argument, which is passed to the base class constructor. Each such facet also provides a constructor that takes a string argumentstr
and arefs
argument, which has the same effect as calling the first constructor with the two argumentsstr.c_str()
andrefs
. If there is no "..._byname
" version of a facet, the base class implements named locale semantics itself by reference to other facets. For any localeloc
constructed bylocale(const char*)
and facetFacet
that has a corresponding standardFacet_byname
class,typeid(use_facet<Facet>(loc)) == typeid(Facet_byname)
.
Modify 28.6.6 [re.traits]/7 as indicated:
template <class ForwardIterator> string_type transform_primary(ForwardIterator first, ForwardIterator last) const;-7- Effects: if
typeid(use_facet<collate<charT> >(getloc())) == typeid(collate_byname<charT>)
and the form of the sort key returned bycollate_byname<charT>::transform(first, last)
is known and can be converted into a primary sort key then returns that key, otherwise returns an empty string.