This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofCD1 status.
Section: 31.8.2.5[stringbuf.virtuals]Status:CD1Submitter: Christian W BrockOpened: 2003-09-24Last modified: 2016-01-28
Priority:Not Prioritized
View otheractive issues in [stringbuf.virtuals].
View all otherissues in [stringbuf.virtuals].
View all issues withCD1 status.
Discussion:
27.7.1.3 par 8 says:
Notes: The function can make a write position available only if ( mode & ios_base::out) != 0. To make a write position available, the function reallocates (or initially allocates) an array object with a sufficient number of elements to hold the current array object (if any), plus one additional write position. If ( mode & ios_base::in) != 0, the function alters the read end pointer egptr() to point just past the new write position (as does the write end pointer epptr()).
The sentences "plus one additional write position." and especially "(as does the write end pointer epptr())" COULD by interpreted (and is interpreted by at least my library vendor) as:
post-condition: epptr() == pptr()+1
This WOULD force sputc() to call the virtual overflow() each time.
The proposed change also affects Defect Report 169.
Proposed resolution:
27.7.1.1/2 Change:
2- Notes: The function allocates no array object.
to:
2- Postcondition: str() == "".
27.7.1.1/3 Change:
-3- Effects: Constructs an object of class basic_stringbuf,initializing the base class with basic_streambuf()(lib.streambuf.cons), and initializing mode with which . Then copiesthe content of str into the basic_stringbuf underlying charactersequence and initializes the input and output sequences according towhich. If which & ios_base::out is true, initializes the outputsequence with the underlying sequence. If which & ios_base::in istrue, initializes the input sequence with the underlying sequence.
to:
-3- Effects: Constructs an object of class basic_stringbuf,initializing the base class with basic_streambuf()(lib.streambuf.cons), and initializing mode with which. Then copiesthe content of str into the basic_stringbuf underlying charactersequence. If which & ios_base::out is true, initializes the outputsequence such that pbase() points to the first underlying character,epptr() points one past the last underlying character, and if (which &ios_base::ate) is true, pptr() is set equal toepptr() else pptr() is set equal to pbase(). If which & ios_base::inis true, initializes the input sequence such that eback() and gptr()point to the first underlying character and egptr() points one pastthe last underlying character.
27.7.1.2/1 Change:
-1- Returns: A basic_string object whose content is equal to thebasic_stringbuf underlying character sequence. If the buffer is onlycreated in input mode, the underlying character sequence is equal tothe input sequence; otherwise, it is equal to the output sequence. Incase of an empty underlying character sequence, the function returnsbasic_string<charT,traits,Allocator>().
to:
-1- Returns: A basic_string object whose content is equal to thebasic_stringbuf underlying character sequence. If the basic_stringbufwas created only in input mode, the resultant basic_string containsthe character sequence in the range [eback(), egptr()). If thebasic_stringbuf was created with (which & ios_base::out) being truethen the resultant basic_string contains the character sequence in therange [pbase(), high_mark) where high_mark represents the position onepast the highest initialized character in the buffer. Characters canbe initialized either through writing to the stream, or byconstructing the basic_stringbuf with a basic_string, or by callingthe str(basic_string) member function. In the case of calling thestr(basic_string) member function, all characters initialized prior tothe call are now considered uninitialized (except for thosecharacters re-initialized by the new basic_string). Otherwise thebasic_stringbuf has been created in neither input nor output mode anda zero length basic_string is returned.
27.7.1.2/2 Change:
-2- Effects: If the basic_stringbuf's underlying character sequence isnot empty, deallocates it. Then copies the content of s into thebasic_stringbuf underlying character sequence and initializes theinput and output sequences according to the mode stored when creatingthe basic_stringbuf object. If (mode&ios_base::out) is true, theninitializes the output sequence with the underlying sequence. If(mode&ios_base::in) is true, then initializes the input sequence withthe underlying sequence.
to:
-2- Effects: Copies the content of s into the basic_stringbufunderlying character sequence. If mode & ios_base::out is true,initializes the output sequence such that pbase() points to the firstunderlying character, epptr() points one past the last underlyingcharacter, and if (mode & ios_base::ate) is true,pptr() is set equal to epptr() else pptr() is set equal to pbase(). Ifmode & ios_base::in is true, initializes the input sequence such thateback() and gptr() point to the first underlying character and egptr()points one past the last underlying character.
Remove 27.2.1.2/3. (Same rationale as issue 238: incorrect and unnecessary.)
27.7.1.3/1 Change:
1- Returns: If the input sequence has a read position available,returns traits::to_int_type(*gptr()). Otherwise, returnstraits::eof().
to:
1- Returns: If the input sequence has a read position available,returns traits::to_int_type(*gptr()). Otherwise, returnstraits::eof(). Any character in the underlying buffer which has beeninitialized is considered to be part of the input sequence.
27.7.1.3/9 Change:
-9- Notes: The function can make a write position available only if (mode & ios_base::out) != 0. To make a write position available, thefunction reallocates (or initially allocates) an array object with asufficient number of elements to hold the current array object (ifany), plus one additional write position. If ( mode & ios_base::in) !=0, the function alters the read end pointer egptr() to point just pastthe new write position (as does the write end pointer epptr()).
to:
-9- The function can make a write position available only if ( mode &ios_base::out) != 0. To make a write position available, the functionreallocates (or initially allocates) an array object with a sufficientnumber of elements to hold the current array object (if any), plus oneadditional write position. If ( mode & ios_base::in) != 0, thefunction alters the read end pointer egptr() to point just past thenew write position.
27.7.1.3/12 Change:
-12- _ If (newoff + off) < 0, or (xend - xbeg) < (newoff + off), thepositioning operation fails. Otherwise, the function assigns xbeg +newoff + off to the next pointer xnext .
to:
-12- _ If (newoff + off) < 0, or if (newoff + off) refers to anuninitialized character (as defined in 31.8.2.4[stringbuf.members]paragraph 1), the positioning operation fails. Otherwise, the functionassigns xbeg + newoff + off to the next pointer xnext .
[post-Kona: Howard provided wording. At Kona the LWG agreed that something along these lines was a good idea, but the original proposed resolution didn't say enough about the effect of various member functions on the underlying character sequences.]
Rationale:
The current basic_stringbuf description is over-constrained in sucha way as to prohibit vendors from making this the high-performancein-memory stream it was meant to be. The fundamental problem is thatthe pointers: eback(), gptr(), egptr(), pbase(), pptr(), epptr() areobservable from a derived client, and the current descriptionrestricts the range [pbase(), epptr()) from being grown geometrically.This change allows, but does not require, geometric growth of thisrange.
Backwards compatibility issues: These changes will break code thatderives from basic_stringbuf, observes epptr(), and depends upon[pbase(), epptr()) growing by one character on each call to overflow()(i.e. test suites). Otherwise there are no backwards compatibilityissues.
27.7.1.1/2: The non-normative note is non-binding, and if it werebinding, would be over specification. The recommended change focuseson the important observable fact.
27.7.1.1/3: This change does two things: 1. It describes exactlywhat must happen in terms of the sequences. The terms "inputsequence" and "output sequence" are not well defined. 2. Itintroduces a common extension: open with app or ate mode. I concurwith issue 238 that paragraph 4 is both wrong and unnecessary.
27.7.1.2/1: This change is the crux of the efficiency issue. Theresultant basic_string is not dependent upon epptr(), and thusimplementors are free to grow the underlying buffer geometricallyduring overflow() *and* place epptr() at the end of that buffer.
27.7.1.2/2: Made consistent with the proposed 27.7.1.1/3.
27.7.1.3/1: Clarifies that characters written to the stream beyondthe initially specified string are available for reading in an i/obasic_streambuf.
27.7.1.3/9: Made normative by removing "Notes:", and removed thetrailing parenthetical comment concerning epptr().
27.7.1.3/12: Restricting the positioning to [xbeg, xend) is nolonger allowable since [pbase(), epptr()) may now containuninitialized characters. Positioning is only allowable over theinitialized range.