From 62d142755001f115ab43822892a2fd92696719de Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sun, 24 Mar 2024 09:04:39 +0900 Subject: [PATCH 1/6] P2867R2 Remove deprecated strstreams from C++26 As no other polls for Tokyo touch the table of library headers, I rebalanced the table columns. Slight tweak to Annex C drafting when importing header units to be consistent with previous wording --- the intent in LWG was to match precedent. --- source/compatibility.tex | 19 + source/future.tex | 1024 -------------------------------------- source/lib-intro.tex | 26 +- source/xrefdelta.tex | 22 + 4 files changed, 58 insertions(+), 1033 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index ccb63c3d6b..eb13565fc3 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -190,6 +190,25 @@ \item \tcode{little_endian}. \end{itemize} +\nodiffref +\change +Remove header \libnoheader{strstream} and all its contents. +\rationale +The header has been deprecated since the original \Cpp{} standard; the +\libheader{spanstream} header provides an updated, safer facility. +Ongoing support is at implementer's discretion, +exercising freedoms granted by \ref{zombie.names}. +\effect +A valid \CppXXIII{} program \tcode{\#include}-ing the header or importing the +header unit may become ill-formed. Code that uses any of the following classes +by importing one of the standard library modules may become ill-formed: +\begin{itemize} +\item \tcode{istrstream} +\item \tcode{ostrstream} +\item \tcode{strstream} +\item \tcode{strstreambuf} +\end{itemize} + \rSec1[diff.cpp20]{\Cpp{} and ISO \CppXX{}} \rSec2[diff.cpp20.general]{General} diff --git a/source/future.tex b/source/future.tex index 34173964ff..1a44162f3d 100644 --- a/source/future.tex +++ b/source/future.tex @@ -323,1030 +323,6 @@ \tcode{!(x < y)}. \end{itemdescr} -\rSec1[depr.str.strstreams]{\tcode{char*} streams} - -\rSec2[depr.strstream.syn]{Header \tcode{} synopsis} - -\pnum -The header \libheaderdef{strstream} -defines types that associate stream buffers with -character array objects and assist reading and writing such objects. - -\begin{codeblock} -namespace std { - class strstreambuf; - class istrstream; - class ostrstream; - class strstream; -} -\end{codeblock} - -\rSec2[depr.strstreambuf]{Class \tcode{strstreambuf}} - -\rSec3[depr.strstreambuf.general]{General} - -\indexlibraryglobal{strstreambuf}% -\begin{codeblock} -namespace std { - class strstreambuf : public basic_streambuf { - public: - strstreambuf() : strstreambuf(0) {} - explicit strstreambuf(streamsize alsize_arg); - strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); - strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = nullptr); - strstreambuf(const char* gnext_arg, streamsize n); - - strstreambuf(signed char* gnext_arg, streamsize n, - signed char* pbeg_arg = nullptr); - strstreambuf(const signed char* gnext_arg, streamsize n); - strstreambuf(unsigned char* gnext_arg, streamsize n, - unsigned char* pbeg_arg = nullptr); - strstreambuf(const unsigned char* gnext_arg, streamsize n); - - virtual ~strstreambuf(); - - void freeze(bool freezefl = true); - char* str(); - int pcount(); - - protected: - int_type overflow (int_type c = EOF) override; - int_type pbackfail(int_type c = EOF) override; - int_type underflow() override; - pos_type seekoff(off_type off, ios_base::seekdir way, - ios_base::openmode which = ios_base::in | ios_base::out) override; - pos_type seekpos(pos_type sp, - ios_base::openmode which = ios_base::in | ios_base::out) override; - streambuf* setbuf(char* s, streamsize n) override; - - private: - using strstate = T1; // \expos - static const strstate allocated; // \expos - static const strstate constant; // \expos - static const strstate dynamic; // \expos - static const strstate frozen; // \expos - strstate strmode; // \expos - streamsize alsize; // \expos - void* (*palloc)(size_t); // \expos - void (*pfree)(void*); // \expos - }; -} -\end{codeblock} - -\pnum -The class -\tcode{strstreambuf} -associates the input sequence, and possibly the output sequence, with an object of some -\textit{character} -array type, whose elements store arbitrary values. -The array object has several attributes. - -\pnum -\begin{note} -For the sake of exposition, these are represented as elements of a bitmask type -(indicated here as \tcode{T1}) called \tcode{strstate}. -The elements are: -\begin{itemize} -\item -\tcode{allocated}, set when a dynamic array object has been -allocated, and hence will be freed by the destructor for the -\tcode{strstreambuf} object; -\item -\tcode{constant}, set when the array object has -\keyword{const} elements, so the output sequence cannot be written; -\item -\tcode{dynamic}, set when the array object is allocated -(or reallocated) -as necessary to hold a character sequence that can change in length; -\item -\tcode{frozen}, set when the program has requested that the -array object not be altered, reallocated, or freed. -\end{itemize} -\end{note} - -\pnum -\begin{note} -For the sake of exposition, the maintained data is presented here as: -\begin{itemize} -\item -\tcode{strstate strmode}, the attributes of the array object -associated with the \tcode{strstreambuf} object; -\item -\tcode{int alsize}, the suggested minimum size for a -dynamic array object; -\item -\tcode{void* (*palloc)(size_t)}, points to the function -to call to allocate a dynamic array object; -\item -\tcode{void (*pfree)(void*)}, points to the function to -call to free a dynamic array object. -\end{itemize} -\end{note} - -\pnum -Each object of class -\tcode{strstreambuf} -has a -\term{seekable area}, -delimited by the pointers \tcode{seeklow} and \tcode{seekhigh}. -If \tcode{gnext} is a null pointer, the seekable area is undefined. -Otherwise, \tcode{seeklow} equals \tcode{gbeg} and -\tcode{seekhigh} is either \tcode{pend}, -if \tcode{pend} is not a null pointer, or \tcode{gend}. - -\rSec3[depr.strstreambuf.cons]{\tcode{strstreambuf} constructors} - -\indexlibraryctor{strstreambuf}% -\begin{itemdecl} -explicit strstreambuf(streamsize alsize_arg); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{streambuf()}. -The postconditions of this function are indicated in \tref{depr.strstreambuf.cons.sz}. -\end{itemdescr} - -\begin{libtab2}{\tcode{strstreambuf(streamsize)} effects}{depr.strstreambuf.cons.sz} -{ll} -{Element}{Value} -\tcode{strmode} & \tcode{dynamic} \\ -\tcode{alsize} & \tcode{alsize_arg} \\ -\tcode{palloc} & a null pointer \\ -\tcode{pfree} & a null pointer \\ -\end{libtab2} - -\indexlibraryctor{strstreambuf}% -\begin{itemdecl} -strstreambuf(void* (*palloc_arg)(size_t), void (*pfree_arg)(void*)); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{streambuf()}. -The postconditions of this function are indicated in \tref{depr.strstreambuf.cons.alloc}. - -\begin{libtab2}{\tcode{strstreambuf(void* (*)(size_t), void (*)(void*))} effects} -{depr.strstreambuf.cons.alloc} -{ll} -{Element}{Value} -\tcode{strmode} & \tcode{dynamic} \\ -\tcode{alsize} & an unspecified value \\ -\tcode{palloc} & \tcode{palloc_arg} \\ -\tcode{pfree} & \tcode{pfree_arg} \\ -\end{libtab2} -\end{itemdescr} - -\indextext{unspecified}% -\indexlibraryctor{strstreambuf}% -\begin{itemdecl} -strstreambuf(char* gnext_arg, streamsize n, char* pbeg_arg = nullptr); -strstreambuf(signed char* gnext_arg, streamsize n, - signed char* pbeg_arg = nullptr); -strstreambuf(unsigned char* gnext_arg, streamsize n, - unsigned char* pbeg_arg = nullptr); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{streambuf()}. -The postconditions of this function are indicated in \tref{depr.strstreambuf.cons.ptr}. - -\begin{libtab2}{\tcode{strstreambuf(charT*, streamsize, charT*)} effects} -{depr.strstreambuf.cons.ptr} -{ll} -{Element}{Value} -\tcode{strmode} & 0 \\ -\tcode{alsize} & an unspecified value \\ -\tcode{palloc} & a null pointer \\ -\tcode{pfree} & a null pointer \\ -\end{libtab2} - -\pnum -\tcode{gnext_arg} shall point to the first element of an array -object whose number of elements \tcode{N} is determined as follows: -\begin{itemize} -\item -If -\tcode{n > 0}, -\tcode{N} is \tcode{n}. -\item -If -\tcode{n == 0}, -\tcode{N} is -\tcode{std::strlen(gnext_arg)}. -\indexlibraryglobal{strlen}% -\item -If -\tcode{n < 0}, -\tcode{N} is -\tcode{INT_MAX}. -\begin{footnote} -The function signature -\indexlibraryglobal{strlen}% -\tcode{strlen(const char*)} -is declared in \libheaderref{cstring}. -The macro \tcode{INT_MAX} is defined in \libheaderref{climits}. -\end{footnote} -\end{itemize} - -\pnum -If \tcode{pbeg_arg} is a null pointer, the function executes: - -\begin{codeblock} -setg(gnext_arg, gnext_arg, gnext_arg + N); -\end{codeblock} - -\pnum -Otherwise, the function executes: - -\begin{codeblock} -setg(gnext_arg, gnext_arg, pbeg_arg); -setp(pbeg_arg, pbeg_arg + N); -\end{codeblock} -\end{itemdescr} - - -\indexlibraryctor{strstreambuf}% -\begin{itemdecl} -strstreambuf(const char* gnext_arg, streamsize n); -strstreambuf(const signed char* gnext_arg, streamsize n); -strstreambuf(const unsigned char* gnext_arg, streamsize n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Behaves the same as -\tcode{strstreambuf((char*)gnext_arg,n)}, -except that the constructor also sets \tcode{constant} in \tcode{strmode}. -\end{itemdescr} - -\indexlibrarydtor{strstreambuf}% -\begin{itemdecl} -virtual ~strstreambuf(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Destroys an object of class -\tcode{strstreambuf}. -The function frees the dynamically allocated array object only if -\tcode{(strmode \& allocated) != 0} -and -\tcode{(strmode \& frozen) == 0}. -(\ref{depr.strstreambuf.virtuals} describes how a dynamically allocated array object is freed.) -\end{itemdescr} - -\rSec3[depr.strstreambuf.members]{Member functions} - -\indexlibrarymember{freeze}{strstreambuf}% -\begin{itemdecl} -void freeze(bool freezefl = true); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If \tcode{strmode \& dynamic} is nonzero, alters the -freeze status of the dynamic array object as follows: -\begin{itemize} -\item -If \tcode{freezefl} is -\tcode{true}, -the function sets \tcode{frozen} in \tcode{strmode}. -\item -Otherwise, it clears \tcode{frozen} in \tcode{strmode}. -\end{itemize} -\end{itemdescr} - -\indexlibrarymember{str}{strstreambuf}% -\begin{itemdecl} -char* str(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Calls -\tcode{freeze()}, -then returns the beginning pointer for the input sequence, \tcode{gbeg}. - -\pnum -\remarks -The return value can be a null pointer. -\end{itemdescr} - -\indexlibrarymember{pcount}{strstreambuf}% -\begin{itemdecl} -int pcount() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -If the next pointer for the output sequence, \tcode{pnext}, is -a null pointer, returns zero. -Otherwise, returns the current -effective length of the array object as the next pointer minus the beginning -pointer for the output sequence, \tcode{pnext - pbeg}. -\end{itemdescr} - -\rSec3[depr.strstreambuf.virtuals]{\tcode{strstreambuf} overridden virtual functions} - -\indexlibrarymember{overflow}{strstreambuf}% -\begin{itemdecl} -int_type overflow(int_type c = EOF) override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Appends the character designated by \tcode{c} to the output -sequence, if possible, in one of two ways: -\begin{itemize} -\item -If -\tcode{c != EOF} -and if either the output sequence has a write position available or -the function makes a write position available -(as described below), -assigns \tcode{c} to -\tcode{*pnext++}. - -Returns -\tcode{(unsigned char)c}. - -\item -If -\tcode{c == EOF}, -there is no character to append. - -Returns a value other than \tcode{EOF}. -\end{itemize} - -\pnum -Returns -\tcode{EOF} -to indicate failure. - -\pnum -\remarks -The function can alter the number of write positions available as a -result of any call. - -\pnum -To make a write position available, the function reallocates -(or initially allocates) -an array object with a sufficient number of elements -\tcode{n} to hold the current array object (if any), -plus at least one additional write position. -How many additional write positions are made -available is otherwise unspecified.% -\indextext{unspecified}% -If \tcode{palloc} is not a null pointer, the function calls -\tcode{(*palloc)(n)} -to allocate the new dynamic array object. -Otherwise, it evaluates the expression -\tcode{new charT[n]}. -In either case, if the allocation fails, the function returns -\tcode{EOF}. -Otherwise, it sets \tcode{allocated} in \tcode{strmode}. - -\pnum -To free a previously existing dynamic array object whose first -element address is \tcode{p}: -If \tcode{pfree} is not a null pointer, -the function calls -\tcode{(*pfree)(p)}. -Otherwise, it evaluates the expression \tcode{delete[]p}. - -\pnum -If -\tcode{(strmode \& dynamic) == 0}, -or if -\tcode{(strmode \& frozen) != 0}, -the function cannot extend the array (reallocate it with greater length) to make a write position available. - -\pnum -\recommended -An implementation should consider \tcode{alsize} in making the -decision how many additional write positions to make available. -\end{itemdescr} - -\indexlibrarymember{pbackfail}{strstreambuf}% -\begin{itemdecl} -int_type pbackfail(int_type c = EOF) override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -Puts back the character designated by \tcode{c} to the input -sequence, if possible, in one of three ways: -\begin{itemize} -\item -If -\tcode{c != EOF}, -if the input sequence has a putback position available, and if -\tcode{(char)c == gnext[-1]}, -assigns -\tcode{gnext - 1} -to \tcode{gnext}. - -Returns \tcode{c}. -\item -If -\tcode{c != EOF}, -if the input sequence has a putback position available, and if -\tcode{strmode \& constant} is zero, -assigns \tcode{c} to -\tcode{*--gnext}. - -Returns -\tcode{c}. -\item -If -\tcode{c == EOF} -and if the input sequence has a putback position available, -assigns -\tcode{gnext - 1} -to \tcode{gnext}. - -Returns a value other than -\tcode{EOF}. -\end{itemize} - -\pnum -Returns -\tcode{EOF} -to indicate failure. - -\pnum -\remarks -If the function can succeed in more than one of these ways, it is -unspecified which way is chosen. -\indextext{unspecified}% -The function can alter the number of putback -positions available as a result of any call. -\end{itemdescr} - -\indexlibrarymember{underflow}{strstreambuf}% -\begin{itemdecl} -int_type underflow() override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Reads a character from the -\term{input sequence}, -if possible, without moving the stream position past it, as follows: -\begin{itemize} -\item -If the input sequence has a read position available, the function -signals success by returning -\tcode{(unsigned char)\brk*gnext}. -\item -Otherwise, if -the current write next pointer \tcode{pnext} is not a null pointer and -is greater than the current read end pointer \tcode{gend}, -makes a -\term{read position} -available by -assigning to \tcode{gend} a value greater than \tcode{gnext} and -no greater than \tcode{pnext}. - -Returns \tcode{(unsigned char)*gnext}. -\end{itemize} - -\pnum -Returns -\tcode{EOF} -to indicate failure. - -\pnum -\remarks -The function can alter the number of read positions available as a -result of any call. -\end{itemdescr} - -\indexlibrarymember{seekoff}{strstreambuf}% -\begin{itemdecl} -pos_type seekoff(off_type off, seekdir way, openmode which = in | out) override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Alters the stream position within one of the -controlled sequences, if possible, as indicated in \tref{depr.strstreambuf.seekoff.pos}. - -\begin{libtab2}{\tcode{seekoff} positioning}{depr.strstreambuf.seekoff.pos} -{p{2.5in}l}{Conditions}{Result} -\tcode{(which \& ios::in) != 0} & - positions the input sequence \\ \rowsep -\tcode{(which \& ios::out) != 0} & - positions the output sequence \\ \rowsep -\tcode{(which \& (ios::in | ios::out)) ==}\br -\tcode{(ios::in | ios::out)} and either\br -\tcode{way == ios::beg} or \tcode{way == ios::end} & - positions both the input and the output sequences \\ \rowsep -Otherwise & - the positioning operation fails. \\ -\end{libtab2} - -\pnum -For a sequence to be positioned, if its next pointer is a null pointer, -the positioning operation fails. -Otherwise, the function determines \tcode{newoff} as indicated in -\tref{depr.strstreambuf.seekoff.newoff}. - -\begin{libtab2}{\tcode{newoff} values}{depr.strstreambuf.seekoff.newoff} -{p{2.0in}p{2.0in}}{Condition}{\tcode{newoff} Value} -\tcode{way == ios::beg} & - 0 \\ \rowsep -\tcode{way == ios::cur} & - the next pointer minus the beginning pointer (\tcode{xnext - xbeg}). \\ \rowsep -\tcode{way == ios::end} & - \tcode{seekhigh} minus the beginning pointer (\tcode{seekhigh - xbeg}). \\ -\end{libtab2} - -\pnum -If \tcode{(newoff + off) < (seeklow - xbeg)} -or \tcode{(seekhigh - xbeg) < (newoff + off)}, -the positioning operation fails. -Otherwise, the function assigns -\tcode{xbeg + newoff + off} -to the next pointer \tcode{xnext}. - -\pnum -\returns -\tcode{pos_type(newoff)}, -constructed from the resultant offset -\tcode{newoff} (of type -\tcode{off_type}), -that stores the resultant stream position, if possible. -If the positioning operation fails, or -if the constructed object cannot represent the resultant stream position, -the return value is -\tcode{pos_type(off_type(-1))}. -\end{itemdescr} - -\indexlibrarymember{seekpos}{strstreambuf}% -\begin{itemdecl} -pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Alters the stream position within one of the -controlled sequences, if possible, to correspond to the -stream position stored in \tcode{sp} -(as described below). -\begin{itemize} -\item -If -\tcode{(which \& ios::in) != 0}, -positions the input sequence. -\item -If -\tcode{(which \& ios::out) != 0}, -positions the output sequence. -\item -If the function positions neither sequence, the positioning operation fails. -\end{itemize} - -\pnum -For a sequence to be positioned, if its next pointer is a null pointer, -the positioning operation fails. -Otherwise, the function determines \tcode{newoff} from -\tcode{sp.offset()}: -\begin{itemize} -\item -If \tcode{newoff} is an invalid stream position, -has a negative value, or -has a value greater than (\tcode{seekhigh - seeklow}), -the positioning operation fails -\item -Otherwise, the function -adds \tcode{newoff} to the beginning pointer \tcode{xbeg} and -stores the result in the next pointer \tcode{xnext}. -\end{itemize} - -\pnum -\returns -\tcode{pos_type(newoff)}, -constructed from the resultant offset \tcode{newoff} -(of type -\tcode{off_type}), -that stores the resultant stream position, if possible. -If the positioning operation fails, or -if the constructed object cannot represent the resultant stream position, -the return value is -\tcode{pos_type(off_type(-1))}. -\end{itemdescr} - -\indexlibrarymember{setbuf}{strstreambuf}% -\begin{itemdecl} -streambuf* setbuf(char* s, streamsize n) override; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Behavior is \impldef{behavior of \tcode{strstreambuf::setbuf}}, -except that -\tcode{setbuf(0, 0)} -has no effect.% -\end{itemdescr} - -\rSec2[depr.istrstream]{Class \tcode{istrstream}} - -\rSec3[depr.istrstream.general]{General} - -\indexlibraryglobal{istrstream}% -\begin{codeblock} -namespace std { - class istrstream : public basic_istream { - public: - explicit istrstream(const char* s); - explicit istrstream(char* s); - istrstream(const char* s, streamsize n); - istrstream(char* s, streamsize n); - virtual ~istrstream(); - - strstreambuf* rdbuf() const; - char* str(); - private: - strstreambuf sb; // \expos - }; -} -\end{codeblock} - -\pnum -The class -\tcode{istrstream} -supports the reading of objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: - -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} - -\rSec3[depr.istrstream.cons]{\tcode{istrstream} constructors} - -\indexlibraryctor{istrstream}% -\begin{itemdecl} -explicit istrstream(const char* s); -explicit istrstream(char* s); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{istream(\&sb)} and -\tcode{sb} with \tcode{strstreambuf(s, 0)}. -\tcode{s} shall designate the first element of an \ntbs{}.% -\indextext{NTBS@\ntbs{}} -\end{itemdescr} - -\indexlibraryctor{istrstream}% -\begin{itemdecl} -istrstream(const char* s, streamsize n); -istrstream(char* s, streamsize n); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{istream(\&sb)} -and \tcode{sb} with \tcode{strstreambuf(s, n)}. -\tcode{s} shall designate the first element of an array whose length is -\tcode{n} elements, and \tcode{n} shall be greater than zero. -\end{itemdescr} - -\rSec3[depr.istrstream.members]{Member functions} - -\indexlibrarymember{rdbuf}{istrstream}% -\begin{itemdecl} -strstreambuf* rdbuf() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{const_cast(\&sb)}. -\end{itemdescr} - -\indexlibrarymember{str}{istrstream}% -\begin{itemdecl} -char* str(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rdbuf()->str()}. -\end{itemdescr} - -\rSec2[depr.ostrstream]{Class \tcode{ostrstream}} - -\rSec3[depr.ostrstream.general]{General} - -\indexlibraryglobal{ostrstream}% -\begin{codeblock} -namespace std { - class ostrstream : public basic_ostream { - public: - ostrstream(); - ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out); - virtual ~ostrstream(); - - strstreambuf* rdbuf() const; - void freeze(bool freezefl = true); - char* str(); - int pcount() const; - private: - strstreambuf sb; // \expos - }; -} -\end{codeblock} - -\pnum -The class -\tcode{ostrstream} -supports the writing of objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: - -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} - -\rSec3[depr.ostrstream.cons]{\tcode{ostrstream} constructors} - -\indexlibraryctor{ostrstream}% -\begin{itemdecl} -ostrstream(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{ostream(\&sb)} and -\tcode{sb} with \tcode{strstreambuf()}. -\end{itemdescr} - -\indexlibraryctor{ostrstream}% -\begin{itemdecl} -ostrstream(char* s, int n, ios_base::openmode mode = ios_base::out); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{ostream(\&sb)}, -and \tcode{sb} with one of two constructors: - -\begin{itemize} -\item -If -\tcode{(mode \& app) == 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements. - -The constructor is -\tcode{strstreambuf(s, n, s)}. -\item -If -\tcode{(mode \& app) != 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements that -contains an \ntbs{} whose first element is designated by \tcode{s}. -\indextext{NTBS@\ntbs{}}% -The constructor is -\tcode{strstreambuf(s, n, s + std::strlen(s))}. -\begin{footnote} -The function signature -\indexlibraryglobal{strlen}% -\tcode{strlen(const char*)} -is declared in \libheaderref{cstring}. -\end{footnote} -\end{itemize} -\end{itemdescr} - -\rSec3[depr.ostrstream.members]{Member functions} - -\indexlibrarymember{rdbuf}{ostrstream}% -\begin{itemdecl} -strstreambuf* rdbuf() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{(strstreambuf*)\&sb}. -\end{itemdescr} - -\indexlibrarymember{freeze}{ostrstream}% -\begin{itemdecl} -void freeze(bool freezefl = true); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Calls -\tcode{rdbuf()->freeze(freezefl)}. -\end{itemdescr} - -\indexlibrarymember{str}{ostrstream}% -\begin{itemdecl} -char* str(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rdbuf()->str()}. -\end{itemdescr} - -\indexlibrarymember{pcount}{ostrstream}% -\begin{itemdecl} -int pcount() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rdbuf()->pcount()}. -\end{itemdescr} - -\rSec2[depr.strstream]{Class \tcode{strstream}} - -\rSec3[depr.strstream.general]{General} - -\indexlibraryglobal{strstream}% -\begin{codeblock} -namespace std { - class strstream - : public basic_iostream { - public: - // types - using char_type = char; - using int_type = char_traits::int_type; - using pos_type = char_traits::pos_type; - using off_type = char_traits::off_type; - - // constructors/destructor - strstream(); - strstream(char* s, int n, - ios_base::openmode mode = ios_base::in|ios_base::out); - virtual ~strstream(); - - // members - strstreambuf* rdbuf() const; - void freeze(bool freezefl = true); - int pcount() const; - char* str(); - - private: - strstreambuf sb; // \expos - }; -} -\end{codeblock} - -\pnum -The class -\tcode{strstream} -supports reading and writing from objects of class -\tcode{strstreambuf}. -It supplies a -\tcode{strstreambuf} -object to control the associated array object. -For the sake of exposition, the maintained data is presented here as: - -\begin{itemize} -\item -\tcode{sb}, the \tcode{strstreambuf} object. -\end{itemize} - -\rSec3[depr.strstream.cons]{\tcode{strstream} constructors} - -\indexlibraryctor{strstream}% -\begin{itemdecl} -strstream(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{iostream(\&sb)}. -\end{itemdescr} - -\indexlibraryctor{strstream}% -\begin{itemdecl} -strstream(char* s, int n, - ios_base::openmode mode = ios_base::in|ios_base::out); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Initializes the base class with \tcode{iostream(\&sb)}, -and \tcode{sb} with one of the two constructors: -\begin{itemize} -\item -If -\tcode{(mode \& app) == 0}, -then \tcode{s} shall designate the first element of an array of \tcode{n} elements. -The constructor is -\tcode{strstreambuf(s,n,s)}. -\item -If -\tcode{(mode \& app) != 0}, -then \tcode{s} shall -designate the first element of an array of \tcode{n} elements that contains -an \ntbs{} whose first element is designated by \tcode{s}. -The constructor is -\tcode{strstreambuf(s,n,s + std::strlen(s))}. -\indexlibrarydtor{strstream}% -\end{itemize} -\end{itemdescr} - -\rSec3[depr.strstream.dest]{\tcode{strstream} destructor} - -\indexlibrarydtor{strstream}% -\begin{itemdecl} -virtual ~strstream(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Destroys an object of class -\tcode{strstream}. -\end{itemdescr} - -\rSec3[depr.strstream.oper]{\tcode{strstream} operations} - -\indexlibrarymember{rdbuf}{strstream}% -\begin{itemdecl} -strstreambuf* rdbuf() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{const_cast(\&sb)}. -\end{itemdescr} - -\indexlibrarymember{freeze}{strstream}% -\begin{itemdecl} -void freeze(bool freezefl = true); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Calls -\tcode{rdbuf()->freeze(freezefl)}. -\end{itemdescr} - -\indexlibrarymember{str}{strstream}% -\begin{itemdecl} -char* str(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rdbuf()->str()}. -\end{itemdescr} - -\indexlibrarymember{pcount}{strstream}% -\begin{itemdecl} -int pcount() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{rdbuf()->pcount()}. -\end{itemdescr} - \rSec1[depr.cerrno]{Deprecated error numbers} \pnum diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 1368929680..7bb771c4eb 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1139,8 +1139,8 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\columnbreak \tcode{} \\ +\columnbreak \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1163,8 +1163,8 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -1186,15 +1186,14 @@ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\tcode{} \\ \columnbreak +\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ -\tcode{} \\ \tcode{} \\ \tcode{} \\ \tcode{} \\ @@ -3049,6 +3048,7 @@ \item \indexlibraryzombie{gets} \tcode{gets}, \item \indexlibraryzombie{is_literal_type} \tcode{is_literal_type}, \item \indexlibraryzombie{is_literal_type_v} \tcode{is_literal_type_v}, +\item \indexlibraryzombie{istrstream} \tcode{istrstream}, \item \indexlibraryzombie{little_endian} \tcode{little_endian}, \item \indexlibraryzombie{mem_fun1_ref_t} \tcode{mem_fun1_ref_t}, \item \indexlibraryzombie{mem_fun1_t} \tcode{mem_fun1_t}, @@ -3058,6 +3058,7 @@ \item \indexlibraryzombie{mem_fun} \tcode{mem_fun}, \item \indexlibraryzombie{not1} \tcode{not1}, \item \indexlibraryzombie{not2} \tcode{not2}, +\item \indexlibraryzombie{ostrstream} \tcode{ostrstream}, \item \indexlibraryzombie{pointer_safety} \tcode{pointer_safety}, \item \indexlibraryzombie{pointer_to_binary_function} \tcode{pointer_to_binary_function}, \item \indexlibraryzombie{pointer_to_unary_function} \tcode{pointer_to_unary_function}, @@ -3068,6 +3069,8 @@ \item \indexlibraryzombie{result_of_t} \tcode{result_of_t}, \item \indexlibraryzombie{return_temporary_buffer} \tcode{return_temporary_buffer}, \item \indexlibraryzombie{set_unexpected} \tcode{set_unexpected}, +\item \indexlibraryzombie{strstream} \tcode{strstream}, +\item \indexlibraryzombie{strstreambuf} \tcode{strstreambuf}, \item \indexlibraryzombie{unary_function} \tcode{unary_function}, \item \indexlibraryzombie{unary_negate} \tcode{unary_negate}, \item \indexlibraryzombie{uncaught_exception} \tcode{uncaught_exception}, @@ -3093,9 +3096,13 @@ \end{itemize} \pnum -The name \indexlibraryzombie{stossc} \tcode{stossc} is reserved as a -member function for previous standardization, and may not be used as a name for -function-like macros in portable code. +The following names are reserved as member functions for previous +standardization, and may not be used as a name for function-like macros in +\begin{itemize} +\item \indexlibraryzombie{freeze} \tcode{freeze}, +\item \indexlibraryzombie{pcount} \tcode{pcount}, and +\item \indexlibraryzombie{stossc} \tcode{stossc}, +\end{itemize} \pnum The header names @@ -3103,8 +3110,9 @@ \libnoheader{ciso646}, \libnoheader{codecvt}, \libnoheader{cstdalign}, -\libnoheader{cstdbool}, and -\libnoheader{ctgmath} +\libnoheader{cstdbool}, +\libnoheader{ctgmath}, and +\libnoheader{strstream} are reserved for previous standardization. \rSec4[macro.names]{Macro names} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 56d006ae82..5fb5fc42c3 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -37,6 +37,28 @@ % P2870R3 Remove `basic_string::reserve()` with no parameters \removedxref{depr.string.capacity} +% P2867R2 Remove deprecated strstreams +\removedxref{depr.istrstream} +\removedxref{depr.istrstream.cons} +\removedxref{depr.istrstream.general} +\removedxref{depr.istrstream.members} +\removedxref{depr.ostrstream} +\removedxref{depr.ostrstream.cons} +\removedxref{depr.ostrstream.general} +\removedxref{depr.ostrstream.members} +\removedxref{depr.str.strstreams} +\removedxref{depr.strstream} +\removedxref{depr.strstream.cons} +\removedxref{depr.strstream.dest} +\removedxref{depr.strstream.general} +\removedxref{depr.strstream.oper} +\removedxref{depr.strstream.syn} +\removedxref{depr.strstreambuf} +\removedxref{depr.strstreambuf.cons} +\removedxref{depr.strstreambuf.general} +\removedxref{depr.strstreambuf.members} +\removedxref{depr.strstreambuf.virtuals} + %%% Renamed sections. %%% Examples: % From a852a0299ce6ebb39f3548d528edaf341acab2f9 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sun, 24 Mar 2024 12:10:05 +0900 Subject: [PATCH 2/6] [zombie.names] Reformatted sequence of zombie header as a list This reformatting, in addition being consistent with the rest of the clause, resolves an overful hbox warning. Also added the missing text at end of the opening sentence of p3. --- source/lib-intro.tex | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 7bb771c4eb..c16c47fb04 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -3098,6 +3098,7 @@ \pnum The following names are reserved as member functions for previous standardization, and may not be used as a name for function-like macros in +portable code: \begin{itemize} \item \indexlibraryzombie{freeze} \tcode{freeze}, \item \indexlibraryzombie{pcount} \tcode{pcount}, and @@ -3105,15 +3106,17 @@ \end{itemize} \pnum -The header names -\libnoheader{ccomplex}, -\libnoheader{ciso646}, -\libnoheader{codecvt}, -\libnoheader{cstdalign}, -\libnoheader{cstdbool}, -\libnoheader{ctgmath}, and -\libnoheader{strstream} -are reserved for previous standardization. +The following header names are reserved for previous standardization: +\begin{itemize} +\item \libnoheader{ccomplex}, +\item \libnoheader{ciso646}, +\item \libnoheader{codecvt}, +\item \libnoheader{cstdalign}, +\item \libnoheader{cstdbool}, +\item \libnoheader{ctgmath}, +and +\item \libnoheader{strstream} +\end{itemize} \rSec4[macro.names]{Macro names} From 84a3f905908d947eef3c8fbd059868287893742b Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sun, 24 Mar 2024 09:58:33 +0900 Subject: [PATCH 3/6] P2869R4 Remove deprecated atomic free function API for shared_ptr The Annex C wording is modeled on the compatibility with C form, and should be revised without the "difficulty of converting" clause, probably with a simple code example in "Effects". --- source/compatibility.tex | 17 +++ source/future.tex | 268 --------------------------------------- source/xrefdelta.tex | 3 + 3 files changed, 20 insertions(+), 268 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index eb13565fc3..bc3bb2c05f 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -155,6 +155,23 @@ // OK in \CppXXVI{} \end{codeblock} +\nodiffref +\change +Removal of atomic access API for \tcode{shared_ptr} objects. +\rationale +The old behavior was brittle. \tcode{shared_ptr} objects using the old API were +not protected by the type system, and certain interactions with code not using +this API would, in some cases, silently produce undefined behavior. A complete +type-safe replacement is provided in the form of \tcode{atomic>}. +\effect +Deletion of an old feature where a superior replacement exists within the +standard. +\difficulty +Violations will be diagnosed by the \Cpp{} translator, as there are no +remaining overloads that would match such calls. Violations are addressed by +replacing affected \tcode{shared_ptr} objects with +\tcode{atomic>}. + \nodiffref \change Remove the \tcode{basic_string::reserve()} overload with no parameters. diff --git a/source/future.tex b/source/future.tex index 1a44162f3d..e5999a31c1 100644 --- a/source/future.tex +++ b/source/future.tex @@ -703,274 +703,6 @@ \tcode{current}. \end{itemdescr} -\rSec1[depr.util.smartptr.shared.atomic]{Deprecated \tcode{shared_ptr} atomic access} - -\pnum -The header \libheaderref{memory} has the following additions: - -\indexlibraryglobal{shared_ptr}% -\begin{codeblock} -namespace std { - template - bool atomic_is_lock_free(const shared_ptr* p); - - template - shared_ptr atomic_load(const shared_ptr* p); - template - shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); - - template - void atomic_store(shared_ptr* p, shared_ptr r); - template - void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); - - template - shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); - template - shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); - - template - bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); - template - bool atomic_compare_exchange_strong(shared_ptr* p, shared_ptr* v, shared_ptr w); - template - bool atomic_compare_exchange_weak_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); - template - bool atomic_compare_exchange_strong_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); -} -\end{codeblock} - -\pnum -Concurrent access to a \tcode{shared_ptr} object from multiple threads does not -introduce a data race if the access is done exclusively via the functions in -this subclause and the instance is passed as their first argument. - -\pnum -The meaning of the arguments of type \tcode{memory_order} is explained in~\ref{atomics.order}. - -\indexlibrarymember{atomic_is_lock_free}{shared_ptr}% -\begin{itemdecl} -template bool atomic_is_lock_free(const shared_ptr* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. - -\pnum -\returns -\tcode{true} if atomic access to \tcode{*p} is lock-free, \tcode{false} otherwise. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_load}{shared_ptr}% -\begin{itemdecl} -template shared_ptr atomic_load(const shared_ptr* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. - -\pnum -\returns -\tcode{atomic_load_explicit(p, memory_order::seq_cst)}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_load_explicit}{shared_ptr}% -\begin{itemdecl} -template shared_ptr atomic_load_explicit(const shared_ptr* p, memory_order mo); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. -\tcode{mo} is neither \tcode{memory_order::release} nor \tcode{memory_order::acq_rel}. - -\pnum -\returns -\tcode{*p}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_store}{shared_ptr}% -\begin{itemdecl} -template void atomic_store(shared_ptr* p, shared_ptr r); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. - -\pnum -\effects -As if by \tcode{atomic_store_explicit(p, r, memory_order::seq_cst)}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_store_explicit}{shared_ptr}% -\begin{itemdecl} -template void atomic_store_explicit(shared_ptr* p, shared_ptr r, memory_order mo); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. -\tcode{mo} is neither \tcode{memory_order::acquire} nor \tcode{memory_order::acq_rel}. - -\pnum -\effects -As if by \tcode{p->swap(r)}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_exchange}{shared_ptr}% -\begin{itemdecl} -template shared_ptr atomic_exchange(shared_ptr* p, shared_ptr r); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. - -\pnum -\returns -\tcode{atomic_exchange_explicit(p, r, memory_order::seq_cst)}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_exchange_explicit}{shared_ptr}% -\begin{itemdecl} -template - shared_ptr atomic_exchange_explicit(shared_ptr* p, shared_ptr r, memory_order mo); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null. - -\pnum -\effects -As if by \tcode{p->swap(r)}. - -\pnum -\returns -The previous value of \tcode{*p}. - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_compare_exchange_weak}{shared_ptr}% -\begin{itemdecl} -template - bool atomic_compare_exchange_weak(shared_ptr* p, shared_ptr* v, shared_ptr w); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null and \tcode{v} is not null. - -\pnum -\returns -\begin{codeblock} -atomic_compare_exchange_weak_explicit(p, v, w, memory_order::seq_cst, memory_order::seq_cst) -\end{codeblock} - -\pnum -\throws -Nothing. -\end{itemdescr} - -\indexlibrarymember{atomic_compare_exchange_strong}{shared_ptr}% -\begin{itemdecl} -template - bool atomic_compare_exchange_strong(shared_ptr* p, shared_ptr* v, shared_ptr w); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\begin{codeblock} -atomic_compare_exchange_strong_explicit(p, v, w, memory_order::seq_cst, - memory_order::seq_cst) -\end{codeblock} -\end{itemdescr} - -\indexlibrarymember{atomic_compare_exchange_weak_explicit}{shared_ptr}% -\indexlibrarymember{atomic_compare_exchange_strong_explicit}{shared_ptr}% -\begin{itemdecl} -template - bool atomic_compare_exchange_weak_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); -template - bool atomic_compare_exchange_strong_explicit( - shared_ptr* p, shared_ptr* v, shared_ptr w, - memory_order success, memory_order failure); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{p} is not null and \tcode{v} is not null. -The \tcode{failure} argument is neither \tcode{memory_order::release} nor -\tcode{memory_order::acq_rel}. - -\pnum -\effects -If \tcode{*p} is equivalent to \tcode{*v}, assigns \tcode{w} to -\tcode{*p} and has synchronization semantics corresponding to the value of -\tcode{success}, otherwise assigns \tcode{*p} to \tcode{*v} and has -synchronization semantics corresponding to the value of \tcode{failure}. - -\pnum -\returns -\tcode{true} if \tcode{*p} was equivalent to \tcode{*v}, \tcode{false} otherwise. - -\pnum -\throws -Nothing. - -\pnum -\remarks -Two \tcode{shared_ptr} objects are equivalent if they store the same -pointer value and share ownership. -The weak form may fail spuriously. See~\ref{atomics.types.operations}. -\end{itemdescr} - \rSec1[depr.format]{Deprecated formatting} \rSec2[depr.format.syn]{Header \tcode{} synopsis} diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 5fb5fc42c3..9a842ac2fb 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -59,6 +59,9 @@ \removedxref{depr.strstreambuf.members} \removedxref{depr.strstreambuf.virtuals} +% P2869R4 Mandating Annex D +\removedxref{depr.util.smartptr.shared.atomic} + %%% Renamed sections. %%% Examples: % From 85d0a7cfb7fc993ecc71ac7bb685f17c90b988f1 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sun, 24 Mar 2024 10:43:02 +0900 Subject: [PATCH 4/6] P2872R3 Remove wstring_convert from C++26 --- source/compatibility.tex | 11 ++ source/future.tex | 377 --------------------------------------- source/lib-intro.tex | 12 +- source/xrefdelta.tex | 6 + 4 files changed, 26 insertions(+), 380 deletions(-) diff --git a/source/compatibility.tex b/source/compatibility.tex index bc3bb2c05f..b6f8aaee0b 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -226,6 +226,17 @@ \item \tcode{strstreambuf} \end{itemize} +\change +Remove convenience interfaces \tcode{wstring_convert} and +\tcode{wbuffer_convert}. +\rationale +These features were underspecified with no clear error reporting mechanism and +were deprecated for the last three editions of this standard. Ongoing support +is at implementer's discretion, exercising freedoms granted by +\ref{zombie.names}. +\effect +A valid \CppXXIII{} program using these interfaces may become ill-formed. + \rSec1[diff.cpp20]{\Cpp{} and ISO \CppXX{}} \rSec2[diff.cpp20.general]{General} diff --git a/source/future.tex b/source/future.tex index e5999a31c1..4ded6f9045 100644 --- a/source/future.tex +++ b/source/future.tex @@ -731,383 +731,6 @@ Equivalent to: \tcode{return visit(std::forward(vis), arg.value);} \end{itemdescr} -\rSec1[depr.conversions]{Deprecated convenience conversion interfaces} - -\rSec2[depr.conversions.general]{General} - -\pnum -The header \libheaderref{locale} has the following additions: - -\begin{codeblock} -namespace std { - template, - class ByteAlloc = allocator> - class wstring_convert; - - template> - class wbuffer_convert; -} -\end{codeblock} - -\rSec2[depr.conversions.string]{Class template \tcode{wstring_convert}} - -\pnum -Class template \tcode{wstring_convert} performs conversions between a wide -string and a byte string. It lets you specify a code conversion facet -(like class template \tcode{codecvt}) to perform the conversions, without -affecting any streams or locales. -\begin{example} -If you want to use a code -conversion facet, \tcode{codecvt_for_utf8}, to output to \tcode{cout} a UTF-8 -multibyte sequence corresponding to a wide string, but you don't want to -alter the locale for \tcode{cout}, you can write something like: -\begin{codeblock} -std::wstring_convert> myconv; -std::string mbstring = myconv.to_bytes(L"Hello\n"); -std::cout << mbstring; -\end{codeblock} -\end{example} - -\indexlibraryglobal{wstring_convert}% -\indexlibrarymember{byte_string}{wstring_convert}% -\indexlibrarymember{int_type}{wstring_convert}% -\indexlibrarymember{state_type}{wstring_convert}% -\indexlibrarymember{wide_string}{wstring_convert}% -\begin{codeblock} -namespace std { - template, - class ByteAlloc = allocator> - class wstring_convert { - public: - using byte_string = basic_string, ByteAlloc>; - using wide_string = basic_string, WideAlloc>; - using state_type = typename Codecvt::state_type; - using int_type = typename wide_string::traits_type::int_type; - - wstring_convert() : wstring_convert(new Codecvt) {} - explicit wstring_convert(Codecvt* pcvt); - wstring_convert(Codecvt* pcvt, state_type state); - explicit wstring_convert(const byte_string& byte_err, - const wide_string& wide_err = wide_string()); - ~wstring_convert(); - - wstring_convert(const wstring_convert&) = delete; - wstring_convert& operator=(const wstring_convert&) = delete; - - wide_string from_bytes(char byte); - wide_string from_bytes(const char* ptr); - wide_string from_bytes(const byte_string& str); - wide_string from_bytes(const char* first, const char* last); - - byte_string to_bytes(Elem wchar); - byte_string to_bytes(const Elem* wptr); - byte_string to_bytes(const wide_string& wstr); - byte_string to_bytes(const Elem* first, const Elem* last); - - size_t converted() const noexcept; - state_type state() const; - - private: - byte_string byte_err_string; // \expos - wide_string wide_err_string; // \expos - Codecvt* cvtptr; // \expos - state_type cvtstate; // \expos - size_t cvtcount; // \expos - }; -} -\end{codeblock} - -\pnum -The class template describes an object that controls conversions between wide -string objects of class \tcode{basic_string, -WideAlloc>} and byte string objects of class \tcode{basic_string, ByteAlloc>}. The class template defines the types -\tcode{wide_string} and \tcode{byte_string} as synonyms for these two types. -Conversion between a sequence of \tcode{Elem} values (stored in a -\tcode{wide_string} object) and multibyte sequences (stored in a -\tcode{byte_string} object) is performed by an object of class -\tcode{Codecvt}, which meets the -requirements of the standard code-conversion facet \tcode{codecvt}. - -\pnum -An object of this class template stores: - -\begin{itemize} -\item \tcode{byte_err_string} --- a byte string to display on errors -\item \tcode{wide_err_string} --- a wide string to display on errors -\item \tcode{cvtptr} --- a pointer to the allocated conversion object -(which is freed when the \tcode{wstring_convert} object is destroyed) -\item \tcode{cvtstate} --- a conversion state object -\item \tcode{cvtcount} --- a conversion count -\end{itemize} - -\indexlibrarymember{converted}{wstring_convert}% -\begin{itemdecl} -size_t converted() const noexcept; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{cvtcount}. -\end{itemdescr} - -\indexlibrarymember{from_bytes}{wstring_convert}% -\begin{itemdecl} -wide_string from_bytes(char byte); -wide_string from_bytes(const char* ptr); -wide_string from_bytes(const byte_string& str); -wide_string from_bytes(const char* first, const char* last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The first member function converts the single-element sequence \tcode{byte} to a -wide string. The second member function converts the null-terminated -sequence beginning at \tcode{ptr} to a wide string. The third member function -converts the sequence stored in \tcode{str} to a wide string. The fourth member -function converts the sequence defined by the range \range{first}{last} to a -wide string. - -\pnum -In all cases: - -\begin{itemize} -\item If the \tcode{cvtstate} object was not constructed with an explicit value, it -is set to its default value (the initial conversion state) before the -conversion begins. Otherwise it is left unchanged. - -\item The number of input elements successfully converted is stored in \tcode{cvtcount}. -\end{itemize} - -\pnum -\returns -If no conversion error occurs, the member function returns the converted wide string. -Otherwise, if the object was constructed with a wide-error string, the -member function returns the wide-error string. -Otherwise, the member function throws an object of class \tcode{range_error}. -\end{itemdescr} - -\indexlibrarymember{state}{wstring_convert}% -\begin{itemdecl} -state_type state() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{cvtstate}. -\end{itemdescr} - -\indexlibrarymember{to_bytes}{wstring_convert}% -\begin{itemdecl} -byte_string to_bytes(Elem wchar); -byte_string to_bytes(const Elem* wptr); -byte_string to_bytes(const wide_string& wstr); -byte_string to_bytes(const Elem* first, const Elem* last); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -The first member function converts the single-element sequence \tcode{wchar} to a byte string. -The second member function converts the null-terminated sequence beginning at \tcode{wptr} to -a byte string. The third member function converts the sequence stored in \tcode{wstr} to a -byte string. The fourth member function converts the sequence defined by the -range \range{first}{last} to a byte string. - -\pnum -In all cases: - -\begin{itemize} -\item If the \tcode{cvtstate} object was not constructed with an explicit value, -it is set to its default value (the initial conversion state) before the -conversion begins. Otherwise it is left unchanged. -\item The number of input elements successfully converted is stored -in \tcode{cvtcount}. -\end{itemize} - -\pnum -\returns -If no conversion error occurs, the member function returns the converted byte string. -Otherwise, if the object was constructed with a byte-error string, the -member function returns the byte-error string. -Otherwise, the member function throws an object of class \tcode{range_error}. -\end{itemdescr} - -\indexlibraryctor{wstring_convert}% -\begin{itemdecl} -explicit wstring_convert(Codecvt* pcvt); -wstring_convert(Codecvt* pcvt, state_type state); -explicit wstring_convert(const byte_string& byte_err, - const wide_string& wide_err = wide_string()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -For the first and second constructors, \tcode{pcvt} is not null. - -\pnum -\effects -The first constructor stores \tcode{pcvt} in \tcode{cvtptr} and -default values in \tcode{cvtstate}, \tcode{byte_err_string}, and -\tcode{wide_err_string}. -The second constructor stores \tcode{pcvt} in \tcode{cvtptr}, -\tcode{state} in \tcode{cvtstate}, and default values in -\tcode{byte_err_string} and \tcode{wide_err_string}; moreover the -stored state is retained between calls to \tcode{from_bytes} and -\tcode{to_bytes}. -The third constructor stores \tcode{new Codecvt} in \tcode{cvtptr}, -\tcode{state_type()} in \tcode{cvtstate}, \tcode{byte_err} -in \tcode{byte_err_string}, and \tcode{wide_err} in -\tcode{wide_err_string}. -\end{itemdescr} - -\indexlibrarydtor{wstring_convert}% -\begin{itemdecl} -~wstring_convert(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -\tcode{delete cvtptr}. -\end{itemdescr} - -\rSec2[depr.conversions.buffer]{Class template \tcode{wbuffer_convert}} - -\pnum -Class template \tcode{wbuffer_convert} looks like a wide stream buffer, but -performs all its I/O through an underlying byte stream buffer that you -specify when you construct it. Like class template \tcode{wstring_convert}, it -lets you specify a code conversion facet to perform the conversions, -without affecting any streams or locales. - -\indexlibraryglobal{wbuffer_convert}% -\indexlibrarymember{state_type}{wbuffer_convert}% -\begin{codeblock} -namespace std { - template> - class wbuffer_convert : public basic_streambuf { - public: - using state_type = typename Codecvt::state_type; - - wbuffer_convert() : wbuffer_convert(nullptr) {} - explicit wbuffer_convert(streambuf* bytebuf, - Codecvt* pcvt = new Codecvt, - state_type state = state_type()); - - ~wbuffer_convert(); - - wbuffer_convert(const wbuffer_convert&) = delete; - wbuffer_convert& operator=(const wbuffer_convert&) = delete; - - streambuf* rdbuf() const; - streambuf* rdbuf(streambuf* bytebuf); - - state_type state() const; - - private: - streambuf* bufptr; // \expos - Codecvt* cvtptr; // \expos - state_type cvtstate; // \expos - }; -} -\end{codeblock} - -\pnum -The class template describes a stream buffer that controls the -transmission of elements of type \tcode{Elem}, whose character traits are -described by the class \tcode{Tr}, to and from a byte stream buffer of type -\tcode{streambuf}. Conversion between a sequence of \tcode{Elem} values and -multibyte sequences is performed by an object of class -\tcode{Codecvt}, which shall meet the requirements -of the standard code-conversion facet \tcode{codecvt}. - -\pnum -An object of this class template stores: - -\begin{itemize} -\item \tcode{bufptr} --- a pointer to its underlying byte stream buffer -\item \tcode{cvtptr} --- a pointer to the allocated conversion object -(which is freed when the \tcode{wbuffer_convert} object is destroyed) -\item \tcode{cvtstate} --- a conversion state object -\end{itemize} - -\indexlibrarymember{state}{wbuffer_convert}% -\begin{itemdecl} -state_type state() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{cvtstate}. -\end{itemdescr} - -\indexlibrarymember{rdbuf}{wbuffer_convert}% -\begin{itemdecl} -streambuf* rdbuf() const; -\end{itemdecl} - -\begin{itemdescr} -\pnum -\returns -\tcode{bufptr}. -\end{itemdescr} - -\indexlibrarymember{rdbuf}{wbuffer_convert}% -\begin{itemdecl} -streambuf* rdbuf(streambuf* bytebuf); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -Stores \tcode{bytebuf} in \tcode{bufptr}. - -\pnum -\returns -The previous value of \tcode{bufptr}. -\end{itemdescr} - -\indexlibraryctor{wbuffer_convert}% -\begin{itemdecl} -explicit wbuffer_convert( - streambuf* bytebuf, - Codecvt* pcvt = new Codecvt, - state_type state = state_type()); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\expects -\tcode{pcvt} is not null. - -\pnum -\effects -The constructor constructs a stream buffer object, initializes -\tcode{bufptr} to \tcode{bytebuf}, initializes \tcode{cvtptr} -to \tcode{pcvt}, and initializes \tcode{cvtstate} to \tcode{state}. -\end{itemdescr} - -\indexlibrarydtor{wbuffer_convert}% -\begin{itemdecl} -~wbuffer_convert(); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -\tcode{delete cvtptr}. -\end{itemdescr} - \rSec1[depr.locale.category]{Deprecated locale category facets} \pnum diff --git a/source/lib-intro.tex b/source/lib-intro.tex index c16c47fb04..a98ce9bed7 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -3076,8 +3076,10 @@ \item \indexlibraryzombie{uncaught_exception} \tcode{uncaught_exception}, \item \indexlibraryzombie{undeclare_no_pointers} \tcode{undeclare_no_pointers}, \item \indexlibraryzombie{undeclare_reachable} \tcode{undeclare_reachable}, +\item \indexlibraryzombie{unexpected_handler} \tcode{unexpected_handler}, +\item \indexlibraryzombie{wbuffer_convert} \tcode{wbuffer_convert}, and -\item \indexlibraryzombie{unexpected_handler} \tcode{unexpected_handler}. +\item \indexlibraryzombie{wstring_convert} \tcode{wstring_convert}. \end{itemize} \pnum @@ -3097,12 +3099,16 @@ \pnum The following names are reserved as member functions for previous -standardization, and may not be used as a name for function-like macros in +standardization, and may not be used as names for function-like macros in portable code: \begin{itemize} +\item \indexlibraryzombie{converted} \tcode{converted}, \item \indexlibraryzombie{freeze} \tcode{freeze}, -\item \indexlibraryzombie{pcount} \tcode{pcount}, and +\item \indexlibraryzombie{from_bytes} \tcode{from_bytes}, +\item \indexlibraryzombie{pcount} \tcode{pcount}, \item \indexlibraryzombie{stossc} \tcode{stossc}, +and +\item \indexlibraryzombie{to_bytes} \tcode{to_bytes}. \end{itemize} \pnum diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 9a842ac2fb..0fe01d1c87 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -62,6 +62,12 @@ % P2869R4 Mandating Annex D \removedxref{depr.util.smartptr.shared.atomic} +% P2872R3 Remove wstring_convert from C++26 +\removedxref{depr.conversions} +\removedxref{depr.conversions.buffer} +\removedxref{depr.conversions.general} +\removedxref{depr.conversions.string} + %%% Renamed sections. %%% Examples: % From f071fdeb6238cc1608f6bd7fb4f852a76d503386 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sat, 23 Mar 2024 10:42:08 +0900 Subject: [PATCH 5/6] P2875R4 Undeprecate polymorphic_allocator::destroy --- source/future.tex | 29 ----------------------------- source/memory.tex | 17 ++++++++++++++++- source/xrefdelta.tex | 3 +++ 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/source/future.tex b/source/future.tex index 4ded6f9045..1a0641e190 100644 --- a/source/future.tex +++ b/source/future.tex @@ -359,35 +359,6 @@ is the same as the value of the \libheader{cerrno} macro shown in the above synopsis. -\rSec1[depr.mem.poly.allocator.mem]{Deprecated \tcode{polymorphic_allocator} member function} - -\pnum -The following member is declared in addition to those members -specified in \ref{mem.poly.allocator.mem}: - -\begin{codeblock} -namespace std::pmr { - template - class polymorphic_allocator { - public: - template - void destroy(T* p); - }; -} -\end{codeblock} - -\indexlibrarymember{destroy}{polymorphic_allocator}% -\begin{itemdecl} -template - void destroy(T* p); -\end{itemdecl} - -\begin{itemdescr} -\pnum -\effects -As if by \tcode{p->\~T()}. -\end{itemdescr} - \rSec1[depr.meta.types]{Deprecated type traits} \pnum diff --git a/source/memory.tex b/source/memory.tex index f65e2de029..62136487b0 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -5813,6 +5813,9 @@ template void construct(T* p, Args&&... args); + template + void destroy(T* p); + polymorphic_allocator select_on_container_copy_construction() const; memory_resource* resource() const; @@ -6023,7 +6026,7 @@ \effects Equivalent to: \begin{codeblock} -allocator_traits::destroy(*this, p); +destroy(p); deallocate_object(p); \end{codeblock} \end{itemdescr} @@ -6053,6 +6056,18 @@ Nothing unless the constructor for \tcode{T} throws. \end{itemdescr} +\indexlibrarymember{destroy}{polymorphic_allocator}% +\begin{itemdecl} +template + void destroy(T* p); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\effects +Equivalent to \tcode{p->\~T()}. +\end{itemdescr} + \indexlibrarymember{select_on_container_copy_construction}{polymorphic_allocator}% \begin{itemdecl} polymorphic_allocator select_on_container_copy_construction() const; diff --git a/source/xrefdelta.tex b/source/xrefdelta.tex index 0fe01d1c87..dff4723e4e 100644 --- a/source/xrefdelta.tex +++ b/source/xrefdelta.tex @@ -79,6 +79,9 @@ % https://github.com/cplusplus/draft/pull/6255 \movedxref{container.gen.reqmts}{container.requirements.general} +% P2875 Undeprecate polymorphic_allocator::destroy +\movedxref{depr.mem.poly.allocator.mem}{mem.poly.allocator.mem} + % https://github.com/cplusplus/draft/pull/6653 \movedxref{mismatch}{alg.mismatch} From 1abc2e107adb60182a9beed129476ad230a82828 Mon Sep 17 00:00:00 2001 From: Alisdair Meredith Date: Sun, 24 Mar 2024 11:43:13 +0900 Subject: [PATCH 6/6] [mem.poly.allocator.class.general] Removed space before angle in template-head --- source/memory.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/memory.tex b/source/memory.tex index 62136487b0..1a80d14ed0 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -5813,7 +5813,7 @@ template void construct(T* p, Args&&... args); - template + template void destroy(T* p); polymorphic_allocator select_on_container_copy_construction() const;