| Doc. no. | N1658=04-0098 |
| Date: | 16 Jul 2004 |
| Project: | Programming Language C++ |
| Reply to: | Matt Austern <austern@apple.com> |
Reference ISO/IEC IS 14882:1998(E)
Also see:
This document contains only library issues which have been closed by the Library Working Group (LWG) after being found to be defects in the standard. That is, issues which have a status of DR, TC, or RR. See the Library Closed Issues List for issues closed as non-defects. See the Library Active Issues List for active issues and more information. The introductory material in that document also applies to this document.
Section: 17.4.2.2 [lib.using.linkage] Status: TC Submitter: Beman Dawes Date: 16 Nov 1997
The change specified in the proposed resolution below did not make it into the Standard. This change was accepted in principle at the London meeting, and the exact wording below was accepted at the Morristown meeting.
Proposed resolution:
Change 17.4.2.2 [lib.using.linkage] paragraph 2 from:
It is unspecified whether a name from the Standard C library declared with external linkage has either extern "C" or extern "C++" linkage.
to:
Whether a name from the Standard C library declared with external linkage has extern "C" or extern "C++" linkage is implementation defined. It is recommended that an implementation use extern "C++" linkage for this purpose.
Section: 18.3 [lib.support.start.term] Status: TC Submitter: Steve Clamage Date: 12 Dec 1997
We appear not to have covered all the possibilities of
exit processing with respect to
atexit registration.
Example 1: (C and C++)
#include <stdlib.h>
void f1() { }
void f2() { atexit(f1); }
int main()
{
atexit(f2); // the only use of f2
return 0; // for C compatibility
}
At program exit, f2 gets called due to its registration in main. Running f2 causes f1 to be newly registered during the exit processing. Is this a valid program? If so, what are its semantics?
Interestingly, neither the C standard, nor the C++ draft standard nor the forthcoming C9X Committee Draft says directly whether you can register a function with atexit during exit processing.
All 3 standards say that functions are run in reverse order of their registration. Since f1 is registered last, it ought to be run first, but by the time it is registered, it is too late to be first.
If the program is valid, the standards are self-contradictory about its semantics.
Example 2: (C++ only)
void F() { static T t; } // type T has a destructor
int main()
{
atexit(F); // the only use of F
}
Function F registered with atexit has a local static variable t, and F is called for the first time during exit processing. A local static object is initialized the first time control flow passes through its definition, and all static objects are destroyed during exit processing. Is the code valid? If so, what are its semantics?
Section 18.3 "Start and termination" says that if a function F is registered with atexit before a static object t is initialized, F will not be called until after t's destructor completes.
In example 2, function F is registered with atexit before its local static object O could possibly be initialized. On that basis, it must not be called by exit processing until after O's destructor completes. But the destructor cannot be run until after F is called, since otherwise the object could not be constructed in the first place.
If the program is valid, the standard is self-contradictory about its semantics.
I plan to submit Example 1 as a public comment on the C9X CD, with a recommendation that the results be undefined. (Alternative: make it unspecified. I don't think it is worthwhile to specify the case where f1 itself registers additional functions, each of which registers still more functions.)
I think we should resolve the situation in the whatever way the C committee decides.
For Example 2, I recommend we declare the results undefined.
[See reflector message lib-6500 for further discussion.]
Proposed resolution:
Change section 18.3/8 from:
First, objects with static storage duration are destroyed and functions registered by calling atexit are called. Objects with static storage duration are destroyed in the reverse order of the completion of their constructor. (Automatic objects are not destroyed as a result of calling exit().) Functions registered with atexit are called in the reverse order of their registration. A function registered with atexit before an object obj1 of static storage duration is initialized will not be called until obj1's destruction has completed. A function registered with atexit after an object obj2 of static storage duration is initialized will be called before obj2's destruction starts.
to:
First, objects with static storage duration are destroyed and functions registered by calling atexit are called. Non-local objects with static storage duration are destroyed in the reverse order of the completion of their constructor. (Automatic objects are not destroyed as a result of calling exit().) Functions registered with atexit are called in the reverse order of their registration, except that a function is called after any previously registered functions that had already been called at the time it was registered. A function registered with atexit before a non-local object obj1 of static storage duration is initialized will not be called until obj1's destruction has completed. A function registered with atexit after a non-local object obj2 of static storage duration is initialized will be called before obj2's destruction starts. A local static object obj3 is destroyed at the same time it would be if a function calling the obj3 destructor were registered with atexit at the completion of the obj3 constructor.
Rationale:
See 99-0039/N1215, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 21.3.6.8 [lib.string::compare] Status: TC Submitter: Jack Reeves Date: 11 Dec 1997
At the very end of the basic_string class definition is the signature: int compare(size_type pos1, size_type n1, const charT* s, size_type n2 = npos) const; In the following text this is defined as: returns basic_string<charT,traits,Allocator>(*this,pos1,n1).compare( basic_string<charT,traits,Allocator>(s,n2);
Since the constructor basic_string(const charT* s, size_type n, const Allocator& a = Allocator()) clearly requires that s != NULL and n < npos and further states that it throws length_error if n == npos, it appears the compare() signature above should always throw length error if invoked like so: str.compare(1, str.size()-1, s); where 's' is some null terminated character array.
This appears to be a typo since the obvious intent is to allow either the call above or something like: str.compare(1, str.size()-1, s, strlen(s)-1);
This would imply that what was really intended was two signatures int compare(size_type pos1, size_type n1, const charT* s) const int compare(size_type pos1, size_type n1, const charT* s, size_type n2) const; each defined in terms of the corresponding constructor.
Proposed resolution:
Replace the compare signature in 21.3 [lib.basic.string] (at the very end of the basic_string synopsis) which reads:
int compare(size_type pos1, size_type n1,
const charT* s, size_type n2 = npos) const;
with:
int compare(size_type pos1, size_type n1,
const charT* s) const;
int compare(size_type pos1, size_type n1,
const charT* s, size_type n2) const;
Replace the portion of 21.3.6.8 [lib.string::compare] paragraphs 5 and 6 which read:
int compare(size_type pos, size_type n1,
charT * s, size_type n2 = npos) const;
Returns:
basic_string<charT,traits,Allocator>(*this, pos, n1).compare(
basic_string<charT,traits,Allocator>( s, n2))
with:
int compare(size_type pos, size_type n1,
const charT * s) const;
Returns:
basic_string<charT,traits,Allocator>(*this, pos, n1).compare(
basic_string<charT,traits,Allocator>( s ))
int compare(size_type pos, size_type n1,
const charT * s, size_type n2) const;
Returns:
basic_string<charT,traits,Allocator>(*this, pos, n1).compare(
basic_string<charT,traits,Allocator>( s, n2))
Editors please note that in addition to splitting the signature, the third argument becomes const, matching the existing synopsis.
Rationale:
While the LWG dislikes adding signatures, this is a clear defect in the Standard which must be fixed. The same problem was also identified in issues 7 (item 5) and 87.
Section: 21 [lib.strings] Status: TC Submitter: Matt Austern Date: 15 Dec 1997
(1) In 21.3.5.4 [lib.string::insert], the description of template <class InputIterator> insert(iterator, InputIterator, InputIterator) makes no sense. It refers to a member function that doesn't exist. It also talks about the return value of a void function.
(2) Several versions of basic_string::replace don't appear in the class synopsis.
(3) basic_string::push_back appears in the synopsis, but is never described elsewhere. In the synopsis its argument is const charT, which doesn't makes much sense; it should probably be charT, or possible const charT&.
(4) basic_string::pop_back is missing.
(5) int compare(size_type pos, size_type n1, charT* s, size_type n2 = npos) make no sense. First, it's const charT* in the synopsis and charT* in the description. Second, given what it says in RETURNS, leaving out the final argument will always result in an exception getting thrown. This is paragraphs 5 and 6 of 21.3.6.8 [lib.string::compare]
(6) In table 37, in section 21.1.1 [lib.char.traits.require], there's a note for X::move(s, p, n). It says "Copies correctly even where p is in [s, s+n)". This is correct as far as it goes, but it doesn't go far enough; it should also guarantee that the copy is correct even where s in in [p, p+n). These are two orthogonal guarantees, and neither one follows from the other. Both guarantees are necessary if X::move is supposed to have the same sort of semantics as memmove (which was clearly the intent), and both guarantees are necessary if X::move is actually supposed to be useful.
Proposed resolution:
ITEM 1: In 21.3.5.4 [lib.string::insert], change paragraph 16 to
EFFECTS: Equivalent to insert(p - begin(), basic_string(first, last)).
ITEM 2: Not a defect; the Standard is clear.. There are ten versions of replace() in
the synopsis, and ten versions in 21.3.5.6 [lib.string::replace].
ITEM 3: Change the declaration of push_back in the string synopsis (21.3,
[lib.basic.string]) from:
void push_back(const charT)
to
void push_back(charT)
Add the following text immediately after 21.3.5.2 [lib.string::append], paragraph 10.
void basic_string::push_back(charT c);
EFFECTS: Equivalent to append(static_cast<size_type>(1), c);
ITEM 4: Not a defect. The omission appears to have been deliberate.
ITEM 5: Duplicate; see issue 5 (and 87).
ITEM 6: In table 37, Replace:
"Copies correctly even where p is in [s, s+n)."
with:
"Copies correctly even where the ranges [p, p+n) and [s,
s+n) overlap."
Section: 22.1.1.5 [lib.locale.statics] Status: TC Submitter: Matt Austern Date: 24 Dec 1997
It appears there's an important guarantee missing from clause 22. We're told that invoking locale::global(L) sets the C locale if L has a name. However, we're not told whether or not invoking setlocale(s) sets the global C++ locale.
The intent, I think, is that it should not, but I can't find any such words anywhere.
Proposed resolution:
Add a sentence at the end of 22.1.1.5 [lib.locale.statics], paragraph 2:
No library function other than locale::global() shall affect the value returned by locale().
Section: 18.4.1 [lib.new.delete] Status: TC Submitter: Steve Clamage Date: 4 Jan 1998
Scott Meyers, in a comp.std.c++ posting: I just noticed that section 3.7.3.1 of CD2 seems to allow for the possibility that all calls to operator new(0) yield the same pointer, an implementation technique specifically prohibited by ARM 5.3.3.Was this prohibition really lifted? Does the FDIS agree with CD2 in the regard? [Issues list maintainer's note: the IS is the same.]
Proposed resolution:
Change the last paragraph of 3.7.3 from:
Any allocation and/or deallocation functions defined in a C++ program shall conform to the semantics specified in 3.7.3.1 and 3.7.3.2.
to:
Any allocation and/or deallocation functions defined in a C++ program, including the default versions in the library, shall conform to the semantics specified in 3.7.3.1 and 3.7.3.2.
Change 3.7.3.1/2, next-to-last sentence, from :
If the size of the space requested is zero, the value returned shall not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about how it responds to or changes flags in the error status for the stream. A strict reading indicates that it ignores the bits and does not change them, which confuses users who do not expect eofbit and failbit to remain set after a successful open. There are three reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit and eofbit on call to open().
Proposed resolution:
In 27.8.1.7 [lib.ifstream.members] paragraph 3, and in 27.8.1.10 [lib.ofstream.members] paragraph 3, under open() effects, add a footnote:
A successful openlib.ifstream.membersll not be a null pointer value (4.10).
to:
Even if the size of the space requested is zero, the request can fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from any previously returned value p1, unless that value p1 was since passed to an operator delete.
5.3.4/7 currently reads:
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements. The pointer returned by the new-expression is non-null. [Note: If the library allocation function is called, the pointer returned is distinct from the pointer to any other object.]
Retain the first sentence, and delete the remainder.
18.4.1 currently has no text. Add the following:
Except where otherwise specified, the provisions of 3.7.3 apply to the library versions of operator new and operator delete.
To 18.4.1.3, add the following text:
The provisions of 3.7.3 do not apply to these reserved placement forms of operator new and operator delete.
Rationale:
See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis supporting to the proposed resolution.
Section: 23.3.5 [lib.template.bitset] Status: TC Submitter: Matt Austern Date: 22 Jan 1998
(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is not documented in 23.3.5.2.
(2) The class synopsis only gives a single signature for bitset<>::operator[], reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded on const. reference operator[](size_t pos); bool operator[](size_t pos) const.
(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should go in the Effects clause.
Proposed resolution:
ITEMS 1 AND 2:
In the bitset synopsis (23.3.5 [lib.template.bitset]),
replace the member function
reference operator[](size_t pos);
with the two member functions
bool operator[](size_t pos) const;
reference operator[](size_t pos);
Add the following text at the end of 23.3.5.2 [lib.bitset.members],
immediately after paragraph 45:
bool operator[](size_t pos) const;
Requires: pos is valid
Throws: nothing
Returns: test(pos)
bitset<N>::reference operator[](size_t pos);
Requires: pos is valid
Throws: nothing
Returns: An object of type bitset<N>::reference such that (*this)[pos] == this->test(pos), and such that (*this)[pos] = val is equivalent to this->set(pos, val);
Rationale:
The LWG believes Item 3 is not a defect. "Formatted input" implies the desired semantics. See 27.6.1.2 [lib.istream.formatted].
Section: 27.6.1.2.3 [lib.istream::extractors] Status: TC Submitter: William M. Miller Date: 3 Mar 1998
In 27.6.1.2.3, there is a reference to "eos", which is the only one in the whole draft (at least using Acrobat search), so it's undefined.
Proposed resolution:
In 27.6.1.2.3 [lib.istream::extractors], replace "eos" with "charT()"
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::combine is the only member function of locale (other than constructors and destructor) that is not const. There is no reason for it not to be const, and good reasons why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 paragraph 6: "An instance of a locale is immutable."
History: this member function originally was a constructor. it happened that the interface it specified had no corresponding language syntax, so it was changed to a member function. As constructors are never const, there was no "const" in the interface which was transformed into member "combine". It should have been added at that time, but the omission was not noticed.
Proposed resolution:
In 22.1.1 [lib.locale] and also in 22.1.1.3 [lib.locale.members], add "const" to the declaration of member combine:
template <class Facet> locale combine(const locale& other) const;
Section: 22.1.1.3 [lib.locale.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
locale::name() is described as returning a string that can be passed to a locale constructor, but there is no matching constructor.
Proposed resolution:
In 22.1.1.3 [lib.locale.members], paragraph 5, replace "locale(name())" with "locale(name().c_str())".
Section: 22.2.1.4 [lib.locale.ctype.byname.special] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The new virtual members ctype_byname<char>::do_widen and do_narrow did not get edited in properly. Instead, the member do_widen appears four times, with wrong argument lists.
Proposed resolution:
The correct declarations for the overloaded members do_narrow and do_widen should be copied from 22.2.1.3 [lib.facet.ctype.special].
Section: 22.2.2.1.2 [lib.facet.num.get.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
This section describes the process of parsing a text boolean value from the input
stream. It does not say it recognizes either of the sequences "true" or
"false" and returns the corresponding bool value; instead, it says it recognizes
only one of those sequences, and chooses which according to the received value of a
reference argument intended for returning the result, and reports an error if the other
sequence is found. (!) Furthermore, it claims to get the names from the ctype<>
facet rather than the numpunct<> facet, and it examines the "boolalpha"
flag wrongly; it doesn't define the value "loc"; and finally, it computes
wrongly whether to use numeric or "alpha" parsing.
I believe the correct algorithm is "as if":
// in, err, val, and str are arguments.
err = 0;
const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc());
const string_type t = np.truename(), f = np.falsename();
bool tm = true, fm = true;
size_t pos = 0;
while (tm && pos < t.size() || fm && pos < f.size()) {
if (in == end) { err = str.eofbit; }
bool matched = false;
if (tm && pos < t.size()) {
if (!err && t[pos] == *in) matched = true;
else tm = false;
}
if (fm && pos < f.size()) {
if (!err && f[pos] == *in) matched = true;
else fm = false;
}
if (matched) { ++in; ++pos; }
if (pos > t.size()) tm = false;
if (pos > f.size()) fm = false;
}
if (tm == fm || pos == 0) { err |= str.failbit; }
else { val = tm; }
return in;
Notice this works reasonably when the candidate strings are both empty, or equal, or when one is a substring of the other. The proposed text below captures the logic of the code above.
Proposed resolution:
In 22.2.2.1.2 [lib.facet.num.get.virtuals], in the first line of paragraph 14, change "&&" to "&".
Then, replace paragraphs 15 and 16 as follows:
Otherwise target sequences are determined "as if" by calling the members falsename() and truename() of the facet obtained by use_facet<numpunct<charT> >(str.getloc()). Successive characters in the range [in,end) (see [lib.sequence.reqmts]) are obtained and matched against corresponding positions in the target sequences only as necessary to identify a unique match. The input iterator in is compared to end only when necessary to obtain a character. If and only if a target sequence is uniquely matched, val is set to the corresponding value.
The in iterator is always left pointing one position beyond the last character successfully matched. If val is set, then err is set to str.goodbit; or to str.eofbit if, when seeking another character to match, it is found that (in==end). If val is not set, then err is set to str.failbit; or to (str.failbit|str.eofbit)if the reason for the failure was that (in==end). [Example: for targets true:"a" and false:"abb", the input sequence "a" yields val==true and err==str.eofbit; the input sequence "abc" yields err=str.failbit, with in ending at the 'c' element. For targets true:"1" and false:"0", the input sequence "1" yields val==true and err=str.goodbit. For empty targets (""), any input sequence yields err==str.failbit. --end example]
Section: 22.2.2.1.1 [lib.facet.num.get.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the list of num_get<> non-virtual members on page 22-23, the member that parses bool values was omitted from the list of definitions of non-virtual members, though it is listed in the class definition and the corresponding virtual is listed everywhere appropriate.
Proposed resolution:
Add at the beginning of 22.2.2.1.1 [lib.facet.num.get.members] another get member for bool&, copied from the entry in 22.2.2.1 [lib.locale.num.get].
Section: 22.2.1.5.2 [lib.locale.codecvt.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the definitions of codecvt<>::do_out and do_in, they are specified to return noconv if "no conversion is needed". This definition is too vague, and does not say normatively what is done with the buffers.
Proposed resolution:
Change the entry for noconv in the table under paragraph 4 in section 22.2.1.5.2 [lib.locale.codecvt.virtuals] to read:
noconv: internT and externT are the same type, and input sequence is identical to converted sequence.
Change the Note in paragraph 2 to normative text as follows:
If returns noconv, internT and externT are the same type and the converted sequence is identical to the input sequence [from,from_next). to_next is set equal to to, the value of state is unchanged, and there are no changes to the values in [to, to_limit).
Section: 22.2.3.1.2 [lib.facet.numpunct.virtuals] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The synopsis for numpunct<>::do_thousands_sep, and the definition of numpunct<>::thousands_sep which calls it, specify that it returns a value of type char_type. Here it is erroneously described as returning a "string_type".
Proposed resolution:
In 22.2.3.1.2 [lib.facet.numpunct.virtuals], above paragraph 2, change "string_type" to "char_type".
Section: 22.1.1.1.1 [lib.locale.category] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
In the second table in the section, captioned "Required instantiations", the instantiations for codecvt_byname<> have been omitted. These are necessary to allow users to construct a locale by name from facets.
Proposed resolution:
Add in 22.1.1.1.1 [lib.locale.category] to the table captioned "Required instantiations", in the category "ctype" the lines
codecvt_byname<char,char,mbstate_t>, codecvt_byname<wchar_t,char,mbstate_t>
Section: 27.8.1.7 [lib.ifstream.members] Status: TC Submitter: Nathan Myers Date: 6 Aug 1998
The description of basic_istream<>::open leaves unanswered questions about h