%!TEX root = std.tex \rSec0[input.output]{Input/output library} \rSec1[input.output.general]{General} \pnum This Clause describes components that \Cpp{} programs may use to perform input/output operations. \pnum The following subclauses describe requirements for stream parameters, and components for forward declarations of iostreams, predefined iostreams objects, base iostreams classes, stream buffering, stream formatting and manipulators, string streams, and file streams, as summarized in \tref{iostreams.summary}. \begin{libsumtab}{Input/output library summary}{iostreams.summary} \ref{iostreams.requirements} & Requirements & \\ \rowsep \ref{iostream.forward} & Forward declarations & \tcode{} \\ \rowsep \ref{iostream.objects} & Standard iostream objects & \tcode{} \\ \rowsep \ref{iostreams.base} & Iostreams base classes & \tcode{} \\ \rowsep \ref{stream.buffers} & Stream buffers & \tcode{} \\ \rowsep \ref{iostream.format} & Formatting and manipulators & \tcode{}, \tcode{}, \tcode{}, \tcode{} \\ \rowsep \ref{string.streams} & String streams & \tcode{} \\ \rowsep \ref{span.streams} & Span-based streams & \tcode{} \\ \rowsep \ref{file.streams} & File streams & \tcode{} \\ \rowsep \ref{syncstream} & Synchronized output streams & \tcode{} \\ \rowsep \ref{filesystems} & File systems & \tcode{} \\ \rowsep \ref{c.files} & C library files & \tcode{}, \tcode{} \\ \end{libsumtab} \rSec1[iostreams.requirements]{Iostreams requirements} \rSec2[iostream.limits.imbue]{Imbue limitations} \pnum No function described in \ref{input.output} except for \tcode{ios_base::imbue} and \tcode{basic_filebuf::pubimbue} causes any instance of \tcode{basic_ios::imbue} or \tcode{basic_streambuf::imbue} to be called. If any user function called from a function declared in \ref{input.output} or as an overriding virtual function of any class declared in \ref{input.output} calls \tcode{imbue}, the behavior is undefined. \rSec2[stream.types]{Types} \indexlibraryglobal{streamoff}% \begin{itemdecl} using streamoff = @\impdefx{type of \tcode{streamoff}}@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{streamoff} is a synonym for one of the signed basic integral types of sufficient size to represent the maximum possible file size for the operating system. \begin{footnote} Typically \tcode{long long}. \end{footnote} \end{itemdescr} \indexlibraryglobal{streamsize}% \begin{itemdecl} using streamsize = @\impdef@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{streamsize} is a synonym for one of the signed basic integral types. It is used to represent the number of characters transferred in an I/O operation, or the size of I/O buffers. \begin{footnote} Most places where \tcode{streamsize} is used would use \tcode{size_t} in C, or \tcode{ssize_t} in POSIX. \end{footnote} \end{itemdescr} \rSec2[iostreams.limits.pos]{Positioning type limitations} \pnum The classes of \ref{input.output} with template arguments \tcode{charT} and \tcode{traits} behave as described if \tcode{traits::pos_type} and \tcode{traits::off_type} are \tcode{streampos} and \tcode{streamoff} respectively. Except as noted explicitly below, their behavior when \tcode{traits::pos_type} and \tcode{traits::off_type} are other types is \impldef{behavior of iostream classes when \tcode{traits::pos_type} is not \tcode{streampos} or when \tcode{traits::\brk{}off_type} is not \tcode{streamoff}}. \pnum \begin{note} For each of the specializations of \tcode{char_traits} defined in \ref{char.traits.specializations}, \tcode{state_type} denotes \tcode{mbstate_t}, \tcode{pos_type} denotes \tcode{fpos}, and \tcode{off_type} denotes \tcode{streamoff}. \end{note} \pnum In the classes of \ref{input.output}, a template parameter with name \tcode{charT} represents a member of the set of types containing \tcode{char}, \keyword{wchar_t}, and any other \impldef{set of character container types that iostreams templates can be instantiated for} character container types\iref{defns.character.container} that meet the requirements for a character on which any of the iostream components can be instantiated. \rSec2[iostreams.threadsafety]{Thread safety} \pnum Concurrent access to a stream object\iref{string.streams,file.streams}, stream buffer object\iref{stream.buffers}, or C Library stream\iref{c.files} by multiple threads may result in a data race\iref{intro.multithread} unless otherwise specified\iref{iostream.objects}. \begin{note} Data races result in undefined behavior\iref{intro.multithread}. \end{note} \pnum If one thread makes a library call \textit{a} that writes a value to a stream and, as a result, another thread reads this value from the stream through a library call \textit{b} such that this does not result in a data race, then \textit{a}'s write synchronizes with \textit{b}'s read. \rSec1[iostream.forward]{Forward declarations} \rSec2[iosfwd.syn]{Header \tcode{} synopsis} \indexheader{iosfwd}% \indexlibraryglobal{basic_ios}% \indexlibraryglobal{basic_streambuf}% \indexlibraryglobal{basic_istream}% \indexlibraryglobal{basic_ostream}% \indexlibraryglobal{basic_stringbuf}% \indexlibraryglobal{basic_istringstream}% \indexlibraryglobal{basic_ostringstream}% \indexlibraryglobal{basic_stringstream}% \indexlibraryglobal{basic_filebuf}% \indexlibraryglobal{basic_ifstream}% \indexlibraryglobal{basic_ofstream}% \indexlibraryglobal{basic_fstream}% \indexlibraryglobal{istreambuf_iterator}% \indexlibraryglobal{ostreambuf_iterator}% \indexlibraryglobal{basic_syncbuf}% \indexlibraryglobal{basic_osyncstream}% \indexlibraryglobal{ios}% \indexlibraryglobal{streambuf}% \indexlibraryglobal{istream}% \indexlibraryglobal{ostream}% \indexlibraryglobal{stringbuf}% \indexlibraryglobal{istringstream}% \indexlibraryglobal{ostringstream}% \indexlibraryglobal{stringstream}% \indexlibraryglobal{filebuf}% \indexlibraryglobal{ifstream}% \indexlibraryglobal{ofstream}% \indexlibraryglobal{fstream}% \indexlibraryglobal{wstreambuf}% \indexlibraryglobal{wistream}% \indexlibraryglobal{wostream}% \indexlibraryglobal{wstringbuf}% \indexlibraryglobal{wistringstream}% \indexlibraryglobal{wostringstream}% \indexlibraryglobal{wstringstream}% \indexlibraryglobal{wfilebuf}% \indexlibraryglobal{wifstream}% \indexlibraryglobal{wofstream}% \indexlibraryglobal{wfstream}% \indexlibraryglobal{syncbuf}% \indexlibraryglobal{wsyncbuf}% \indexlibraryglobal{osyncstream}% \indexlibraryglobal{wosyncstream}% \indexlibraryglobal{fpos}% \indexlibraryglobal{streampos}% \indexlibraryglobal{wstreampos}% \indexlibraryglobal{u16streampos}% \indexlibraryglobal{u32streampos}% \begin{codeblock} namespace std { template struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template<> struct char_traits; template class allocator; template> class basic_ios; template> class basic_streambuf; template> class basic_istream; template> class basic_ostream; template> class basic_iostream; template, class Allocator = allocator> class basic_stringbuf; template, class Allocator = allocator> class basic_istringstream; template, class Allocator = allocator> class basic_ostringstream; template, class Allocator = allocator> class basic_stringstream; template> class basic_spanbuf; template> class basic_ispanstream; template> class basic_ospanstream; template> class basic_spanstream; template> class basic_filebuf; template> class basic_ifstream; template> class basic_ofstream; template> class basic_fstream; template, class Allocator = allocator> class basic_syncbuf; template, class Allocator = allocator> class basic_osyncstream; template> class istreambuf_iterator; template> class ostreambuf_iterator; using ios = basic_ios; using wios = basic_ios; using streambuf = basic_streambuf; using istream = basic_istream; using ostream = basic_ostream; using iostream = basic_iostream; using stringbuf = basic_stringbuf; using istringstream = basic_istringstream; using ostringstream = basic_ostringstream; using stringstream = basic_stringstream; using spanbuf = basic_spanbuf; using ispanstream = basic_ispanstream; using ospanstream = basic_ospanstream; using spanstream = basic_spanstream; using filebuf = basic_filebuf; using ifstream = basic_ifstream; using ofstream = basic_ofstream; using fstream = basic_fstream; using syncbuf = basic_syncbuf; using osyncstream = basic_osyncstream; using wstreambuf = basic_streambuf; using wistream = basic_istream; using wostream = basic_ostream; using wiostream = basic_iostream; using wstringbuf = basic_stringbuf; using wistringstream = basic_istringstream; using wostringstream = basic_ostringstream; using wstringstream = basic_stringstream; using wspanbuf = basic_spanbuf; using wispanstream = basic_ispanstream; using wospanstream = basic_ospanstream; using wspanstream = basic_spanstream; using wfilebuf = basic_filebuf; using wifstream = basic_ifstream; using wofstream = basic_ofstream; using wfstream = basic_fstream; using wsyncbuf = basic_syncbuf; using wosyncstream = basic_osyncstream; template class fpos; using streampos = fpos::state_type>; using wstreampos = fpos::state_type>; using u8streampos = fpos::state_type>; using u16streampos = fpos::state_type>; using u32streampos = fpos::state_type>; } \end{codeblock} \pnum Default template arguments are described as appearing both in \libheader{iosfwd} and in the synopsis of other headers but it is well-formed to include both \libheader{iosfwd} and one or more of the other headers. \begin{footnote} It is the implementation's responsibility to implement headers so that including \libheader{iosfwd} and other headers does not violate the rules about multiple occurrences of default arguments. \end{footnote} \rSec2[iostream.forward.overview]{Overview} \pnum The class template specialization \tcode{basic_ios} serves as a virtual base class for the class templates \tcode{basic_istream}, \tcode{basic_ostream}, and class templates derived from them. \tcode{basic_iostream} is a class template derived from both \tcode{basic_istream} and \tcode{basic_ostream}. \pnum The class template specialization \tcode{basic_streambuf} serves as a base class for class templates \tcode{basic_stringbuf}, \tcode{basic_filebuf}, and \tcode{basic_syncbuf}. \pnum The class template specialization \tcode{basic_istream} serves as a base class for class templates \tcode{basic_istringstream} and \tcode{basic_ifstream}. \pnum The class template specialization \tcode{basic_ostream} serves as a base class for class templates \tcode{basic_ostringstream}, \tcode{basic_ofstream}, and \tcode{basic_osyncstream}. \pnum The class template specialization \tcode{basic_iostream} serves as a base class for class templates \tcode{basic_stringstream} and \tcode{basic_fstream}. \pnum \begin{note} For each of the class templates above, the program is ill-formed if \tcode{traits::char_type} is not the same type as \tcode{charT}\iref{char.traits}. \end{note} \pnum Other \grammarterm{typedef-name}{s} define instances of class templates specialized for \tcode{char} or \keyword{wchar_t} types. \pnum Specializations of the class template \tcode{fpos} are used for specifying file position information. \begin{example} The types \tcode{streampos} and \tcode{wstreampos} are used for positioning streams specialized on \tcode{char} and \keyword{wchar_t} respectively. \end{example} \pnum \begin{note} This synopsis suggests a circularity between \tcode{streampos} and \tcode{char_traits}. An implementation can avoid this circularity by substituting equivalent types. \end{note} \rSec1[iostream.objects]{Standard iostream objects} \rSec2[iostream.syn]{Header \tcode{} synopsis} \indexheader{iostream}% \begin{codeblock} #include // see \ref{ios.syn} #include // see \ref{streambuf.syn} #include // see \ref{istream.syn} #include // see \ref{ostream.syn} namespace std { extern istream cin; extern ostream cout; extern ostream cerr; extern ostream clog; extern wistream wcin; extern wostream wcout; extern wostream wcerr; extern wostream wclog; } \end{codeblock} \rSec2[iostream.objects.overview]{Overview} \pnum In this Clause, the type name \tcode{FILE} refers to the type \tcode{FILE} declared in \libheaderref{cstdio}. \pnum The header \libheader{iostream} declares objects that associate objects with the standard C streams provided for by the functions declared in \libheader{cstdio}, and includes all the headers necessary to use these objects. \pnum The objects are constructed and the associations are established at some time prior to or during the first time an object of class \tcode{ios_base::Init} is constructed, and in any case before the body of \tcode{main}\iref{basic.start.main} begins execution. The objects are not destroyed during program execution. \begin{footnote} Constructors and destructors for objects with static storage duration can access these objects to read input from \tcode{stdin} or write output to \tcode{stdout} or \tcode{stderr}. \end{footnote} \pnum \recommended If it is possible for them to do so, implementations should initialize the objects earlier than required. \pnum The results of including \libheader{iostream} in a translation unit shall be as if \libheader{iostream} defined an instance of \tcode{ios_base::Init} with static storage duration. Each \Cpp{} library module\iref{std.modules} in a hosted implementation shall behave as if it contains an interface unit that defines an unexported \tcode{ios_base::Init} variable with ordered initialization\iref{basic.start.dynamic}. \begin{note} As a result, the definition of that variable is appearance-ordered before any declaration following the point of importation of a \Cpp{} library module. Whether such a definition exists is unobservable by a program that does not reference any of the standard iostream objects. \end{note} \pnum Mixing operations on corresponding wide- and narrow-character streams follows the same semantics as mixing such operations on \tcode{FILE}s, as specified in the C standard library. \pnum Concurrent access to a synchronized\iref{ios.members.static} standard iostream object's formatted and unformatted input\iref{istream} and output\iref{ostream} functions or a standard C stream by multiple threads does not result in a data race\iref{intro.multithread}. \begin{note} Unsynchronized concurrent use of these objects and streams by multiple threads can result in interleaved characters. \end{note} \xrefc{7.21.2} \rSec2[narrow.stream.objects]{Narrow stream objects} \indexlibraryglobal{cin}% \begin{itemdecl} istream cin; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{cin} controls input from a stream buffer associated with the object \tcode{stdin}, declared in \libheaderref{cstdio}. \pnum After the object \tcode{cin} is initialized, \tcode{cin.tie()} returns \tcode{\&cout}. Its state is otherwise the same as required for \tcode{basic_ios::init}\iref{basic.ios.cons}. \end{itemdescr} \indexlibraryglobal{cout}% \begin{itemdecl} ostream cout; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{cout} controls output to a stream buffer associated with the object \tcode{stdout}, declared in \libheaderref{cstdio}. \end{itemdescr} \indexlibraryglobal{cerr}% \begin{itemdecl} ostream cerr; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{cerr} controls output to a stream buffer associated with the object \tcode{stderr}, declared in \libheaderref{cstdio}. \pnum After the object \tcode{cerr} is initialized, \tcode{cerr.flags() \& unitbuf} is nonzero and \tcode{cerr.tie()} returns \tcode{\&cout}. Its state is otherwise the same as required for \tcode{basic_ios::init}\iref{basic.ios.cons}. \end{itemdescr} \indexlibraryglobal{clog}% \begin{itemdecl} ostream clog; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{clog} controls output to a stream buffer associated with the object \tcode{stderr}, declared in \libheaderref{cstdio}. \end{itemdescr} \rSec2[wide.stream.objects]{Wide stream objects} \indexlibraryglobal{wcin}% \begin{itemdecl} wistream wcin; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{wcin} controls input from a stream buffer associated with the object \tcode{stdin}, declared in \libheaderref{cstdio}. \pnum After the object \tcode{wcin} is initialized, \tcode{wcin.tie()} returns \tcode{\&wcout}. Its state is otherwise the same as required for \tcode{basic_ios::init}\iref{basic.ios.cons}. \end{itemdescr} \indexlibraryglobal{wcout}% \begin{itemdecl} wostream wcout; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{wcout} controls output to a stream buffer associated with the object \tcode{stdout}, declared in \libheaderref{cstdio}. \end{itemdescr} \indexlibraryglobal{wcerr}% \begin{itemdecl} wostream wcerr; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{wcerr} controls output to a stream buffer associated with the object \tcode{stderr}, declared in \libheaderref{cstdio}. \pnum After the object \tcode{wcerr} is initialized, \tcode{wcerr.flags() \& unitbuf} is nonzero and \tcode{wcerr.tie()} returns \tcode{\&wcout}. Its state is otherwise the same as required for \tcode{basic_ios::init}\iref{basic.ios.cons}. \end{itemdescr} \indexlibraryglobal{wclog}% \begin{itemdecl} wostream wclog; \end{itemdecl} \begin{itemdescr} \pnum The object \tcode{wclog} controls output to a stream buffer associated with the object \tcode{stderr}, declared in \libheaderref{cstdio}. \end{itemdescr} \rSec1[iostreams.base]{Iostreams base classes} \rSec2[ios.syn]{Header \tcode{} synopsis} \indexheader{ios}% \indexlibraryglobal{io_errc}% \begin{codeblock} #include // see \ref{iosfwd.syn} namespace std { // \ref{stream.types}, types using streamoff = @\impdef@; using streamsize = @\impdef@; // \ref{fpos}, class template \tcode{fpos} template class fpos; // \ref{ios.base}, class \tcode{ios_base} class ios_base; // \ref{ios}, class template \tcode{basic_ios} template> class basic_ios; // \ref{std.ios.manip}, manipulators ios_base& boolalpha (ios_base& str); ios_base& noboolalpha(ios_base& str); ios_base& showbase (ios_base& str); ios_base& noshowbase (ios_base& str); ios_base& showpoint (ios_base& str); ios_base& noshowpoint(ios_base& str); ios_base& showpos (ios_base& str); ios_base& noshowpos (ios_base& str); ios_base& skipws (ios_base& str); ios_base& noskipws (ios_base& str); ios_base& uppercase (ios_base& str); ios_base& nouppercase(ios_base& str); ios_base& unitbuf (ios_base& str); ios_base& nounitbuf (ios_base& str); // \ref{adjustfield.manip}, adjustfield ios_base& internal (ios_base& str); ios_base& left (ios_base& str); ios_base& right (ios_base& str); // \ref{basefield.manip}, basefield ios_base& dec (ios_base& str); ios_base& hex (ios_base& str); ios_base& oct (ios_base& str); // \ref{floatfield.manip}, floatfield ios_base& fixed (ios_base& str); ios_base& scientific (ios_base& str); ios_base& hexfloat (ios_base& str); ios_base& defaultfloat(ios_base& str); // \ref{error.reporting}, error reporting enum class @\libglobal{io_errc}@ { @\libmember{stream}{io_errc}@ = 1 }; template<> struct is_error_code_enum : public true_type { }; error_code make_error_code(io_errc e) noexcept; error_condition make_error_condition(io_errc e) noexcept; const error_category& iostream_category() noexcept; } \end{codeblock} \indexlibraryglobal{ios}% \indexlibraryglobal{basic_ios}% \indexlibraryglobal{wios}% \indexlibraryglobal{basic_ios}% \indexlibraryglobal{fpos}% \rSec2[ios.base]{Class \tcode{ios_base}} \rSec3[ios.base.general]{General} \indexlibraryglobal{ios_base}% \begin{codeblock} namespace std { class ios_base { public: class failure; // see below // \ref{ios.fmtflags}, \tcode{fmtflags} using fmtflags = @\textit{T1}@; static constexpr fmtflags boolalpha = @\unspec@; static constexpr fmtflags dec = @\unspec@; static constexpr fmtflags fixed = @\unspec@; static constexpr fmtflags hex = @\unspec@; static constexpr fmtflags internal = @\unspec@; static constexpr fmtflags left = @\unspec@; static constexpr fmtflags oct = @\unspec@; static constexpr fmtflags right = @\unspec@; static constexpr fmtflags scientific = @\unspec@; static constexpr fmtflags showbase = @\unspec@; static constexpr fmtflags showpoint = @\unspec@; static constexpr fmtflags showpos = @\unspec@; static constexpr fmtflags skipws = @\unspec@; static constexpr fmtflags unitbuf = @\unspec@; static constexpr fmtflags uppercase = @\unspec@; static constexpr fmtflags adjustfield = @\seebelow@; static constexpr fmtflags basefield = @\seebelow@; static constexpr fmtflags floatfield = @\seebelow@; // \ref{ios.iostate}, \tcode{iostate} using iostate = @\textit{T2}@; static constexpr iostate badbit = @\unspec@; static constexpr iostate eofbit = @\unspec@; static constexpr iostate failbit = @\unspec@; static constexpr iostate goodbit = @\seebelow@; // \ref{ios.openmode}, \tcode{openmode} using openmode = @\textit{T3}@; static constexpr openmode app = @\unspec@; static constexpr openmode ate = @\unspec@; static constexpr openmode binary = @\unspec@; static constexpr openmode in = @\unspec@; static constexpr openmode noreplace = @\unspec@; static constexpr openmode out = @\unspec@; static constexpr openmode trunc = @\unspec@; // \ref{ios.seekdir}, \tcode{seekdir} using seekdir = @\textit{T4}@; static constexpr seekdir beg = @\unspec@; static constexpr seekdir cur = @\unspec@; static constexpr seekdir end = @\unspec@; class Init; // \ref{fmtflags.state}, \tcode{fmtflags} state fmtflags flags() const; fmtflags flags(fmtflags fmtfl); fmtflags setf(fmtflags fmtfl); fmtflags setf(fmtflags fmtfl, fmtflags mask); void unsetf(fmtflags mask); streamsize precision() const; streamsize precision(streamsize prec); streamsize width() const; streamsize width(streamsize wide); // \ref{ios.base.locales}, locales locale imbue(const locale& loc); locale getloc() const; // \ref{ios.base.storage}, storage static int xalloc(); long& iword(int idx); void*& pword(int idx); // destructor virtual ~ios_base(); // \ref{ios.base.callback}, callbacks enum @\libmember{event}{ios_base}@ { erase_event, imbue_event, copyfmt_event }; using event_callback = void (*)(event, ios_base&, int idx); void register_callback(event_callback fn, int idx); ios_base(const ios_base&) = delete; ios_base& operator=(const ios_base&) = delete; static bool sync_with_stdio(bool sync = true); protected: ios_base(); private: static int @\exposid{index}@; // \expos long* @\exposid{iarray}@; // \expos void** @\exposid{parray}@; // \expos }; } \end{codeblock} \pnum \tcode{ios_base} defines several member types: \begin{itemize} \item a type \tcode{failure}, defined as either a class derived from \tcode{system_error} or a synonym for a class derived from \tcode{system_error}; \item a class \tcode{Init}; \item three bitmask types, \tcode{fmtflags}, \tcode{iostate}, and \tcode{openmode}; \item an enumerated type, \tcode{seekdir}. \end{itemize} \pnum It maintains several kinds of data: \begin{itemize} \item state information that reflects the integrity of the stream buffer; \item control information that influences how to interpret (format) input sequences and how to generate (format) output sequences; \item additional information that is stored by the program for its private use. \end{itemize} \pnum \begin{note} For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \tcode{static int \exposid{index}}, specifies the next available unique index for the integer or pointer arrays maintained for the private use of the program, initialized to an unspecified value; \item \tcode{long* \exposid{iarray}}, points to the first element of an arbitrary-length \tcode{long} array maintained for the private use of the program; \item \tcode{void** \exposid{parray}}, points to the first element of an arbitrary-length pointer array maintained for the private use of the program. \end{itemize} \end{note} \rSec3[ios.types]{Types} \rSec4[ios.failure]{Class \tcode{ios_base::failure}} \indexlibraryglobal{ios_base::failure}% \indexlibrarymember{ios_base}{failure}% \begin{codeblock} namespace std { class ios_base::failure : public system_error { public: explicit failure(const string& msg, const error_code& ec = io_errc::stream); explicit failure(const char* msg, const error_code& ec = io_errc::stream); }; } \end{codeblock} \pnum An implementation is permitted to define \tcode{ios_base::failure} as a synonym for a class with equivalent functionality to class \tcode{ios_base::failure} shown in this subclause. \begin{note} When \tcode{ios_base::failure} is a synonym for another type, that type needs to provide a nested type \tcode{failure} to emulate the injected-class-name. \end{note} The class \tcode{failure} defines the base class for the types of all objects thrown as exceptions, by functions in the iostreams library, to report errors detected during stream buffer operations. \pnum When throwing \tcode{ios_base::failure} exceptions, implementations should provide values of \tcode{ec} that identify the specific reason for the failure. \begin{note} Errors arising from the operating system would typically be reported as \tcode{system_category()} errors with an error value of the error number reported by the operating system. Errors arising from within the stream library would typically be reported as \tcode{error_code(io_errc::stream, iostream_category())}. \end{note} \indexlibraryctor{ios_base::failure}% \begin{itemdecl} explicit failure(const string& msg, const error_code& ec = io_errc::stream); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs the base class with \tcode{msg} and \tcode{ec}. \end{itemdescr} \indexlibraryctor{ios_base::failure}% \begin{itemdecl} explicit failure(const char* msg, const error_code& ec = io_errc::stream); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs the base class with \tcode{msg} and \tcode{ec}. \end{itemdescr} \rSec4[ios.fmtflags]{Type \tcode{ios_base::fmtflags}} \indexlibrarymember{fmtflags}{ios_base}% \begin{itemdecl} using fmtflags = @\textit{T1}@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{fmtflags} is a bitmask type\iref{bitmask.types}. Setting its elements has the effects indicated in \tref{ios.fmtflags}. \begin{libefftab}{\tcode{fmtflags} effects}{ios.fmtflags} \tcode{boolalpha} & insert and extract \tcode{bool} type in alphabetic format\\ \tcode{dec} & converts integer input or generates integer output in decimal base\\ \tcode{fixed} & generate floating-point output in fixed-point notation\\ \tcode{hex} & converts integer input or generates integer output in hexadecimal base\\ \tcode{internal} & adds fill characters at a designated internal point in certain generated output, or identical to \tcode{right} if no such point is designated\\ \tcode{left} & adds fill characters on the right (final positions) of certain generated output\\ \tcode{oct} & converts integer input or generates integer output in octal base\\ \tcode{right} & adds fill characters on the left (initial positions) of certain generated output\\ \tcode{scientific} & generates floating-point output in scientific notation\\ \tcode{showbase} & generates a prefix indicating the numeric base of generated integer output\\ \tcode{showpoint} & generates a decimal-point character unconditionally in generated floating-point output\\ \tcode{showpos} & generates a \tcode{+} sign in non-negative generated numeric output\\ \tcode{skipws} & skips leading whitespace before certain input operations\\ \tcode{unitbuf} & flushes output after each output operation\\ \tcode{uppercase} & replaces certain lowercase letters with their uppercase equivalents in generated output\\ \end{libefftab} \pnum Type \tcode{fmtflags} also defines the constants indicated in \tref{ios.fmtflags.const}. \begin{floattable}{\tcode{fmtflags} constants}{ios.fmtflags.const} {ll} \topline \lhdr{Constant} & \rhdr{Allowable values} \\ \capsep \tcode{adjustfield} & \tcode{left | right | internal} \\ \tcode{basefield} & \tcode{dec | oct | hex} \\ \tcode{floatfield} & \tcode{scientific | fixed} \\ \end{floattable} \end{itemdescr} \rSec4[ios.iostate]{Type \tcode{ios_base::iostate}} \indexlibrarymember{iostate}{ios_base}% \begin{itemdecl} using iostate = @\textit{T2}@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{iostate} is a bitmask type\iref{bitmask.types} that contains the elements indicated in \tref{ios.iostate}. \begin{libefftab}{\tcode{iostate} effects}{ios.iostate} \tcode{badbit} & indicates a loss of integrity in an input or output sequence (such as an irrecoverable read error from a file); \\ \tcode{eofbit} & indicates that an input operation reached the end of an input sequence; \\ \tcode{failbit} & indicates that an input operation failed to read the expected characters, or that an output operation failed to generate the desired characters. \\ \end{libefftab} \pnum Type \tcode{iostate} also defines the constant: \begin{itemize} \item \tcode{goodbit}, the value zero. \end{itemize} \end{itemdescr} \rSec4[ios.openmode]{Type \tcode{ios_base::openmode}} \indexlibrarymember{openmode}{ios_base}% \begin{itemdecl} using openmode = @\textit{T3}@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{openmode} is a bitmask type\iref{bitmask.types}. It contains the elements indicated in \tref{ios.openmode}. \begin{libefftab}{\tcode{openmode} effects}{ios.openmode} \tcode{app} & seek to end before each write \\ \tcode{ate} & open and seek to end immediately after opening \\ \tcode{binary} & perform input and output in binary mode (as opposed to text mode) \\ \tcode{in} & open for input \\ \tcode{noreplace} & open in exclusive mode \\ \tcode{out} & open for output \\ \tcode{trunc} & truncate an existing stream when opening \\ \end{libefftab} \end{itemdescr} \rSec4[ios.seekdir]{Type \tcode{ios_base::seekdir}} \indexlibrarymember{seekdir}{ios_base}% \begin{itemdecl} using seekdir = @\textit{T4}@; \end{itemdecl} \begin{itemdescr} \pnum The type \tcode{seekdir} is an enumerated type\iref{enumerated.types} that contains the elements indicated in \tref{ios.seekdir}. \begin{libefftabmean}{\tcode{seekdir} effects}{ios.seekdir} \tcode{beg} & request a seek (for subsequent input or output) relative to the beginning of the stream \\ \tcode{cur} & request a seek relative to the current position within the sequence \\ \tcode{end} & request a seek relative to the current end of the sequence \\ \end{libefftabmean} \end{itemdescr} \rSec4[ios.init]{Class \tcode{ios_base::Init}} \indexlibraryglobal{ios_base::Init}% \indexlibrarymember{ios_base}{Init}% \begin{codeblock} namespace std { class ios_base::Init { public: Init(); Init(const Init&) = default; ~Init(); Init& operator=(const Init&) = default; }; } \end{codeblock} \pnum The class \tcode{Init} describes an object whose construction ensures the construction of the eight objects declared in \libheader{iostream}\iref{iostream.objects} that associate file stream buffers with the standard C streams provided for by the functions declared in \libheaderref{cstdio}. \indexlibraryctor{ios_base::Init}% \begin{itemdecl} Init(); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs and initializes the objects \tcode{cin}, \tcode{cout}, \tcode{cerr}, \tcode{clog}, \tcode{wcin}, \tcode{wcout}, \tcode{wcerr}, and \tcode{wclog} if they have not already been constructed and initialized. \end{itemdescr} \indexlibrarydtor{ios_base::Init}% \begin{itemdecl} ~Init(); \end{itemdecl} \begin{itemdescr} \pnum \effects If there are no other instances of the class still in existence, calls \indexlibraryglobal{flush}% \tcode{cout.flush()}, \tcode{cerr.flush()}, \tcode{clog.flush()}, \tcode{wcout.flush()}, \tcode{wcerr.flush()}, \tcode{wclog.flush()}. \end{itemdescr} \rSec3[fmtflags.state]{State functions} \indexlibrarymember{flags}{ios_base}% \begin{itemdecl} fmtflags flags() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The format control information for both input and output. \end{itemdescr} \indexlibrarymember{flags}{ios_base}% \begin{itemdecl} fmtflags flags(fmtflags fmtfl); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{fmtfl == flags()}. \pnum \returns The previous value of \tcode{flags()}. \end{itemdescr} \indexlibrarymember{setf}{ios_base}% \begin{itemdecl} fmtflags setf(fmtflags fmtfl); \end{itemdecl} \begin{itemdescr} \pnum \effects Sets \tcode{fmtfl} in \tcode{flags()}. \pnum \returns The previous value of \tcode{flags()}. \end{itemdescr} \indexlibrarymember{setf}{ios_base}% \begin{itemdecl} fmtflags setf(fmtflags fmtfl, fmtflags mask); \end{itemdecl} \begin{itemdescr} \pnum \effects Clears \tcode{mask} in \tcode{flags()}, sets \tcode{fmtfl \& mask} in \tcode{flags()}. \pnum \returns The previous value of \tcode{flags()}. \end{itemdescr} \indexlibrarymember{unsetf}{ios_base}% \begin{itemdecl} void unsetf(fmtflags mask); \end{itemdecl} \begin{itemdescr} \pnum \effects Clears \tcode{mask} in \tcode{flags()}. \end{itemdescr} \indexlibrarymember{precision}{ios_base}% \begin{itemdecl} streamsize precision() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The precision to generate on certain output conversions. \end{itemdescr} \indexlibrarymember{precision}{ios_base}% \begin{itemdecl} streamsize precision(streamsize prec); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{prec == precision()}. \pnum \returns The previous value of \tcode{precision()}. \end{itemdescr} \indexlibrarymember{width}{ios_base}% \begin{itemdecl} streamsize width() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The minimum field width (number of characters) to generate on certain output conversions. \end{itemdescr} \indexlibrarymember{width}{ios_base}% \begin{itemdecl} streamsize width(streamsize wide); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{wide == width()}. \pnum \returns The previous value of \tcode{width()}. \end{itemdescr} \rSec3[ios.base.locales]{Functions} \indexlibrarymember{imbue}{ios_base}% \begin{itemdecl} locale imbue(const locale& loc); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls each registered callback pair \tcode{(fn, idx)}\iref{ios.base.callback} as \tcode{(*fn)(imbue_event, *this, idx)} at such a time that a call to \tcode{ios_base::getloc()} from within \tcode{fn} returns the new locale value \tcode{loc}. \pnum \ensures \tcode{loc == getloc()}. \pnum \returns The previous value of \tcode{getloc()}. \end{itemdescr} \indexlibrarymember{getloc}{ios_base}% \begin{itemdecl} locale getloc() const; \end{itemdecl} \begin{itemdescr} \pnum \returns If no locale has been imbued, a copy of the global \Cpp{} locale, \tcode{locale()}, in effect at the time of construction. Otherwise, returns the imbued locale, to be used to perform locale-dependent input and output operations. \end{itemdescr} \rSec3[ios.members.static]{Static members} \indexlibrarymember{sync_with_stdio}{ios_base}% \begin{itemdecl} static bool sync_with_stdio(bool sync = true); \end{itemdecl} \begin{itemdescr} \pnum \effects If any input or output operation has occurred using the standard streams prior to the call, the effect is \impldef{effect of calling \tcode{ios_base::sync_with_stdio} after any input or output operation on standard streams}. Otherwise, called with a \tcode{false} argument, it allows the standard streams to operate independently of the standard C streams. \pnum \returns \tcode{true} if the previous state of the standard iostream objects\iref{iostream.objects} was synchronized and otherwise returns \tcode{false}. The first time it is called, the function returns \tcode{true}. \pnum \remarks When a standard iostream object \tcode{str} is \textit{synchronized} with a standard stdio stream \tcode{f}, the effect of inserting a character \tcode{c} by \begin{codeblock} fputc(f, c); \end{codeblock} is the same as the effect of \begin{codeblock} str.rdbuf()->sputc(c); \end{codeblock} for any sequences of characters; the effect of extracting a character \tcode{c} by \begin{codeblock} c = fgetc(f); \end{codeblock} is the same as the effect of \begin{codeblock} c = str.rdbuf()->sbumpc(); \end{codeblock} for any sequences of characters; and the effect of pushing back a character \tcode{c} by \begin{codeblock} ungetc(c, f); \end{codeblock} is the same as the effect of \begin{codeblock} str.rdbuf()->sputbackc(c); \end{codeblock} for any sequence of characters. \begin{footnote} This implies that operations on a standard iostream object can be mixed arbitrarily with operations on the corresponding stdio stream. In practical terms, synchronization usually means that a standard iostream object and a standard stdio object share a buffer. \end{footnote} \end{itemdescr} \rSec3[ios.base.storage]{Storage functions} \indexlibrarymember{xalloc}{ios_base}% \begin{itemdecl} static int xalloc(); \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{index} \tcode{++}. \pnum \remarks Concurrent access to this function by multiple threads does not result in a data race\iref{intro.multithread}. \end{itemdescr} \indexlibrarymember{iword}{ios_base}% \begin{itemdecl} long& iword(int idx); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{idx} is a value obtained by a call to \tcode{xalloc}. \pnum \effects If \exposid{iarray} is a null pointer, allocates an array of \tcode{long} of unspecified size and stores a pointer to its first element in \exposid{iarray}. The function then extends the array pointed at by \exposid{iarray} as necessary to include the element \tcode{\exposid{iarray}[idx]}. Each newly allocated element of the array is initialized to zero. The reference returned is invalid after any other operation on the object. \begin{footnote} An implementation is free to implement both the integer array pointed at by \exposid{iarray} and the pointer array pointed at by \exposid{parray} as sparse data structures, possibly with a one-element cache for each. \end{footnote} However, the value of the storage referred to is retained, so that until the next call to \tcode{copyfmt}, calling \tcode{iword} with the same index yields another reference to the same value. If the function fails \begin{footnote} For example, because it cannot allocate space. \end{footnote} and \tcode{*this} is a base class subobject of a \tcode{basic_ios<>} object or subobject, the effect is equivalent to calling \tcode{basic_ios<>::setstate(badbit)} on the derived object (which may throw \tcode{failure}). \pnum \returns On success \tcode{\exposid{iarray}[idx]}. On failure, a valid \tcode{long\&} initialized to 0. \end{itemdescr} \indexlibrarymember{pword}{ios_base}% \begin{itemdecl} void*& pword(int idx); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{idx} is a value obtained by a call to \tcode{xalloc}. \pnum \effects If \exposid{parray} is a null pointer, allocates an array of pointers to \keyword{void} of unspecified size and stores a pointer to its first element in \exposid{parray}. The function then extends the array pointed at by \exposid{parray} as necessary to include the element \tcode{\exposid{parray}[idx]}. Each newly allocated element of the array is initialized to a null pointer. The reference returned is invalid after any other operation on the object. However, the value of the storage referred to is retained, so that until the next call to \tcode{copyfmt}, calling \tcode{pword} with the same index yields another reference to the same value. If the function fails \begin{footnote} For example, because it cannot allocate space. \end{footnote} and \tcode{*this} is a base class subobject of a \tcode{basic_ios<>} object or subobject, the effect is equivalent to calling \tcode{basic_ios<>::setstate(badbit)} on the derived object (which may throw \tcode{failure}). \pnum \returns On success \tcode{parray[idx]}. On failure a valid \tcode{void*\&} initialized to 0. \pnum \remarks After a subsequent call to \tcode{pword(int)} for the same object, the earlier return value may no longer be valid. \end{itemdescr} \rSec3[ios.base.callback]{Callbacks} \indexlibrarymember{register_callback}{ios_base}% \begin{itemdecl} void register_callback(event_callback fn, int idx); \end{itemdecl} \begin{itemdescr} \pnum \expects The function \tcode{fn} does not throw exceptions. \pnum \effects Registers the pair \tcode{(fn, idx)} such that during calls to \tcode{imbue()}\iref{ios.base.locales}, \tcode{copyfmt()}, or \tcode{\~{}ios_base()}\iref{ios.base.cons}, the function \tcode{fn} is called with argument \tcode{idx}. Functions registered are called when an event occurs, in opposite order of registration. Functions registered while a callback function is active are not called until the next event. \pnum \remarks Identical pairs are not merged. A function registered twice will be called twice. \end{itemdescr} \rSec3[ios.base.cons]{Constructors and destructor} \indexlibraryctor{ios_base}% \begin{itemdecl} ios_base(); \end{itemdecl} \begin{itemdescr} \pnum \effects Each \tcode{ios_base} member has an indeterminate value after construction. The object's members shall be initialized by calling \tcode{basic_ios::init} before the object's first use or before it is destroyed, whichever comes first; otherwise the behavior is undefined. \end{itemdescr} \indexlibrarydtor{ios_base}% \begin{itemdecl} ~ios_base(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls each registered callback pair \tcode{(fn, idx)}\iref{ios.base.callback} as \tcode{(*fn)(\brk{}erase_event, *this, idx)} at such time that any \tcode{ios_base} member function called from within \tcode{fn} has well-defined results. Then, any memory obtained is deallocated. \end{itemdescr} \rSec2[fpos]{Class template \tcode{fpos}} \rSec3[fpos.general]{General} \indexlibraryglobal{fpos}% \begin{codeblock} namespace std { template class fpos { public: // \ref{fpos.members}, members stateT state() const; void state(stateT); private: stateT @\exposid{st}@; // \expos }; } \end{codeblock} \rSec3[fpos.members]{Members} \indexlibrarymember{state}{fpos}% \begin{itemdecl} void state(stateT s); \end{itemdecl} \begin{itemdescr} \pnum \effects Assigns \tcode{s} to \exposid{st}. \end{itemdescr} \indexlibrarymember{state}{fpos}% \begin{itemdecl} stateT state() const; \end{itemdecl} \begin{itemdescr} \pnum \returns Current value of \exposid{st}. \end{itemdescr} \rSec3[fpos.operations]{Requirements} \pnum \indexlibraryglobal{fpos}% \indexlibraryglobal{streamoff}% An \tcode{fpos} type specifies file position information. It holds a state object whose type is equal to the template parameter \tcode{stateT}. Type \tcode{stateT} shall meet the \oldconcept{DefaultConstructible} (\tref{cpp17.defaultconstructible}), \oldconcept{CopyConstructible} (\tref{cpp17.copyconstructible}), \oldconcept{CopyAssignable} (\tref{cpp17.copyassignable}), and \oldconcept{Destructible} (\tref{cpp17.destructible}) requirements. If \tcode{is_trivially_copy_constructible_v} is \tcode{true}, then \tcode{fpos} has a trivial copy constructor. If \tcode{is_trivially_copy_assignable_v} is \tcode{true}, then \tcode{fpos} has a trivial copy assignment operator. If \tcode{is_trivially_destructible_v} is \tcode{true}, then \tcode{fpos} has a trivial destructor. All specializations of \tcode{fpos} meet the \oldconcept{DefaultConstructible}, \oldconcept{CopyConstructible}, \oldconcept{CopyAssignable}, \oldconcept{Destructible}, and \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable}) requirements. In addition, the expressions shown in \tref{fpos.operations} are valid and have the indicated semantics. In that table, \begin{itemize} \item \tcode{P} refers to a specialization of \tcode{fpos}, \item \tcode{p} and \tcode{q} refer to values of type \tcode{P} or \tcode{const P}, \item \tcode{pl} and \tcode{ql} refer to modifiable lvalues of type \tcode{P}, \item \tcode{O} refers to type \tcode{streamoff}, and \item \tcode{o} and \tcode{o2} refer to values of type \tcode{streamoff} or \tcode{const streamoff}. \end{itemize} \begin{libreqtab4c} {Position type requirements} {fpos.operations} \\ \topline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep \endfirsthead \continuedcaption\\ \hline \lhdr{Expression} & \chdr{Return type} & \chdr{Operational} & \rhdr{Assertion/note} \\ & & \chdr{semantics} & \rhdr{pre-/post-condition} \\ \capsep \endhead \tcode{P(o)} & \tcode{P} & converts from \tcode{offset} & \effects Value-initializes the state object. \\ \rowsep \tcode{P p(o);}\br \tcode{P p = o;} & & & \effects Value-initializes the state object. \br \ensures \tcode{p == P(o)} is \tcode{true}. \\ \rowsep \tcode{P()} & \tcode{P} & \tcode{P(0)} & \\ \rowsep \tcode{P p;} & & \tcode{P p(0);} & \\ \rowsep \tcode{O(p)} & \tcode{streamoff} & converts to \tcode{offset} & \tcode{P(O(p)) == p} \\ \rowsep \tcode{p == q} & \tcode{bool} & & \remarks For any two values \tcode{o} and \tcode{o2}, if \tcode{p} is obtained from \tcode{o} converted to \tcode{P} or from a copy of such \tcode{P} value and if \tcode{q} is obtained from \tcode{o2} converted to \tcode{P} or from a copy of such \tcode{P} value, then \tcode{p == q} is \tcode{true} only if \tcode{o == o2} is \tcode{true}. \\ \rowsep \tcode{p != q} & \tcode{bool} & \tcode{!(p == q)} & \\ \rowsep \tcode{p + o} & \tcode{P} & \tcode{+} offset & \remarks With \tcode{ql = p + o;}, then: \tcode{ql - o == p} \\ \rowsep \tcode{pl += o} & \tcode{P\&} & \tcode{+=} offset & \remarks With \tcode{ql = pl;} before the \tcode{+=}, then: \tcode{pl - o == ql} \\ \rowsep \tcode{p - o} & \tcode{P} & \tcode{-} offset & \remarks With \tcode{ql = p - o;}, then: \tcode{ql + o == p} \\ \rowsep \tcode{pl -= o} & \tcode{P\&} & \tcode{-=} offset & \remarks With \tcode{ql = pl;} before the \tcode{-=}, then: \tcode{pl + o == ql} \\ \rowsep \tcode{o + p} & convertible to \tcode{P} & \tcode{p + o} & \tcode{P(o + p) == p + o} \\ \rowsep \tcode{p - q} & \tcode{streamoff} & distance & \tcode{p == q + (p - q)} \\ \end{libreqtab4c} \pnum Stream operations that return a value of type \tcode{traits::pos_type} return \tcode{P(O(-1))} as an invalid value to signal an error. If this value is used as an argument to any \tcode{istream}, \tcode{ostream}, or \tcode{streambuf} member that accepts a value of type \tcode{traits::pos_type} then the behavior of that function is undefined. \indextext{undefined}% \rSec2[ios]{Class template \tcode{basic_ios}} \rSec3[ios.overview]{Overview} \indexlibraryglobal{basic_ios}% \begin{codeblock} namespace std { template> class basic_ios : public ios_base { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{iostate.flags}, flags functions explicit operator bool() const; bool operator!() const; iostate rdstate() const; void clear(iostate state = goodbit); void setstate(iostate state); bool good() const; bool eof() const; bool fail() const; bool bad() const; iostate exceptions() const; void exceptions(iostate except); // \ref{basic.ios.cons}, constructor/destructor explicit basic_ios(basic_streambuf* sb); virtual ~basic_ios(); // \ref{basic.ios.members}, members basic_ostream* tie() const; basic_ostream* tie(basic_ostream* tiestr); basic_streambuf* rdbuf() const; basic_streambuf* rdbuf(basic_streambuf* sb); basic_ios& copyfmt(const basic_ios& rhs); char_type fill() const; char_type fill(char_type ch); locale imbue(const locale& loc); char narrow(char_type c, char dfault) const; char_type widen(char c) const; basic_ios(const basic_ios&) = delete; basic_ios& operator=(const basic_ios&) = delete; protected: basic_ios(); void init(basic_streambuf* sb); void move(basic_ios& rhs); void move(basic_ios&& rhs); void swap(basic_ios& rhs) noexcept; void set_rdbuf(basic_streambuf* sb); }; } \end{codeblock} \rSec3[basic.ios.cons]{Constructors} \indexlibraryctor{basic_ios}% \begin{itemdecl} explicit basic_ios(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Assigns initial values to its member objects by calling \tcode{init(sb)}. \end{itemdescr} \indexlibraryctor{basic_ios}% \begin{itemdecl} basic_ios(); \end{itemdecl} \begin{itemdescr} \pnum \effects Leaves its member objects uninitialized. The object shall be initialized by calling \tcode{basic_ios::init} before its first use or before it is destroyed, whichever comes first; otherwise the behavior is undefined. \end{itemdescr} \indexlibrarydtor{basic_ios}% \begin{itemdecl} ~basic_ios(); \end{itemdecl} \begin{itemdescr} \pnum \remarks The destructor does not destroy \tcode{rdbuf()}. \end{itemdescr} \indexlibrarymember{init}{basic_ios}% \begin{itemdecl} void init(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \ensures The postconditions of this function are indicated in \tref{basic.ios.cons}. \begin{libefftabvalue}{\tcode{basic_ios::init()} effects}{basic.ios.cons} \tcode{rdbuf()} & \tcode{sb} \\ \tcode{tie()} & \tcode{0} \\ \tcode{rdstate()} & \tcode{goodbit} if \tcode{sb} is not a null pointer, otherwise \tcode{badbit}. \\ \tcode{exceptions()} & \tcode{goodbit} \\ \tcode{flags()} & \tcode{skipws | dec} \\ \tcode{width()} & \tcode{0} \\ \tcode{precision()} & \tcode{6} \\ \tcode{fill()} & \tcode{widen(' ')} \\ \tcode{getloc()} & a copy of the value returned by \tcode{locale()} \\ \tcode{\textit{iarray}} & a null pointer \\ \tcode{\textit{parray}} & a null pointer \\ \end{libefftabvalue} \end{itemdescr} \rSec3[basic.ios.members]{Member functions} \indexlibrarymember{tie}{basic_ios}% \begin{itemdecl} basic_ostream* tie() const; \end{itemdecl} \begin{itemdescr} \pnum \returns An output sequence that is \textit{tied} to (synchronized with) the sequence controlled by the stream buffer. \end{itemdescr} \indexlibrarymember{tie}{basic_ios}% \begin{itemdecl} basic_ostream* tie(basic_ostream* tiestr); \end{itemdecl} \begin{itemdescr} \pnum \expects If \tcode{tiestr} is not null, \tcode{tiestr} is not reachable by traversing the linked list of tied stream objects starting from \tcode{tiestr->tie()}. \pnum \ensures \tcode{tiestr == tie()}. \pnum \returns The previous value of \tcode{tie()}. \end{itemdescr} \indexlibrarymember{rdbuf}{basic_ios}% \begin{itemdecl} basic_streambuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns A pointer to the \tcode{streambuf} associated with the stream. \end{itemdescr} \indexlibrarymember{rdbuf}{basic_ios}% \begin{itemdecl} basic_streambuf* rdbuf(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{clear()}. \pnum \ensures \tcode{sb == rdbuf()}. \pnum \returns The previous value of \tcode{rdbuf()}. \end{itemdescr} \indexlibrarymember{imbue}{basic_ios}% \begin{itemdecl} locale imbue(const locale& loc); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{ios_base::imbue(loc)}\iref{ios.base.locales} and if \tcode{rdbuf() != 0} then \tcode{rdbuf()->pubimbue(loc)}\iref{streambuf.locales}. \pnum \returns The prior value of \tcode{ios_base::imbue()}. \end{itemdescr} \indexlibrarymember{narrow}{basic_ios}% \begin{itemdecl} char narrow(char_type c, char dfault) const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{use_facet>(getloc()).narrow(c, dfault)} \end{itemdescr} \indexlibrarymember{widen}{basic_ios}% \begin{itemdecl} char_type widen(char c) const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{use_facet>(getloc()).widen(c)} \end{itemdescr} \indexlibrarymember{fill}{basic_ios}% \begin{itemdecl} char_type fill() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The character used to pad (fill) an output conversion to the specified field width. \end{itemdescr} \indexlibrarymember{fill}{basic_ios}% \begin{itemdecl} char_type fill(char_type fillch); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{traits::eq(fillch, fill())}. \pnum \returns The previous value of \tcode{fill()}. \end{itemdescr} \indexlibrarymember{copyfmt}{basic_ios}% \begin{itemdecl} basic_ios& copyfmt(const basic_ios& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{(this == addressof(rhs))} is \tcode{true} does nothing. Otherwise assigns to the member objects of \tcode{*this} the corresponding member objects of \tcode{rhs} as follows: \begin{itemize} \item calls each registered callback pair \tcode{(fn, idx)} as \tcode{(*fn)(erase_event, *this, idx)}; \item then, assigns to the member objects of \tcode{*this} the corresponding member objects of \tcode{rhs}, except that \begin{itemize} \item \tcode{rdstate()}, \tcode{rdbuf()}, and \tcode{exceptions()} are left unchanged; \item the contents of arrays pointed at by \tcode{pword} and \tcode{iword} are copied, not the pointers themselves; \begin{footnote} This suggests an infinite amount of copying, but the implementation can keep track of the maximum element of the arrays that is nonzero. \end{footnote} and \item if any newly stored pointer values in \tcode{*this} point at objects stored outside the object \tcode{rhs} and those objects are destroyed when \tcode{rhs} is destroyed, the newly stored pointer values are altered to point at newly constructed copies of the objects; \end{itemize} \item then, calls each callback pair that was copied from \tcode{rhs} as \tcode{(*fn)(copyfmt_event, *this, idx)}; \item then, calls \tcode{exceptions(rhs.exceptions())}. \end{itemize} \pnum \begin{note} The second pass through the callback pairs permits a copied \tcode{pword} value to be zeroed, or to have its referent deep copied or reference counted, or to have other special action taken. \end{note} \pnum \ensures The postconditions of this function are indicated in \tref{basic.ios.copyfmt}. \begin{LibEffTab}{\tcode{basic_ios::copyfmt()} effects} {basic.ios.copyfmt}{Value}{1.2in} \tcode{rdbuf()} & \textit{unchanged} \\ \tcode{tie()} & \tcode{rhs.tie()} \\ \tcode{rdstate()} & \textit{unchanged} \\ \tcode{exceptions()} & \tcode{rhs.exceptions()} \\ \tcode{flags()} & \tcode{rhs.flags()} \\ \tcode{width()} & \tcode{rhs.width()} \\ \tcode{precision()} & \tcode{rhs.precision()} \\ \tcode{fill()} & \tcode{rhs.fill()} \\ \tcode{getloc()} & \tcode{rhs.getloc()} \\ \end{LibEffTab} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{move}{basic_ios}% \begin{itemdecl} void move(basic_ios& rhs); void move(basic_ios&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{*this} has the state that \tcode{rhs} had before the function call, except that \tcode{rdbuf()} returns \keyword{nullptr}. \tcode{rhs} is in a valid but unspecified state, except that \tcode{rhs.rdbuf()} returns the same value as it returned before the function call, and \tcode{rhs.tie()} returns \keyword{nullptr}. \end{itemdescr} \indexlibrarymember{swap}{basic_ios}% \begin{itemdecl} void swap(basic_ios& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects The states of \tcode{*this} and \tcode{rhs} are exchanged, except that \tcode{rdbuf()} returns the same value as it returned before the function call, and \tcode{rhs.rdbuf()} returns the same value as it returned before the function call. \end{itemdescr} \indexlibrarymember{set_rdbuf}{basic_ios}% \begin{itemdecl} void set_rdbuf(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{sb != nullptr} is \tcode{true}. \pnum \effects Associates the \tcode{basic_streambuf} object pointed to by \tcode{sb} with this stream without calling \tcode{clear()}. \pnum \ensures \tcode{rdbuf() == sb} is \tcode{true}. \pnum \throws Nothing. \end{itemdescr} \rSec3[iostate.flags]{Flags functions} \indexlibrarymember{operator bool}{basic_ios}% \begin{itemdecl} explicit operator bool() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!fail()}. \end{itemdescr} \indexlibrarymember{operator"!}{basic_ios}% \begin{itemdecl} bool operator!() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{fail()}. \end{itemdescr} \indexlibrarymember{rdstate}{basic_ios}% \begin{itemdecl} iostate rdstate() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The error state of the stream buffer. \end{itemdescr} \indexlibrarymember{clear}{basic_ios}% \begin{itemdecl} void clear(iostate state = goodbit); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{((state | (rdbuf() ? goodbit : badbit)) \& exceptions()) == 0}, returns. Otherwise, the function throws an object of class \tcode{ios_base::failure}\iref{ios.failure}, constructed with \impldef{argument values to construct \tcode{ios_base::failure}} argument values.% \pnum \ensures If \tcode{rdbuf() != 0} then \tcode{state == rdstate()}; otherwise \tcode{rdstate() == (state | ios_base::badbit)}. \end{itemdescr} \indexlibrarymember{setstate}{basic_ios}% \begin{itemdecl} void setstate(iostate state); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{clear(rdstate() | state)} (which may throw \tcode{ios_base::failure}\iref{ios.failure}). \end{itemdescr} \indexlibrarymember{good}{basic_ios}% \begin{itemdecl} bool good() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{rdstate() == 0} \end{itemdescr} \indexlibrarymember{eof}{basic_ios}% \begin{itemdecl} bool eof() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if \tcode{eofbit} is set in \tcode{rdstate()}. \end{itemdescr} \indexlibrarymember{fail}{basic_ios}% \begin{itemdecl} bool fail() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if \tcode{failbit} or \tcode{badbit} is set in \tcode{rdstate()}. \begin{footnote} Checking \tcode{badbit} also for \tcode{fail()} is historical practice. \end{footnote} \end{itemdescr} \indexlibrarymember{bad}{basic_ios}% \begin{itemdecl} bool bad() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if \tcode{badbit} is set in \tcode{rdstate()}. \end{itemdescr} \indexlibrarymember{exceptions}{basic_ios}% \begin{itemdecl} iostate exceptions() const; \end{itemdecl} \begin{itemdescr} \pnum \returns A mask that determines what elements set in \tcode{rdstate()} cause exceptions to be thrown. \end{itemdescr} \indexlibrarymember{exceptions}{basic_ios}% \begin{itemdecl} void exceptions(iostate except); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{clear(rdstate())}. \pnum \ensures \tcode{except == exceptions()}. \end{itemdescr} \rSec2[std.ios.manip]{\tcode{ios_base} manipulators} \rSec3[fmtflags.manip]{\tcode{fmtflags} manipulators} \pnum Each function specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{boolalpha}% \begin{itemdecl} ios_base& boolalpha(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::boolalpha)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{noboolalpha}% \begin{itemdecl} ios_base& noboolalpha(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::boolalpha)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{showbase}% \begin{itemdecl} ios_base& showbase(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::showbase)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{noshowbase}% \begin{itemdecl} ios_base& noshowbase(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::showbase)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{showpoint}% \begin{itemdecl} ios_base& showpoint(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::showpoint)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{noshowpoint}% \begin{itemdecl} ios_base& noshowpoint(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::showpoint)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{showpos}% \begin{itemdecl} ios_base& showpos(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::showpos)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{noshowpos}% \begin{itemdecl} ios_base& noshowpos(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::showpos)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{skipws}% \begin{itemdecl} ios_base& skipws(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::skipws)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{noskipws}% \begin{itemdecl} ios_base& noskipws(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::skipws)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{uppercase}% \begin{itemdecl} ios_base& uppercase(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::uppercase)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{nouppercase}% \begin{itemdecl} ios_base& nouppercase(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::uppercase)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{unitbuf}% \begin{itemdecl} ios_base& unitbuf(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::unitbuf)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{nounitbuf}% \begin{itemdecl} ios_base& nounitbuf(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::unitbuf)}. \pnum \returns \tcode{str}. \end{itemdescr} \rSec3[adjustfield.manip]{\tcode{adjustfield} manipulators} \pnum Each function specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{internal}% \begin{itemdecl} ios_base& internal(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::internal, ios_base::adjustfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{left}% \begin{itemdecl} ios_base& left(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::left, ios_base::adjustfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{right}% \begin{itemdecl} ios_base& right(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::right, ios_base::adjustfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \rSec3[basefield.manip]{\tcode{basefield} manipulators} \pnum Each function specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{dec}% \begin{itemdecl} ios_base& dec(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::dec, ios_base::basefield)}. \pnum \returns \tcode{str}. \begin{footnote} The function signature \tcode{dec(ios_base\&)} can be called by the function signature \tcode{basic_ostream\& stream::operator<<(ios_base\& (*)(ios_base\&))} to permit expressions of the form \tcode{cout << dec} to change the format flags stored in \tcode{cout}. \end{footnote} \end{itemdescr} \indexlibraryglobal{hex}% \begin{itemdecl} ios_base& hex(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::hex, ios_base::basefield)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{oct}% \begin{itemdecl} ios_base& oct(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::oct, ios_base::basefield)}. \pnum \returns \tcode{str}. \end{itemdescr} \rSec3[floatfield.manip]{\tcode{floatfield} manipulators} \pnum Each function specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{fixed}% \begin{itemdecl} ios_base& fixed(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::fixed, ios_base::floatfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{scientific}% \begin{itemdecl} ios_base& scientific(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::scientific, ios_base::floatfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \indexlibraryglobal{hexfloat}% \begin{itemdecl} ios_base& hexfloat(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \pnum \begin{note} \tcode{ios_base::hex} cannot be used to specify a hexadecimal floating-point format, because it is not part of \tcode{ios_base::floatfield} (\tref{ios.fmtflags.const}). \end{note} \indexlibraryglobal{defaultfloat}% \begin{itemdecl} ios_base& defaultfloat(ios_base& str); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{str.unsetf(ios_base::floatfield)}. \pnum \returns \tcode{str}. \end{itemdescr} \rSec2[error.reporting]{Error reporting} \indexlibrarymember{make_error_code}{io_errc}% \begin{itemdecl} error_code make_error_code(io_errc e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{error_code(static_cast(e), iostream_category())}. \end{itemdescr} \indexlibrarymember{make_error_condition}{io_errc}% \begin{itemdecl} error_condition make_error_condition(io_errc e) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{error_condition(static_cast(e), iostream_category())}. \end{itemdescr} \indexlibraryglobal{iostream_category}% \begin{itemdecl} const error_category& iostream_category() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A reference to an object of a type derived from class \tcode{error_category}. \pnum The object's \tcode{default_error_condition} and \tcode{equivalent} virtual functions shall behave as specified for the class \tcode{error_category}. The object's \tcode{name} virtual function shall return a pointer to the string \tcode{"iostream"}. \end{itemdescr} \rSec1[stream.buffers]{Stream buffers} \rSec2[streambuf.syn]{Header \tcode{} synopsis} \indexheader{streambuf}% \indexlibraryglobal{streambuf}% \indexlibraryglobal{basic_streambuf}% \indexlibraryglobal{wstreambuf}% \indexlibraryglobal{basic_streambuf}% \begin{codeblock} namespace std { // \ref{streambuf}, class template \tcode{basic_streambuf} template> class basic_streambuf; using streambuf = basic_streambuf; using wstreambuf = basic_streambuf; } \end{codeblock} \pnum The header \libheader{streambuf} defines types that control input from and output to \textit{character} sequences. \rSec2[streambuf.reqts]{Stream buffer requirements} \pnum Stream buffers can impose various constraints on the sequences they control. Some constraints are: \begin{itemize} \item The controlled input sequence can be not readable. \item The controlled output sequence can be not writable. \item The controlled sequences can be associated with the contents of other representations for character sequences, such as external files. \item The controlled sequences can support operations \textit{directly} to or from associated sequences. \item The controlled sequences can impose limitations on how the program can read characters from a sequence, write characters to a sequence, put characters back into an input sequence, or alter the stream position. \end{itemize} \pnum Each sequence is characterized by three pointers which, if non-null, all point into the same \tcode{charT} array object. The array object represents, at any moment, a (sub)sequence of characters from the sequence. Operations performed on a sequence alter the values stored in these pointers, perform reads and writes directly to or from associated sequences, and alter ``the stream position'' and conversion state as needed to maintain this subsequence relationship. The three pointers are: \begin{itemize} \item the \term{beginning pointer}, or lowest element address in the array (called \tcode{xbeg} here); \item the \term{next pointer}, or next element address that is a current candidate for reading or writing (called \tcode{xnext} here); \item the \term{end pointer}, or first element address beyond the end of the array (called \tcode{xend} here). \end{itemize} \pnum The following semantic constraints shall always apply for any set of three pointers for a sequence, using the pointer names given immediately above: \begin{itemize} \item If \tcode{xnext} is not a null pointer, then \tcode{xbeg} and \tcode{xend} shall also be non-null pointers into the same \tcode{charT} array, as described above; otherwise, \tcode{xbeg} and \tcode{xend} shall also be null. \item If \tcode{xnext} is not a null pointer and \tcode{xnext < xend} for an output sequence, then a \term{write position} is available. In this case, \tcode{*xnext} shall be assignable as the next element to write (to put, or to store a character value, into the sequence). \item If \tcode{xnext} is not a null pointer and \tcode{xbeg < xnext} for an input sequence, then a \term{putback position} is available. In this case, \tcode{xnext[-1]} shall have a defined value and is the next (preceding) element to store a character that is put back into the input sequence. \item If \tcode{xnext} is not a null pointer and \tcode{xnext < xend} for an input sequence, then a \term{read position} is available. In this case, \tcode{*xnext} shall have a defined value and is the next element to read (to get, or to obtain a character value, from the sequence). \end{itemize} \rSec2[streambuf]{Class template \tcode{basic_streambuf}} \rSec3[streambuf.general]{General} \indexlibraryglobal{basic_streambuf}% \begin{codeblock} namespace std { template> class basic_streambuf { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; virtual ~basic_streambuf(); // \ref{streambuf.locales}, locales locale pubimbue(const locale& loc); locale getloc() const; // \ref{streambuf.buffer}, buffer and positioning basic_streambuf* pubsetbuf(char_type* s, streamsize n); pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); int pubsync(); // get and put areas // \ref{streambuf.pub.get}, get area streamsize in_avail(); int_type snextc(); int_type sbumpc(); int_type sgetc(); streamsize sgetn(char_type* s, streamsize n); // \ref{streambuf.pub.pback}, putback int_type sputbackc(char_type c); int_type sungetc(); // \ref{streambuf.pub.put}, put area int_type sputc(char_type c); streamsize sputn(const char_type* s, streamsize n); protected: basic_streambuf(); basic_streambuf(const basic_streambuf& rhs); basic_streambuf& operator=(const basic_streambuf& rhs); void swap(basic_streambuf& rhs); // \ref{streambuf.get.area}, get area access char_type* eback() const; char_type* gptr() const; char_type* egptr() const; void gbump(int n); void setg(char_type* gbeg, char_type* gnext, char_type* gend); // \ref{streambuf.put.area}, put area access char_type* pbase() const; char_type* pptr() const; char_type* epptr() const; void pbump(int n); void setp(char_type* pbeg, char_type* pend); // \ref{streambuf.virtuals}, virtual functions // \ref{streambuf.virt.locales}, locales virtual void imbue(const locale& loc); // \ref{streambuf.virt.buffer}, buffer management and positioning virtual basic_streambuf* setbuf(char_type* s, streamsize n); virtual pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); virtual pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); virtual int sync(); // \ref{streambuf.virt.get}, get area virtual streamsize showmanyc(); virtual streamsize xsgetn(char_type* s, streamsize n); virtual int_type underflow(); virtual int_type uflow(); // \ref{streambuf.virt.pback}, putback virtual int_type pbackfail(int_type c = traits::eof()); // \ref{streambuf.virt.put}, put area virtual streamsize xsputn(const char_type* s, streamsize n); virtual int_type overflow(int_type c = traits::eof()); }; } \end{codeblock} \pnum The class template \tcode{basic_streambuf} serves as a base class for deriving various \term{stream buffers} whose objects each control two \term{character sequences}: \begin{itemize} \item a character \term{input sequence}; \item a character \term{output sequence}. \end{itemize} \rSec3[streambuf.cons]{Constructors} \indexlibraryctor{basic_streambuf}% \begin{itemdecl} basic_streambuf(); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes: \begin{footnote} The default constructor is protected for class \tcode{basic_streambuf} to assure that only objects for classes derived from this class can be constructed. \end{footnote} \begin{itemize} \item all pointer member objects to null pointers, \item the \tcode{getloc()} member to a copy of the global locale, \tcode{locale()}, at the time of construction. \end{itemize} \pnum \remarks Once the \tcode{getloc()} member is initialized, results of calling locale member functions, and of members of facets so obtained, can safely be cached until the next time the member \tcode{imbue} is called. \end{itemdescr} \indexlibraryctor{basic_streambuf}% \begin{itemdecl} basic_streambuf(const basic_streambuf& rhs); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{eback() == rhs.eback()} \item \tcode{gptr() == rhs.gptr()} \item \tcode{egptr() == rhs.egptr()} \item \tcode{pbase() == rhs.pbase()} \item \tcode{pptr() == rhs.pptr()} \item \tcode{epptr() == rhs.epptr()} \item \tcode{getloc() == rhs.getloc()} \end{itemize} \end{itemdescr} \indexlibrarydtor{basic_streambuf}% \begin{itemdecl} ~basic_streambuf(); \end{itemdecl} \begin{itemdescr} \pnum \effects None. \end{itemdescr} \rSec3[streambuf.members]{Public member functions} \rSec4[streambuf.locales]{Locales} \indexlibrarymember{pubimbue}{basic_streambuf}% \begin{itemdecl} locale pubimbue(const locale& loc); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{imbue(loc)}. \pnum \ensures \tcode{loc == getloc()}. \pnum \returns Previous value of \tcode{getloc()}. \end{itemdescr} \indexlibrarymember{getloc}{basic_streambuf}% \begin{itemdecl} locale getloc() const; \end{itemdecl} \begin{itemdescr} \pnum \returns If \tcode{pubimbue()} has ever been called, then the last value of \tcode{loc} supplied, otherwise the current global locale, \tcode{locale()}, in effect at the time of construction. If called after \tcode{pubimbue()} has been called but before \tcode{pubimbue} has returned (i.e., from within the call of \tcode{imbue()}) then it returns the previous value. \end{itemdescr} \rSec4[streambuf.buffer]{Buffer management and positioning} \indexlibrarymember{pubsetbuf}{basic_streambuf}% \begin{itemdecl} basic_streambuf* pubsetbuf(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{setbuf(s, n)}. \end{itemdescr} \indexlibrarymember{pubseekoff}{basic_streambuf}% \begin{itemdecl} pos_type pubseekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{seekoff(off, way, which)}. \end{itemdescr} \indexlibrarymember{pubseekpos}{basic_streambuf}% \begin{itemdecl} pos_type pubseekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{seekpos(sp, which)}. \end{itemdescr} \indexlibrarymember{pubsync}{basic_streambuf}% \begin{itemdecl} int pubsync(); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{sync()}. \end{itemdescr} \rSec4[streambuf.pub.get]{Get area} \indexlibrarymember{in_avail}{basic_streambuf}% \begin{itemdecl} streamsize in_avail(); \end{itemdecl} \begin{itemdescr} \pnum \returns If a read position is available, returns \tcode{egptr() - gptr()}. Otherwise returns \tcode{showmanyc()}\iref{streambuf.virt.get}. \end{itemdescr} \indexlibrarymember{snextc}{basic_streambuf}% \begin{itemdecl} int_type snextc(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{sbumpc()}. \pnum \returns If that function returns \tcode{traits::eof()}, returns \tcode{traits::eof()}. Otherwise, returns \tcode{sgetc()}. \end{itemdescr} \indexlibrarymember{sbumpc}{basic_streambuf}% \begin{itemdecl} int_type sbumpc(); \end{itemdecl} \begin{itemdescr} \pnum \effects If the input sequence read position is not available, returns \tcode{uflow()}. Otherwise, returns \tcode{traits::to_int_type(*gptr())} and increments the next pointer for the input sequence. \end{itemdescr} \indexlibrarymember{sgetc}{basic_streambuf}% \begin{itemdecl} int_type sgetc(); \end{itemdecl} \begin{itemdescr} \pnum \returns If the input sequence read position is not available, returns \tcode{underflow()}. Otherwise, returns \tcode{traits::to_int_type(*gptr())}. \end{itemdescr} \indexlibrarymember{sgetn}{basic_streambuf}% \begin{itemdecl} streamsize sgetn(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{xsgetn(s, n)}. \end{itemdescr} \rSec4[streambuf.pub.pback]{Putback} \indexlibrarymember{sputbackc}{basic_streambuf}% \begin{itemdecl} int_type sputbackc(char_type c); \end{itemdecl} \begin{itemdescr} \pnum \effects If the input sequence putback position is not available, or if \tcode{traits::eq(c, gptr()[-1])} is \tcode{false}, returns \tcode{pbackfail(traits::to_int_type(c))}. Otherwise, decrements the next pointer for the input sequence and returns \tcode{traits::to_int_type(*gptr())}. \end{itemdescr} \indexlibrarymember{sungetc}{basic_streambuf}% \begin{itemdecl} int_type sungetc(); \end{itemdecl} \begin{itemdescr} \pnum \effects If the input sequence putback position is not available, returns \tcode{pbackfail()}. Otherwise, decrements the next pointer for the input sequence and returns \tcode{traits::to_int_type(*gptr())}. \end{itemdescr} \rSec4[streambuf.pub.put]{Put area} \indexlibrarymember{sputc}{basic_streambuf}% \begin{itemdecl} int_type sputc(char_type c); \end{itemdecl} \begin{itemdescr} \pnum \effects If the output sequence write position is not available, returns \tcode{overflow(traits::to_int_type(c))}. Otherwise, stores \tcode{c} at the next pointer for the output sequence, increments the pointer, and returns \tcode{traits::to_int_type(c)}. \end{itemdescr} \indexlibrarymember{sputn}{basic_streambuf}% \begin{itemdecl} streamsize sputn(const char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{xsputn(s, n)}. \end{itemdescr} \rSec3[streambuf.protected]{Protected member functions} \rSec4[streambuf.assign]{Assignment} \indexlibrarymember{operator=}{basic_streambuf}% \begin{itemdecl} basic_streambuf& operator=(const basic_streambuf& rhs); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{eback() == rhs.eback()} \item \tcode{gptr() == rhs.gptr()} \item \tcode{egptr() == rhs.egptr()} \item \tcode{pbase() == rhs.pbase()} \item \tcode{pptr() == rhs.pptr()} \item \tcode{epptr() == rhs.epptr()} \item \tcode{getloc() == rhs.getloc()} \end{itemize} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{basic_streambuf}% \begin{itemdecl} void swap(basic_streambuf& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Swaps the data members of \tcode{rhs} and \tcode{*this}. \end{itemdescr} \rSec4[streambuf.get.area]{Get area access} \indexlibrarymember{eback}{basic_streambuf}% \begin{itemdecl} char_type* eback() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The beginning pointer for the input sequence. \end{itemdescr} \indexlibrarymember{gptr}{basic_streambuf}% \begin{itemdecl} char_type* gptr() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The next pointer for the input sequence. \end{itemdescr} \indexlibrarymember{egptr}{basic_streambuf}% \begin{itemdecl} char_type* egptr() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The end pointer for the input sequence. \end{itemdescr} \indexlibrarymember{gbump}{basic_streambuf}% \begin{itemdecl} void gbump(int n); \end{itemdecl} \begin{itemdescr} \pnum \effects Adds \tcode{n} to the next pointer for the input sequence. \end{itemdescr} \indexlibrarymember{setg}{basic_streambuf}% \begin{itemdecl} void setg(char_type* gbeg, char_type* gnext, char_type* gend); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{gbeg}{gnext}, \range{gbeg}{gend}, and \range{gnext}{gend} are all valid ranges. \pnum \ensures \tcode{gbeg == eback()}, \tcode{gnext == gptr()}, and \tcode{gend == egptr()} are all \tcode{true}. \end{itemdescr} \rSec4[streambuf.put.area]{Put area access} \indexlibrarymember{pbase}{basic_streambuf}% \begin{itemdecl} char_type* pbase() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The beginning pointer for the output sequence. \end{itemdescr} \indexlibrarymember{pptr}{basic_streambuf}% \begin{itemdecl} char_type* pptr() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The next pointer for the output sequence. \end{itemdescr} \indexlibrarymember{epptr}{basic_streambuf}% \begin{itemdecl} char_type* epptr() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The end pointer for the output sequence. \end{itemdescr} \indexlibrarymember{pbump}{basic_streambuf}% \begin{itemdecl} void pbump(int n); \end{itemdecl} \begin{itemdescr} \pnum \effects Adds \tcode{n} to the next pointer for the output sequence. \end{itemdescr} \indexlibrarymember{setp}{basic_streambuf}% \begin{itemdecl} void setp(char_type* pbeg, char_type* pend); \end{itemdecl} \begin{itemdescr} \pnum \expects \range{pbeg}{pend} is a valid range. \pnum \ensures \tcode{pbeg == pbase()}, \tcode{pbeg == pptr()}, and \tcode{pend == epptr()} are all \tcode{true}. \end{itemdescr} \rSec3[streambuf.virtuals]{Virtual functions} \rSec4[streambuf.virt.locales]{Locales} \indexlibrarymember{imbue}{basic_streambuf}% \begin{itemdecl} void imbue(const locale&); \end{itemdecl} \begin{itemdescr} \pnum \effects Change any translations based on locale. \pnum \remarks Allows the derived class to be informed of changes in locale at the time they occur. Between invocations of this function a class derived from streambuf can safely cache results of calls to locale functions and to members of facets so obtained. \pnum \default Does nothing. \end{itemdescr} \rSec4[streambuf.virt.buffer]{Buffer management and positioning} \indexlibrarymember{setbuf}{basic_streambuf}% \begin{itemdecl} basic_streambuf* setbuf(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Influences stream buffering in a way that is defined separately for each class derived from \tcode{basic_streambuf} in this Clause\iref{stringbuf.virtuals,filebuf.virtuals}. \pnum \default Does nothing. Returns \keyword{this}. \end{itemdescr} \indexlibrarymember{seekoff}{basic_streambuf}% \begin{itemdecl} pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from \tcode{basic_streambuf} in this Clause\iref{stringbuf.virtuals,filebuf.virtuals}. \pnum \default Returns \tcode{pos_type(off_type(-1))}. \end{itemdescr} \indexlibrarymember{seekpos}{basic_streambuf}% \begin{itemdecl} pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Alters the stream positions within one or more of the controlled sequences in a way that is defined separately for each class derived from \tcode{basic_streambuf} in this Clause\iref{stringbuf,filebuf}. \pnum \default Returns \tcode{pos_type(off_type(-1))}. \end{itemdescr} \indexlibrarymember{sync}{basic_streambuf}% \begin{itemdecl} int sync(); \end{itemdecl} \begin{itemdescr} \pnum \effects Synchronizes the controlled sequences with the arrays. That is, if \tcode{pbase()} is non-null the characters between \tcode{pbase()} and \tcode{pptr()} are written to the controlled sequence. The pointers may then be reset as appropriate. \pnum \returns \tcode{-1} on failure. What constitutes failure is determined by each derived class\iref{filebuf.virtuals}. \pnum \default Returns zero. \end{itemdescr} \rSec4[streambuf.virt.get]{Get area} \indexlibrarymember{showmanyc}{basic_streambuf}% \begin{itemdecl} streamsize showmanyc();@ \begin{footnote} The morphemes of \tcode{showmanyc} are ``es-how-many-see'', not ``show-manic''. \end{footnote}@ \end{itemdecl} \begin{itemdescr} \pnum \returns An estimate of the number of characters available in the sequence, or $-1$. If it returns a positive value, then successive calls to \tcode{underflow()} will not return \tcode{traits::eof()} until at least that number of characters have been extracted from the stream. If \tcode{showmanyc()} returns $-1$, then calls to \tcode{underflow()} or \tcode{uflow()} will fail. \begin{footnote} \tcode{underflow} or \tcode{uflow} can fail by throwing an exception prematurely. The intention is not only that the calls will not return \tcode{eof()} but that they will return ``immediately''. \end{footnote} \pnum \default Returns zero. \pnum \remarks Uses \tcode{traits::eof()}. \end{itemdescr} \indexlibrarymember{xsgetn}{basic_streambuf}% \begin{itemdecl} streamsize xsgetn(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Assigns up to \tcode{n} characters to successive elements of the array whose first element is designated by \tcode{s}. The characters assigned are read from the input sequence as if by repeated calls to \tcode{sbumpc()}. Assigning stops when either \tcode{n} characters have been assigned or a call to \tcode{sbumpc()} would return \tcode{traits::eof()}. \pnum \returns The number of characters assigned. \begin{footnote} Classes derived from \tcode{basic_streambuf} can provide more efficient ways to implement \tcode{xsgetn()} and \tcode{xsputn()} by overriding these definitions from the base class. \end{footnote} \pnum \remarks Uses \tcode{traits::eof()}. \end{itemdescr} \indexlibrarymember{underflow}{basic_streambuf}% \begin{itemdecl} int_type underflow(); \end{itemdecl} \begin{itemdescr} \pnum The \term{pending sequence} of characters is defined as the concatenation of \begin{itemize} \item the empty sequence if \tcode{gptr()} is null, otherwise the characters in \range{gptr()}{egptr()}, followed by \item some (possibly empty) sequence of characters read from the input sequence. \end{itemize} \pnum The \term{result character} is the first character of the pending sequence if it is non-empty, otherwise the next character that would be read from the input sequence. \pnum The \term{backup sequence} is the empty sequence if \tcode{eback()} is null, otherwise the characters in \range{eback()}{gptr()}. \pnum \effects The function sets up the \tcode{gptr()} and \tcode{egptr()} such that if the pending sequence is non-empty, then \tcode{egptr()} is non-null and the characters in \range{gptr()}{egptr()} are the characters in the pending sequence, otherwise either \tcode{gptr()} is null or \tcode{gptr() == egptr()}. \pnum If \tcode{eback()} and \tcode{gptr()} are non-null then the function is not constrained as to their contents, but the ``usual backup condition'' is that either \begin{itemize} \item the backup sequence contains at least \tcode{gptr() - eback()} characters, in which case the characters in \range{eback()}{gptr()} agree with the last \tcode{gptr() - eback()} characters of the backup sequence, or \item the characters in \range{gptr() - n}{gptr()} agree with the backup sequence (where \tcode{n} is the length of the backup sequence). \end{itemize} \pnum \returns \tcode{traits::to_int_type(c)}, where \tcode{c} is the first \textit{character} of the \term{pending sequence}, without moving the input sequence position past it. If the pending sequence is null then the function returns \tcode{traits::eof()} to indicate failure. \pnum \default Returns \tcode{traits::eof()}. \pnum \remarks The public members of \tcode{basic_streambuf} call this virtual function only if \tcode{gptr()} is null or \tcode{gptr() >= egptr()}. \end{itemdescr} \indexlibrarymember{uflow}{basic_streambuf}% \begin{itemdecl} int_type uflow(); \end{itemdecl} \begin{itemdescr} \pnum \expects The constraints are the same as for \tcode{underflow()}, except that the result character is transferred from the pending sequence to the backup sequence, and the pending sequence is not empty before the transfer. \pnum \default Calls \tcode{underflow()}. If \tcode{underflow()} returns \tcode{traits::eof()}, returns \tcode{traits::eof()}. Otherwise, returns the value of \tcode{traits::to_int_type(*gptr())} and increments the value of the next pointer for the input sequence. \pnum \returns \tcode{traits::eof()} to indicate failure. \end{itemdescr} \rSec4[streambuf.virt.pback]{Putback} \indexlibrarymember{pbackfail}{basic_streambuf}% \begin{itemdecl} int_type pbackfail(int_type c = traits::eof()); \end{itemdecl} \begin{itemdescr} \pnum The \term{pending sequence} is defined as for \tcode{underflow()}, with the modifications that \begin{itemize} \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true}, then the input sequence is backed up one character before the pending sequence is determined. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{false}, then \tcode{c} is prepended. Whether the input sequence is backed up or modified in any other way is unspecified. \end{itemize} \pnum \ensures On return, the constraints of \tcode{gptr()}, \tcode{eback()}, and \tcode{pptr()} are the same as for \tcode{underflow()}. \pnum \returns \tcode{traits::eof()} to indicate failure. Failure may occur because the input sequence could not be backed up, or if for some other reason the pointers cannot be set consistent with the constraints. \tcode{pbackfail()} is called only when put back has really failed. \pnum Returns some value other than \tcode{traits::eof()} to indicate success. \pnum \default Returns \tcode{traits::eof()}. \pnum \remarks The public functions of \tcode{basic_streambuf} call this virtual function only when \tcode{gptr()} is null, \tcode{gptr() == eback()}, or \tcode{traits::eq(traits::to_char_type(c), gptr()[-1])} returns \tcode{false}. Other calls shall also satisfy that constraint. \end{itemdescr} \rSec4[streambuf.virt.put]{Put area} \indexlibrarymember{xsputn}{basic_streambuf}% \begin{itemdecl} streamsize xsputn(const char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Writes up to \tcode{n} characters to the output sequence as if by repeated calls to \tcode{sputc(c)}. The characters written are obtained from successive elements of the array whose first element is designated by \tcode{s}. Writing stops when either \tcode{n} characters have been written or a call to \tcode{sputc(c)} would return \tcode{traits::eof()}. It is unspecified whether the function calls \tcode{overflow()} when \tcode{pptr() == epptr()} becomes \tcode{true} or whether it achieves the same effects by other means. \pnum \returns The number of characters written. \end{itemdescr} \indexlibrarymember{overflow}{basic_streambuf}% \begin{itemdecl} int_type overflow(int_type c = traits::eof()); \end{itemdecl} \begin{itemdescr} % NOCHECK: order \pnum \effects Consumes some initial subsequence of the characters of the \term{pending sequence}. The pending sequence is defined as the concatenation of \begin{itemize} \item the empty sequence if \tcode{pbase()} is null, otherwise the \tcode{pptr() - pbase()} characters beginning at \tcode{pbase()}, followed by \item the empty sequence if \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true}, otherwise the sequence consisting of \tcode{c}. \end{itemize} \pnum \expects Every overriding definition of this virtual function obeys the following constraints: \begin{itemize} \item The effect of consuming a character on the associated output sequence is specified. \begin{footnote} That is, for each class derived from a specialization of \tcode{basic_streambuf} in this Clause\iref{stringbuf,filebuf}, a specification of how consuming a character effects the associated output sequence is given. There is no requirement on a program-defined class. \end{footnote} \item Let \tcode{r} be the number of characters in the pending sequence not consumed. If \tcode{r} is nonzero then \tcode{pbase()} and \tcode{pptr()} are set so that: \tcode{pptr() - pbase() == r} and the \tcode{r} characters starting at \tcode{pbase()} are the associated output stream. In case \tcode{r} is zero (all characters of the pending sequence have been consumed) then either \tcode{pbase()} is set to \keyword{nullptr}, or \tcode{pbase()} and \tcode{pptr()} are both set to the same non-null value. \item The function may fail if either appending some character to the associated output stream fails or if it is unable to establish \tcode{pbase()} and \tcode{pptr()} according to the above rules. \end{itemize} \pnum \returns \tcode{traits::eof()} or throws an exception if the function fails. Otherwise, returns some value other than \tcode{traits::eof()} to indicate success. \begin{footnote} Typically, \tcode{overflow} returns \tcode{c} to indicate success, except when \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true}, in which case it returns \tcode{traits::not_eof(c)}. \end{footnote} \pnum \default Returns \tcode{traits::eof()}. \pnum \remarks The member functions \tcode{sputc()} and \tcode{sputn()} call this function in case that no room can be found in the put buffer enough to accommodate the argument character sequence. \end{itemdescr} \rSec1[iostream.format]{Formatting and manipulators} \rSec2[istream.syn]{Header \tcode{} synopsis} \indexheader{istream}% \begin{codeblock} namespace std { // \ref{istream}, class template \tcode{basic_istream} template> class basic_istream; using istream = basic_istream; using wistream = basic_istream; // \ref{iostreamclass}, class template \tcode{basic_iostream} template> class basic_iostream; using iostream = basic_iostream; using wiostream = basic_iostream; // \ref{istream.manip}, standard \tcode{basic_istream} manipulators template basic_istream& ws(basic_istream& is); // \ref{istream.rvalue}, rvalue stream extraction template Istream&& operator>>(Istream&& is, T&& x); } \end{codeblock} \indexlibraryglobal{istream}% \indexlibraryglobal{basic_istream}% \indexlibraryglobal{wistream}% \indexlibraryglobal{basic_istream}% \rSec2[ostream.syn]{Header \tcode{} synopsis} \indexheader{ostream}% \begin{codeblock} namespace std { // \ref{ostream}, class template \tcode{basic_ostream} template> class basic_ostream; using ostream = basic_ostream; using wostream = basic_ostream; // \ref{ostream.manip}, standard \tcode{basic_ostream} manipulators template basic_ostream& endl(basic_ostream& os); template basic_ostream& ends(basic_ostream& os); template basic_ostream& flush(basic_ostream& os); template basic_ostream& emit_on_flush(basic_ostream& os); template basic_ostream& noemit_on_flush(basic_ostream& os); template basic_ostream& flush_emit(basic_ostream& os); // \ref{ostream.rvalue}, rvalue stream insertion template Ostream&& operator<<(Ostream&& os, const T& x); // \ref{ostream.formatted.print}, print functions template void print(ostream& os, format_string fmt, Args&&... args); template void println(ostream& os, format_string fmt, Args&&... args); void println(ostream& os); void vprint_unicode(ostream& os, string_view fmt, format_args args); void vprint_nonunicode(ostream& os, string_view fmt, format_args args); } \end{codeblock} \indexlibraryglobal{ostream}% \indexlibraryglobal{basic_ostream}% \indexlibraryglobal{wostream}% \indexlibraryglobal{basic_ostream}% \rSec2[iomanip.syn]{Header \tcode{} synopsis} \indexheader{iomanip}% \begin{codeblock} namespace std { // \ref{std.manip}, standard manipulators @\unspec@ resetiosflags(ios_base::fmtflags mask); @\unspec@ setiosflags (ios_base::fmtflags mask); @\unspec@ setbase(int base); template @\unspec@ setfill(charT c); @\unspec@ setprecision(int n); @\unspec@ setw(int n); // \ref{ext.manip}, extended manipulators template @\unspec@ get_money(moneyT& mon, bool intl = false); template @\unspec@ put_money(const moneyT& mon, bool intl = false); template @\unspec@ get_time(tm* tmb, const charT* fmt); template @\unspec@ put_time(const tm* tmb, const charT* fmt); // \ref{quoted.manip}, quoted manipulators template @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); template @\unspec@ quoted(const basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); template @\unspec@ quoted(basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); template @\unspec@ quoted(basic_string_view s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); } \end{codeblock} \rSec2[print.syn]{Header \tcode{} synopsis} \indexheader{print}% \begin{codeblock} namespace std { // \ref{print.fun}, print functions template void print(format_string fmt, Args&&... args); template void print(FILE* stream, format_string fmt, Args&&... args); template void println(format_string fmt, Args&&... args); void println(); template void println(FILE* stream, format_string fmt, Args&&... args); void println(FILE* stream); void vprint_unicode(string_view fmt, format_args args); void vprint_unicode(FILE* stream, string_view fmt, format_args args); void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args); void vprint_nonunicode(string_view fmt, format_args args); void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args); } \end{codeblock} \rSec2[input.streams]{Input streams} \rSec3[input.streams.general]{General} \pnum The header \libheader{istream} defines two class templates and a function template that control input from a stream buffer, along with a function template that extracts from stream rvalues. \rSec3[istream]{Class template \tcode{basic_istream}} \rSec4[istream.general]{General} \pnum When a function is specified with a type placeholder of \tcode{\placeholder{extended-floating-point-type}}, the implementation provides overloads for all cv-unqualified extended floating-point types\iref{basic.fundamental} in lieu of \tcode{\placeholder{extended-floating-\brk{}point-type}}. \indexlibraryglobal{basic_istream}% \begin{codeblock} namespace std { template> class basic_istream : virtual public basic_ios { public: // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{istream.cons}, constructor/destructor explicit basic_istream(basic_streambuf* sb); virtual ~basic_istream(); // \ref{istream.sentry}, prefix/suffix class sentry; // \ref{istream.formatted}, formatted input basic_istream& operator>>(basic_istream& (*pf)(basic_istream&)); basic_istream& operator>>(basic_ios& (*pf)(basic_ios&)); basic_istream& operator>>(ios_base& (*pf)(ios_base&)); basic_istream& operator>>(bool& n); basic_istream& operator>>(short& n); basic_istream& operator>>(unsigned short& n); basic_istream& operator>>(int& n); basic_istream& operator>>(unsigned int& n); basic_istream& operator>>(long& n); basic_istream& operator>>(unsigned long& n); basic_istream& operator>>(long long& n); basic_istream& operator>>(unsigned long long& n); basic_istream& operator>>(float& f); basic_istream& operator>>(double& f); basic_istream& operator>>(long double& f); basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& f); basic_istream& operator>>(void*& p); basic_istream& operator>>(basic_streambuf* sb); // \ref{istream.unformatted}, unformatted input streamsize gcount() const; int_type get(); basic_istream& get(char_type& c); basic_istream& get(char_type* s, streamsize n); basic_istream& get(char_type* s, streamsize n, char_type delim); basic_istream& get(basic_streambuf& sb); basic_istream& get(basic_streambuf& sb, char_type delim); basic_istream& getline(char_type* s, streamsize n); basic_istream& getline(char_type* s, streamsize n, char_type delim); basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof()); int_type peek(); basic_istream& read (char_type* s, streamsize n); streamsize readsome(char_type* s, streamsize n); basic_istream& putback(char_type c); basic_istream& unget(); int sync(); pos_type tellg(); basic_istream& seekg(pos_type); basic_istream& seekg(off_type, ios_base::seekdir); protected: // \ref{istream.cons}, copy/move constructor basic_istream(const basic_istream&) = delete; basic_istream(basic_istream&& rhs); // \ref{istream.assign}, assignment and swap basic_istream& operator=(const basic_istream&) = delete; basic_istream& operator=(basic_istream&& rhs); void swap(basic_istream& rhs); }; // \ref{istream.extractors}, character extraction templates template basic_istream& operator>>(basic_istream&, charT&); template basic_istream& operator>>(basic_istream&, unsigned char&); template basic_istream& operator>>(basic_istream&, signed char&); template basic_istream& operator>>(basic_istream&, charT(&)[N]); template basic_istream& operator>>(basic_istream&, unsigned char(&)[N]); template basic_istream& operator>>(basic_istream&, signed char(&)[N]); } \end{codeblock} \pnum The class template \tcode{basic_istream} defines a number of member function signatures that assist in reading and interpreting input from sequences controlled by a stream buffer. \pnum Two groups of member function signatures share common properties: the \term{formatted input functions} (or \term{extractors}) and the \term{unformatted input functions.} Both groups of input functions are described as if they obtain (or \term{extract}) input \term{characters} by calling \tcode{rdbuf()->sbumpc()} or \tcode{rdbuf()->sgetc()}. They may use other public members of \tcode{istream}. \rSec4[istream.cons]{Constructors} \indexlibraryctor{basic_istream}% \begin{itemdecl} explicit basic_istream(basic_streambuf* sb); \end{itemdecl} \indexlibrarymember{init}{basic_ios}% \begin{itemdescr} \pnum \effects Initializes the base class subobject with \tcode{basic_ios::init(sb)}\iref{basic.ios.cons}. \pnum \ensures \tcode{gcount() == 0}. \end{itemdescr} \indexlibraryctor{basic_istream}% \begin{itemdecl} basic_istream(basic_istream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Default constructs the base class, copies the \tcode{gcount()} from \tcode{rhs}, calls \tcode{basic_ios::move(rhs)} to initialize the base class, and sets the \tcode{gcount()} for \tcode{rhs} to 0. \end{itemdescr} \indexlibrarydtor{basic_istream}% \begin{itemdecl} virtual ~basic_istream(); \end{itemdecl} \begin{itemdescr} \pnum \remarks Does not perform any operations of \tcode{rdbuf()}. \end{itemdescr} \rSec4[istream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_istream}% \begin{itemdecl} basic_istream& operator=(basic_istream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{swap(rhs)}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{basic_istream}% \begin{itemdecl} void swap(basic_istream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{basic_ios::swap(rhs)}. Exchanges the values returned by \tcode{gcount()} and \tcode{rhs.gcount()}. \end{itemdescr} \rSec4[istream.sentry]{Class \tcode{basic_istream::sentry}} \indexlibraryglobal{basic_istream::sentry}% \indexlibrarymember{sentry}{basic_istream}% \begin{codeblock} namespace std { template class basic_istream::sentry { bool @\exposid{ok_}@; // \expos public: explicit sentry(basic_istream& is, bool noskipws = false); ~sentry(); explicit operator bool() const { return @\exposid{ok_}@; } sentry(const sentry&) = delete; sentry& operator=(const sentry&) = delete; }; } \end{codeblock} \begin{itemdescr} \pnum The class \tcode{sentry} defines a class that is responsible for doing exception safe prefix and suffix operations. \end{itemdescr} \indexlibraryctor{sentry}% \indexlibraryctor{basic_istream::sentry}% \begin{itemdecl} explicit sentry(basic_istream& is, bool noskipws = false); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{is.good()} is \tcode{false}, calls \tcode{is.setstate(failbit)}. Otherwise, prepares for formatted or unformatted input. First, if \tcode{is.tie()} is not a null pointer, the function calls \indexlibraryglobal{flush}% \tcode{is.tie()->flush()} to synchronize the output sequence with any associated external C stream. Except that this call can be suppressed if the put area of \tcode{is.tie()} is empty. Further an implementation is allowed to defer the call to \tcode{flush} until a call of \tcode{is.rdbuf()->underflow()} occurs. If no such call occurs before the \tcode{sentry} object is destroyed, the call to \tcode{flush} may be eliminated entirely. \begin{footnote} This will be possible only in functions that are part of the library. The semantics of the constructor used in user code is as specified. \end{footnote} If \tcode{noskipws} is zero and \tcode{is.flags() \& ios_base::skipws} is nonzero, the function extracts and discards each character as long as the next available input character \tcode{c} is a whitespace character. If \tcode{is.rdbuf()->sbumpc()} or \tcode{is.rdbuf()->sgetc()} returns \tcode{traits::eof()}, the function calls \tcode{setstate(failbit | eofbit)} (which may throw \tcode{ios_base::failure}). \pnum \remarks The constructor \begin{codeblock} explicit sentry(basic_istream& is, bool noskipws = false) \end{codeblock} uses the currently imbued locale in \tcode{is}, to determine whether the next input character is whitespace or not. \pnum To decide if the character \tcode{c} is a whitespace character, the constructor performs as if it executes the following code fragment: \begin{codeblock} const ctype& ctype = use_facet>(is.getloc()); if (ctype.is(ctype.space, c) != 0) // \tcode{c} is a whitespace character. \end{codeblock} \pnum If, after any preparation is completed, \tcode{is.good()} is \tcode{true}, \tcode{\exposid{ok_} != false} otherwise, \tcode{\exposid{ok_} == false}. During preparation, the constructor may call \tcode{setstate(failbit)} (which may throw \tcode{ios_base::\brk{}failure}\iref{iostate.flags}). \begin{footnote} The \tcode{sentry} constructor and destructor can also perform additional \indextext{implementation-dependent}% implementation-dependent operations. \end{footnote} \end{itemdescr} \indexlibrarydtor{sentry}% \indexlibrarydtor{basic_istream::sentry}% \begin{itemdecl} ~sentry(); \end{itemdecl} \begin{itemdescr} \pnum \effects None. \end{itemdescr} \indexlibrarymember{operator bool}{basic_istream::sentry}% \begin{itemdecl} explicit operator bool() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{ok_}. \end{itemdescr} \rSec3[istream.formatted]{Formatted input functions} \rSec4[istream.formatted.reqmts]{Common requirements} \pnum Each formatted input function begins execution by constructing an object of type \tcode{ios_base::iostate}, termed the local error state, and initializing it to \tcode{ios_base::goodbit}. It then creates an object of class \tcode{sentry} with the \tcode{noskipws} (second) argument \tcode{false}. If the \tcode{sentry} object returns \tcode{true}, when converted to a value of type \tcode{bool}, the function endeavors to obtain the requested input. Otherwise, if the \tcode{sentry} constructor exits by throwing an exception or if the \tcode{sentry} object produces \tcode{false} when converted to a value of type \tcode{bool}, the function returns without attempting to obtain any input. If \tcode{rdbuf()->sbumpc()} or \tcode{rdbuf()->sgetc()} returns \tcode{traits::eof()}, then \tcode{ios_base::eofbit} is set in the local error state and the input function stops trying to obtain the requested input. If an exception is thrown during input then \tcode{ios_base::badbit} is set in the local error state, \tcode{*this}'s error state is set to the local error state, and the exception is rethrown if \tcode{(exceptions() \& badbit) != 0}. After extraction is done, the input function calls \tcode{setstate}, which sets \tcode{*this}'s error state to the local error state, and may throw an exception. In any case, the formatted input function destroys the \tcode{sentry} object. If no exception has been thrown, it returns \tcode{*this}. \rSec4[istream.formatted.arithmetic]{Arithmetic extractors} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(unsigned short& val); basic_istream& operator>>(unsigned int& val); basic_istream& operator>>(long& val); basic_istream& operator>>(unsigned long& val); basic_istream& operator>>(long long& val); basic_istream& operator>>(unsigned long long& val); basic_istream& operator>>(float& val); basic_istream& operator>>(double& val); basic_istream& operator>>(long double& val); basic_istream& operator>>(bool& val); basic_istream& operator>>(void*& val); \end{itemdecl} \begin{itemdescr} \pnum As in the case of the inserters, these extractors depend on the locale's \tcode{num_get<>}\iref{locale.num.get} object to perform parsing the input stream data. These extractors behave as formatted input functions (as described in~\ref{istream.formatted.reqmts}). After a \tcode{sentry} object is constructed, the conversion occurs as if performed by the following code fragment, where \tcode{state} represents the input function's local error state: \begin{codeblock} using numget = num_get>; use_facet(loc).get(*this, 0, *this, state, val); \end{codeblock} In the above fragment, \tcode{loc} stands for the private member of the \tcode{basic_ios} class. \begin{note} The first argument provides an object of the \tcode{istreambuf_iterator} class which is an iterator pointed to an input stream. It bypasses istreams and uses streambufs directly. \end{note} Class \tcode{locale} relies on this type as its interface to \tcode{istream}, so that it does not need to depend directly on \tcode{istream}. \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(short& val); \end{itemdecl} \begin{itemdescr} \pnum The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment): \begin{codeblock} using numget = num_get>; long lval; use_facet(loc).get(*this, 0, *this, state, lval); if (lval < numeric_limits::min()) { state |= ios_base::failbit; val = numeric_limits::min(); } else if (numeric_limits::max() < lval) { state |= ios_base::failbit; val = numeric_limits::max(); } else val = static_cast(lval); \end{codeblock} \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(int& val); \end{itemdecl} \begin{itemdescr} \pnum The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment): \begin{codeblock} using numget = num_get>; long lval; use_facet(loc).get(*this, 0, *this, state, lval); if (lval < numeric_limits::min()) { state |= ios_base::failbit; val = numeric_limits::min(); } else if (numeric_limits::max() < lval) { state |= ios_base::failbit; val = numeric_limits::max(); } else val = static_cast(lval); \end{codeblock} \end{itemdescr} \begin{itemdecl} basic_istream& operator>>(@\placeholder{extended-floating-point-type}@& val); \end{itemdecl} \begin{itemdescr} \pnum If the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is not less than or equal to that of \tcode{long double}, then an invocation of the operator function is conditionally supported with \impldef{\tcode{operator>>} for large extended floating-point types} semantics. \pnum Otherwise, let \tcode{FP} be a standard floating-point type: \begin{itemize} \item if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is less than or equal to that of \tcode{float}, then \tcode{FP} is \tcode{float}, \item otherwise, if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is less than or equal to that of \tcode{double}, then \tcode{FP} is \tcode{double}, \item otherwise, \tcode{FP} is \tcode{long double}. \end{itemize} \pnum The conversion occurs as if performed by the following code fragment (using the same notation as for the preceding code fragment): \begin{codeblock} using numget = num_get>; FP fval; use_facet(loc).get(*this, 0, *this, state, fval); if (fval < -numeric_limits<@\placeholder{extended-floating-point-type}@>::max()) { state |= ios_base::failbit; val = -numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); } else if (numeric_limits<@\placeholder{extended-floating-point-type}@>::max() < fval) { state |= ios_base::failbit; val = numeric_limits<@\placeholder{extended-floating-point-type}@>::max(); } else { val = static_cast<@\placeholder{extended-floating-point-type}@>(fval); } \end{codeblock} \begin{note} When the extended floating-point type has a floating-point conversion rank that is not equal to the rank of any standard floating-point type, then double rounding during the conversion can result in inaccurate results. \tcode{from_chars} can be used in situations where maximum accuracy is important. \end{note} \end{itemdescr} \rSec4[istream.extractors]{\tcode{basic_istream::operator>>}} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(basic_istream& (*pf)(basic_istream&)); \end{itemdecl} \begin{itemdescr} \pnum \effects None. This extractor does not behave as a formatted input function (as described in~\ref{istream.formatted.reqmts}). \pnum \returns \tcode{pf(*this)}.% \indexlibraryglobal{ws}% \begin{footnote} See, for example, the function signature \tcode{ws(basic_istream\&)}\iref{istream.manip}. \end{footnote} \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(basic_ios& (*pf)(basic_ios&)); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{pf(*this)}. This extractor does not behave as a formatted input function (as described in~\ref{istream.formatted.reqmts}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(ios_base& (*pf)(ios_base&)); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{pf(*this)}. \begin{footnote} See, for example, the function signature \tcode{dec(ios_base\&)}\iref{basefield.manip}. \end{footnote} This extractor does not behave as a formatted input function (as described in~\ref{istream.formatted.reqmts}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} template basic_istream& operator>>(basic_istream& in, charT (&s)[N]); template basic_istream& operator>>(basic_istream& in, unsigned char (&s)[N]); template basic_istream& operator>>(basic_istream& in, signed char (&s)[N]); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves like a formatted input member (as described in~\ref{istream.formatted.reqmts}) of \tcode{in}. After a \tcode{sentry} object is constructed, \tcode{operator>>} extracts characters and stores them into \tcode{s}. If \tcode{width()} is greater than zero, \tcode{n} is \tcode{min(size_t(width()), N)}. Otherwise \tcode{n} is \tcode{N}. \tcode{n} is the maximum number of characters stored. \pnum Characters are extracted and stored until any of the following occurs: \begin{itemize} \item \tcode{n-1} characters are stored; \item end of file occurs on the input sequence; \item letting \tcode{ct} be \tcode{use_facet>(in.getloc())}, \tcode{ct.is(ct.space, c)} is \tcode{true}. \end{itemize} \pnum \tcode{operator>>} then stores a null byte (\tcode{charT()}) in the next position, which may be the first position if no characters were extracted. \tcode{operator>>} then calls \tcode{width(0)}. \pnum If the function extracted no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{in}. \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} template basic_istream& operator>>(basic_istream& in, charT& c); template basic_istream& operator>>(basic_istream& in, unsigned char& c); template basic_istream& operator>>(basic_istream& in, signed char& c); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves like a formatted input member (as described in~\ref{istream.formatted.reqmts}) of \tcode{in}. A character is extracted from \tcode{in}, if one is available, and stored in \tcode{c}. Otherwise, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{in}. \end{itemdescr} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} basic_istream& operator>>(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function\iref{istream.unformatted}. If \tcode{sb} is null, calls \tcode{setstate(fail\-bit)}, which may throw \tcode{ios_base::failure}\iref{iostate.flags}. After a \tcode{sentry} object is constructed, extracts characters from \tcode{*this} and inserts them in the output sequence controlled by \tcode{sb}. Characters are extracted and inserted until any of the following occurs: \begin{itemize} \item end-of-file occurs on the input sequence; \item inserting in the output sequence fails (in which case the character to be inserted is not extracted); \item an exception occurs (in which case the exception is caught). \end{itemize} \pnum If the function inserts no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{*this}. \end{itemdescr} \rSec3[istream.unformatted]{Unformatted input functions} \pnum Each unformatted input function begins execution by constructing an object of type \tcode{ios_base::iostate}, termed the local error state, and initializing it to \tcode{ios_base::goodbit}. It then creates an object of class \tcode{sentry} with the default argument \tcode{noskipws} (second) argument \tcode{true}. If the \tcode{sentry} object returns \tcode{true}, when converted to a value of type \tcode{bool}, the function endeavors to obtain the requested input. Otherwise, if the \tcode{sentry} constructor exits by throwing an exception or if the \tcode{sentry} object produces \tcode{false}, when converted to a value of type \tcode{bool}, the function returns without attempting to obtain any input. In either case the number of extracted characters is set to 0; unformatted input functions taking a character array of nonzero size as an argument shall also store a null character (using \tcode{charT()}) in the first location of the array. If \tcode{rdbuf()->sbumpc()} or \tcode{rdbuf()->sgetc()} returns \tcode{traits::eof()}, then \tcode{ios_base::eofbit} is set in the local error state and the input function stops trying to obtain the requested input. If an exception is thrown during input then \tcode{ios_base::badbit} is set in the local error state, \tcode{*this}'s error state is set to the local error state, and the exception is rethrown if \tcode{(exceptions() \& badbit) != 0}. If no exception has been thrown it stores the number of characters extracted in a member object. After extraction is done, the input function calls \tcode{setstate}, which sets \tcode{*this}'s error state to the local error state, and may throw an exception. In any event the \tcode{sentry} object is destroyed before leaving the unformatted input function. \indexlibrarymember{gcount}{basic_istream}% \begin{itemdecl} streamsize gcount() const; \end{itemdecl} \begin{itemdescr} \pnum \effects None. This member function does not behave as an unformatted input function (as described above). \pnum \returns The number of characters extracted by the last unformatted input member function called for the object. If the number cannot be represented, returns \tcode{numeric_limits::max()}. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} int_type get(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts a character \tcode{c}, if one is available. Otherwise, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{c} if available, otherwise \tcode{traits::eof()}. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} basic_istream& get(char_type& c); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts a character, if one is available, and assigns it to \tcode{c}. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} Otherwise, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} basic_istream& get(char_type* s, streamsize n, char_type delim); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts characters and stores them into successive locations of an array whose first element is designated by \tcode{s}. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} Characters are extracted and stored until any of the following occurs: \begin{itemize} \item \tcode{n} is less than one or \tcode{n - 1} characters are stored; \item end-of-file occurs on the input sequence; \item \tcode{traits::eq(c, delim)} for the next available input character \tcode{c} (in which case \tcode{c} is not extracted). \end{itemize} \pnum If the function stores no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. In any case, if \tcode{n} is greater than zero it then stores a null character into the next successive location of the array. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} basic_istream& get(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{get(s, n, widen('\textbackslash n'))}. \pnum \returns Value returned by the call. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} basic_istream& get(basic_streambuf& sb, char_type delim); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts characters and inserts them in the output sequence controlled by \tcode{sb}. Characters are extracted and inserted until any of the following occurs: \begin{itemize} \item end-of-file occurs on the input sequence; \item inserting in the output sequence fails (in which case the character to be inserted is not extracted); \item \tcode{traits::eq(c, delim)} for the next available input character \tcode{c} (in which case \tcode{c} is not extracted); \item an exception occurs (in which case, the exception is caught but not rethrown). \end{itemize} \pnum If the function inserts no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{get}{basic_istream}% \begin{itemdecl} basic_istream& get(basic_streambuf& sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{get(sb, widen('\textbackslash n'))}. \pnum \returns Value returned by the call. \end{itemdescr} \indexlibrarymember{getline}{basic_istream}% \begin{itemdecl} basic_istream& getline(char_type* s, streamsize n, char_type delim); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts characters and stores them into successive locations of an array whose first element is designated by \tcode{s}. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} Characters are extracted and stored until one of the following occurs: \begin{enumerate} \item end-of-file occurs on the input sequence; \item \tcode{traits::eq(c, delim)} for the next available input character \tcode{c} (in which case the input character is extracted but not stored); \begin{footnote} Since the final input character is ``extracted'', it is counted in the \tcode{gcount()}, even though it is not stored. \end{footnote} \item \tcode{n} is less than one or \tcode{n - 1} characters are stored (in which case the function calls \tcode{setstate(\brk{}failbit)}). \end{enumerate} \pnum These conditions are tested in the order shown. \begin{footnote} This allows an input line which exactly fills the buffer, without setting \tcode{failbit}. This is different behavior than the historical AT\&T implementation. \end{footnote} \pnum If the function extracts no characters, \tcode{ios_base::failbit} is set in the input function's local error state before \tcode{setstate} is called. \begin{footnote} This implies an empty input line will not cause \tcode{failbit} to be set. \end{footnote} \pnum In any case, if \tcode{n} is greater than zero, it then stores a null character (using \tcode{charT()}) into the next successive location of the array. \pnum \returns \tcode{*this}. \pnum \begin{example} \begin{codeblock} #include int main() { using namespace std; const int line_buffer_size = 100; char buffer[line_buffer_size]; int line_number = 0; while (cin.getline(buffer, line_buffer_size, '@\textbackslash@n') || cin.gcount()) { int count = cin.gcount(); if (cin.eof()) cout << "Partial final line"; // \tcode{cin.fail()} is \tcode{false} else if (cin.fail()) { cout << "Partial long line"; cin.clear(cin.rdstate() & ~ios_base::failbit); } else { count--; // Don't include newline in \tcode{count} cout << "Line " << ++line_number; } cout << " (" << count << " chars): " << buffer << endl; } } \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{getline}{basic_istream}% \begin{itemdecl} basic_istream& getline(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{getline(s, n, widen('\textbackslash n'))} \end{itemdescr} \indexlibrarymember{ignore}{basic_istream}% \begin{itemdecl} basic_istream& ignore(streamsize n = 1, int_type delim = traits::eof()); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, extracts characters and discards them. Characters are extracted until any of the following occurs: \begin{itemize} \item \tcode{n != numeric_limits::max()}\iref{numeric.limits} and \tcode{n} characters have been extracted so far; \item end-of-file occurs on the input sequence (in which case the function calls \tcode{setstate(eofbit)}, which may throw \tcode{ios_base::failure}\iref{iostate.flags}); \item \tcode{traits::eq_int_type(traits::to_int_type(c), delim)} for the next available input character \tcode{c} (in which case \tcode{c} is extracted). \end{itemize} \begin{note} The last condition will never occur if \tcode{traits::eq_int_type(delim, traits::eof())}. \end{note} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{peek}{basic_istream}% \begin{itemdecl} int_type peek(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, reads but does not extract the current input character. \pnum \returns \tcode{traits::eof()} if \tcode{good()} is \tcode{false}. Otherwise, returns \tcode{rdbuf()->sgetc()}. \end{itemdescr} \indexlibrarymember{read}{basic_istream}% \begin{itemdecl} basic_istream& read(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, if \tcode{!good()} calls \tcode{setstate(failbit)} which may throw an exception, and return. Otherwise extracts characters and stores them into successive locations of an array whose first element is designated by \tcode{s}. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} Characters are extracted and stored until either of the following occurs: \begin{itemize} \item \tcode{n} characters are stored; \item end-of-file occurs on the input sequence (in which case the function calls \tcode{setstate(failbit | eofbit)}, which may throw \tcode{ios_base::failure}\iref{iostate.flags}). \end{itemize} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{readsome}{basic_istream}% \begin{itemdecl} streamsize readsome(char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above). After constructing a \tcode{sentry} object, if \tcode{!good()} calls \tcode{setstate(failbit)} which may throw an exception, and return. Otherwise extracts characters and stores them into successive locations of an array whose first element is designated by \tcode{s}. If \tcode{rdbuf()->in_avail() == -1}, calls \tcode{setstate(eofbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}), and extracts no characters; \begin{itemize} \item If \tcode{rdbuf()->in_avail() == 0}, extracts no characters \item If \tcode{rdbuf()->in_avail() > 0}, extracts \tcode{min(rdbuf()->in_avail(), n))}. \end{itemize} \pnum \returns The number of characters extracted. \end{itemdescr} \indexlibrarymember{putback}{basic_istream}% \begin{itemdecl} basic_istream& putback(char_type c); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that the function first clears \tcode{eofbit}. After constructing a \tcode{sentry} object, if \tcode{!good()} calls \tcode{setstate(failbit)} which may throw an exception, and return. If \tcode{rdbuf()} is not null, calls \tcode{rdbuf()->sputbackc(c)}. If \tcode{rdbuf()} is null, or if \tcode{sputbackc} returns \tcode{traits::eof()}, calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). \begin{note} This function extracts no characters, so the value returned by the next call to \tcode{gcount()} is 0. \end{note} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{unget}{basic_istream}% \begin{itemdecl} basic_istream& unget(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that the function first clears \tcode{eofbit}. After constructing a \tcode{sentry} object, if \tcode{!good()} calls \tcode{setstate(failbit)} which may throw an exception, and return. If \tcode{rdbuf()} is not null, calls \tcode{rdbuf()->sungetc()}. If \tcode{rdbuf()} is null, or if \tcode{sungetc} returns \tcode{traits::eof()}, calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). \begin{note} This function extracts no characters, so the value returned by the next call to \tcode{gcount()} is 0. \end{note} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{sync}{basic_istream}% \begin{itemdecl} int sync(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to \tcode{gcount()}. After constructing a \tcode{sentry} object, if \tcode{rdbuf()} is a null pointer, returns \tcode{-1}. Otherwise, calls \tcode{rdbuf()->pubsync()} and, if that function returns \tcode{-1} calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}, and returns \tcode{-1}. Otherwise, returns zero. \end{itemdescr} \indexlibrarymember{tellg}{basic_istream}% \begin{itemdecl} pos_type tellg(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to \tcode{gcount()}. \pnum \returns After constructing a \tcode{sentry} object, if \tcode{fail() != false}, returns \tcode{pos_type(-1)} to indicate failure. Otherwise, returns \tcode{rdbuf()->pubseekoff(0, cur, in)}. \end{itemdescr} \indexlibrarymember{seekg}{basic_istream}% \begin{itemdecl} basic_istream& seekg(pos_type pos); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that the function first clears \tcode{eofbit}, it does not count the number of characters extracted, and it does not affect the value returned by subsequent calls to \tcode{gcount()}. After constructing a \tcode{sentry} object, if \tcode{fail() != true}, executes \tcode{rdbuf()->pubseekpos(pos, ios_base::in)}. In case of failure, the function calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{seekg}{basic_istream}% \begin{itemdecl} basic_istream& seekg(off_type off, ios_base::seekdir dir); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function (as described above), except that the function first clears \tcode{eofbit}, does not count the number of characters extracted, and does not affect the value returned by subsequent calls to \tcode{gcount()}. After constructing a \tcode{sentry} object, if \tcode{fail() != true}, executes \tcode{rdbuf()->pubseekoff(off, dir, ios_base::in)}. In case of failure, the function calls \tcode{setstate(\brk{}failbit)} (which may throw \tcode{ios_base::failure}). \pnum \returns \tcode{*this}. \end{itemdescr} \rSec3[istream.manip]{Standard \tcode{basic_istream} manipulators} \pnum Each instantiation of the function template specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{ws}% \begin{itemdecl} template basic_istream& ws(basic_istream& is); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted input function\iref{istream.unformatted}, except that it does not count the number of characters extracted and does not affect the value returned by subsequent calls to \tcode{is.gcount()}. After constructing a \tcode{sentry} object extracts characters as long as the next available character \tcode{c} is whitespace or until there are no more characters in the sequence. Whitespace characters are distinguished with the same criterion as used by \tcode{sentry::sentry}\iref{istream.sentry}. If \tcode{ws} stops extracting characters because there are no more available it sets \tcode{eofbit}, but not \tcode{failbit}. \pnum \returns \tcode{is}. \end{itemdescr} \rSec3[istream.rvalue]{Rvalue stream extraction} \indexlibrarymember{operator>>}{basic_istream}% \begin{itemdecl} template Istream&& operator>>(Istream&& is, T&& x); \end{itemdecl} \begin{itemdescr} \pnum \constraints The expression \tcode{is >> std::forward(x)} is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand} and \tcode{Istream} is publicly and unambiguously derived from \tcode{ios_base}. \pnum \effects Equivalent to: \begin{codeblock} is >> std::forward(x); return std::move(is); \end{codeblock} \end{itemdescr} \rSec3[iostreamclass]{Class template \tcode{basic_iostream}} \rSec4[iostreamclass.general]{General} \indexlibraryglobal{basic_iostream}% \begin{codeblock} namespace std { template> class basic_iostream : public basic_istream, public basic_ostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{iostream.cons}, constructor explicit basic_iostream(basic_streambuf* sb); // \ref{iostream.dest}, destructor virtual ~basic_iostream(); protected: // \ref{iostream.cons}, constructor basic_iostream(const basic_iostream&) = delete; basic_iostream(basic_iostream&& rhs); // \ref{iostream.assign}, assignment and swap basic_iostream& operator=(const basic_iostream&) = delete; basic_iostream& operator=(basic_iostream&& rhs); void swap(basic_iostream& rhs); }; } \end{codeblock} \pnum The class template \tcode{basic_iostream} inherits a number of functions that allow reading input and writing output to sequences controlled by a stream buffer. \rSec4[iostream.cons]{Constructors} \indexlibraryctor{basic_iostream}% \begin{itemdecl} explicit basic_iostream(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class subobjects with \tcode{basic_istream(sb)}\iref{istream} and \tcode{basic_ostream(sb)}\iref{ostream}. \pnum \ensures \tcode{rdbuf() == sb} and \tcode{gcount() == 0}. \end{itemdescr} \indexlibraryctor{basic_iostream}% \begin{itemdecl} basic_iostream(basic_iostream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs from the rvalue \tcode{rhs} by constructing the \tcode{basic_istream} base class with \tcode{std::move(rhs)}. \end{itemdescr} \rSec4[iostream.dest]{Destructor} \indexlibrarydtor{basic_iostream}% \begin{itemdecl} virtual ~basic_iostream(); \end{itemdecl} \begin{itemdescr} \pnum \remarks Does not perform any operations on \tcode{rdbuf()}. \end{itemdescr} \rSec4[iostream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_iostream}% \begin{itemdecl} basic_iostream& operator=(basic_iostream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{swap(rhs)}. \end{itemdescr} \indexlibrarymember{swap}{basic_iostream}% \begin{itemdecl} void swap(basic_iostream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{basic_istream::swap(rhs)}. \end{itemdescr} \rSec2[output.streams]{Output streams} \rSec3[output.streams.general]{General} \pnum The header \libheader{ostream} defines a class template and several function templates that control output to a stream buffer, along with a function template that inserts into stream rvalues. \rSec3[ostream]{Class template \tcode{basic_ostream}} \rSec4[ostream.general]{General} \pnum When a function has a parameter type \tcode{\placeholder{extended-floating-point-type}}, the implementation provides overloads for all cv-unqualified extended floating-point types\iref{basic.fundamental}. \indexlibraryglobal{basic_ostream}% \begin{codeblock} namespace std { template> class basic_ostream : virtual public basic_ios { public: // types (inherited from \tcode{basic_ios}\iref{ios}) using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{ostream.cons}, constructor/destructor explicit basic_ostream(basic_streambuf* sb); virtual ~basic_ostream(); // \ref{ostream.sentry}, prefix/suffix class sentry; // \ref{ostream.formatted}, formatted output basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&)); basic_ostream& operator<<(basic_ios& (*pf)(basic_ios&)); basic_ostream& operator<<(ios_base& (*pf)(ios_base&)); basic_ostream& operator<<(bool n); basic_ostream& operator<<(short n); basic_ostream& operator<<(unsigned short n); basic_ostream& operator<<(int n); basic_ostream& operator<<(unsigned int n); basic_ostream& operator<<(long n); basic_ostream& operator<<(unsigned long n); basic_ostream& operator<<(long long n); basic_ostream& operator<<(unsigned long long n); basic_ostream& operator<<(float f); basic_ostream& operator<<(double f); basic_ostream& operator<<(long double f); basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ f); basic_ostream& operator<<(const void* p); basic_ostream& operator<<(const volatile void* p); basic_ostream& operator<<(nullptr_t); basic_ostream& operator<<(basic_streambuf* sb); // \ref{ostream.unformatted}, unformatted output basic_ostream& put(char_type c); basic_ostream& write(const char_type* s, streamsize n); basic_ostream& flush(); // \ref{ostream.seeks}, seeks pos_type tellp(); basic_ostream& seekp(pos_type); basic_ostream& seekp(off_type, ios_base::seekdir); protected: // \ref{ostream.cons}, copy/move constructor basic_ostream(const basic_ostream&) = delete; basic_ostream(basic_ostream&& rhs); // \ref{ostream.assign}, assignment and swap basic_ostream& operator=(const basic_ostream&) = delete; basic_ostream& operator=(basic_ostream&& rhs); void swap(basic_ostream& rhs); }; // \ref{ostream.inserters.character}, character inserters template basic_ostream& operator<<(basic_ostream&, charT); template basic_ostream& operator<<(basic_ostream&, char); template basic_ostream& operator<<(basic_ostream&, char); template basic_ostream& operator<<(basic_ostream&, signed char); template basic_ostream& operator<<(basic_ostream&, unsigned char); template basic_ostream& operator<<(basic_ostream&, wchar_t) = delete; template basic_ostream& operator<<(basic_ostream&, char8_t) = delete; template basic_ostream& operator<<(basic_ostream&, char16_t) = delete; template basic_ostream& operator<<(basic_ostream&, char32_t) = delete; template basic_ostream& operator<<(basic_ostream&, char8_t) = delete; template basic_ostream& operator<<(basic_ostream&, char16_t) = delete; template basic_ostream& operator<<(basic_ostream&, char32_t) = delete; template basic_ostream& operator<<(basic_ostream&, const charT*); template basic_ostream& operator<<(basic_ostream&, const char*); template basic_ostream& operator<<(basic_ostream&, const char*); template basic_ostream& operator<<(basic_ostream&, const signed char*); template basic_ostream& operator<<(basic_ostream&, const unsigned char*); template basic_ostream& operator<<(basic_ostream&, const wchar_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char8_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char16_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char32_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char8_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char16_t*) = delete; template basic_ostream& operator<<(basic_ostream&, const char32_t*) = delete; } \end{codeblock} \pnum The class template \tcode{basic_ostream} defines a number of member function signatures that assist in formatting and writing output to output sequences controlled by a stream buffer. \pnum Two groups of member function signatures share common properties: the \term{formatted output functions} (or \term{inserters}) and the \term{unformatted output functions.} Both groups of output functions generate (or \term{insert}) output \term{characters} by actions equivalent to calling \tcode{rdbuf()->sputc(int_type)}. They may use other public members of \tcode{basic_ostream} except that they shall not invoke any virtual members of \tcode{rdbuf()} except \tcode{overflow()}, \tcode{xsputn()}, and \tcode{sync()}. \pnum If one of these called functions throws an exception, then unless explicitly noted otherwise the output function sets \tcode{badbit} in the error state. If \tcode{badbit} is set in \tcode{exceptions()}, the output function rethrows the exception without completing its actions, otherwise it does not throw anything and proceeds as if the called function had returned a failure indication. \pnum \begin{note} The deleted overloads of \tcode{operator<<} prevent formatting characters as integers and strings as pointers. \end{note} \rSec4[ostream.cons]{Constructors} \indexlibraryctor{basic_ostream}% \begin{itemdecl} explicit basic_ostream(basic_streambuf* sb); \end{itemdecl} \indexlibrarymember{init}{basic_ostream}% \begin{itemdescr} \pnum \effects Initializes the base class subobject with \tcode{basic_ios::init(sb)}\iref{basic.ios.cons}. \pnum \ensures \tcode{rdbuf() == sb}. \end{itemdescr} \indexlibraryctor{basic_ostream}% \begin{itemdecl} basic_ostream(basic_ostream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by default constructing the base class and calling \tcode{basic_ios::move(rhs)} to initialize the base class. \end{itemdescr} \indexlibrarydtor{basic_ostream}% \begin{itemdecl} virtual ~basic_ostream(); \end{itemdecl} \begin{itemdescr} \pnum \remarks Does not perform any operations on \tcode{rdbuf()}. \end{itemdescr} \rSec4[ostream.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_ostream}% \begin{itemdecl} basic_ostream& operator=(basic_ostream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{swap(rhs)}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{basic_ostream}% \begin{itemdecl} void swap(basic_ostream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{basic_ios::swap(rhs)}. \end{itemdescr} \rSec4[ostream.sentry]{Class \tcode{basic_ostream::sentry}} \indexlibraryglobal{basic_ostream::sentry}% \indexlibrarymember{sentry}{basic_ostream}% \begin{codeblock} namespace std { template class basic_ostream::sentry { bool @\exposid{ok_}@; // \expos public: explicit sentry(basic_ostream& os); ~sentry(); explicit operator bool() const { return @\exposid{ok_}@; } sentry(const sentry&) = delete; sentry& operator=(const sentry&) = delete; }; } \end{codeblock} \pnum The class \tcode{sentry} defines a class that is responsible for doing exception safe prefix and suffix operations. \indexlibraryctor{basic_ostream::sentry}% \begin{itemdecl} explicit sentry(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum If \tcode{os.good()} is nonzero, prepares for formatted or unformatted output. If \tcode{os.tie()} is not a null pointer, calls \indexlibraryglobal{flush}% \tcode{os.tie()->flush()}.% \begin{footnote} The call \tcode{os.tie()->flush()} does not necessarily occur if the function can determine that no synchronization is necessary. \end{footnote} \pnum If, after any preparation is completed, \tcode{os.good()} is \tcode{true}, \tcode{\exposid{ok_} == true} otherwise, \tcode{\exposid{ok_} == false}. During preparation, the constructor may call \tcode{setstate(failbit)} (which may throw \tcode{ios_base::\brk{}failure}\iref{iostate.flags}). \begin{footnote} The \tcode{sentry} constructor and destructor can also perform additional \indextext{implementation-dependent}% implementation-dependent operations. \end{footnote} \end{itemdescr} \indexlibrarydtor{basic_ostream::sentry}% \begin{itemdecl} ~sentry(); \end{itemdecl} \begin{itemdescr} \pnum If \tcode{(os.flags() \& ios_base::unitbuf) \&\& !uncaught_exceptions() \&\& os.good()} is \tcode{true}, calls \tcode{os.rdbuf()->pubsync()}. If that function returns $-1$, sets \tcode{badbit} in \tcode{os.rdstate()} without propagating an exception. \end{itemdescr} \indexlibrarymember{operator bool}{basic_ostream::sentry}% \begin{itemdecl} explicit operator bool() const; \end{itemdecl} \begin{itemdescr} \pnum \effects Returns \exposid{ok_}. \end{itemdescr} \rSec4[ostream.seeks]{Seek members} \pnum Each seek member function begins execution by constructing an object of class \tcode{sentry}. It returns by destroying the \tcode{sentry} object. \indexlibrarymember{tellp}{basic_ostream}% \begin{itemdecl} pos_type tellp(); \end{itemdecl} \begin{itemdescr} \pnum \returns If \tcode{fail() != false}, returns \tcode{pos_type(-1)} to indicate failure. Otherwise, returns \tcode{rdbuf()->\brk{}pub\-seek\-off(\brk0, cur, out)}. \end{itemdescr} \indexlibrarymember{seekp}{basic_ostream}% \begin{itemdecl} basic_ostream& seekp(pos_type pos); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{fail() != true}, executes \tcode{rdbuf()->pubseekpos(pos, ios_base::out)}. In case of failure, the function calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{seekp}{basic_ostream}% \begin{itemdecl} basic_ostream& seekp(off_type off, ios_base::seekdir dir); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{fail() != true}, executes \tcode{rdbuf()->pubseekoff(off, dir, ios_base::out)}. In case of failure, the function calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure}). \pnum \returns \tcode{*this}. \end{itemdescr} \rSec3[ostream.formatted]{Formatted output functions} \rSec4[ostream.formatted.reqmts]{Common requirements} \pnum Each formatted output function begins execution by constructing an object of class \tcode{sentry}. If that object returns \tcode{true} when converted to a value of type \tcode{bool}, the function endeavors to generate the requested output. If the generation fails, then the formatted output function does \tcode{setstate(ios_base::failbit)}, which can throw an exception. If an exception is thrown during output, then \tcode{ios_base::badbit} is set \begin{footnote} This is done without causing an \tcode{ios_base::failure} to be thrown. \end{footnote} in \tcode{*this}'s error state. If \tcode{(exceptions()\&badbit) != 0} then the exception is rethrown. Whether or not an exception is thrown, the \tcode{sentry} object is destroyed before leaving the formatted output function. If no exception is thrown, the result of the formatted output function is \tcode{*this}. \pnum The descriptions of the individual formatted output functions describe how they perform output and do not mention the \tcode{sentry} object. \pnum If a formatted output function of a stream \tcode{os} determines padding, it does so as follows. Given a \tcode{charT} character sequence \tcode{seq} where \tcode{charT} is the character container type of the stream, if the length of \tcode{seq} is less than \tcode{os.width()}, then enough copies of \tcode{os.fill()} are added to this sequence as necessary to pad to a width of \tcode{os.width()} characters. If \tcode{(os.flags() \& ios_base::adjustfield) == ios_base::left} is \tcode{true}, the fill characters are placed after the character sequence; otherwise, they are placed before the character sequence. \rSec4[ostream.inserters.arithmetic]{Arithmetic inserters} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(bool val); basic_ostream& operator<<(short val); basic_ostream& operator<<(unsigned short val); basic_ostream& operator<<(int val); basic_ostream& operator<<(unsigned int val); basic_ostream& operator<<(long val); basic_ostream& operator<<(unsigned long val); basic_ostream& operator<<(long long val); basic_ostream& operator<<(unsigned long long val); basic_ostream& operator<<(float val); basic_ostream& operator<<(double val); basic_ostream& operator<<(long double val); basic_ostream& operator<<(const void* val); \end{itemdecl} \begin{itemdescr} \pnum \effects The classes \tcode{num_get<>} and \tcode{num_put<>} handle locale-dependent numeric formatting and parsing. These inserter functions use the imbued \tcode{locale} value to perform numeric formatting. When \tcode{val} is of type \tcode{bool}, \tcode{long}, \tcode{unsigned long}, \tcode{long long}, \tcode{unsigned long long}, \tcode{double}, \tcode{long double}, or \tcode{const void*}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( getloc()).put(*this, *this, fill(), val).failed(); \end{codeblock} When \tcode{val} is of type \tcode{short} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; bool failed = use_facet>>( getloc()).put(*this, *this, fill(), baseflags == ios_base::oct || baseflags == ios_base::hex ? static_cast(static_cast(val)) : static_cast(val)).failed(); \end{codeblock} When \tcode{val} is of type \tcode{int} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; bool failed = use_facet>>( getloc()).put(*this, *this, fill(), baseflags == ios_base::oct || baseflags == ios_base::hex ? static_cast(static_cast(val)) : static_cast(val)).failed(); \end{codeblock} When \tcode{val} is of type \tcode{unsigned short} or \tcode{unsigned int} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} When \tcode{val} is of type \tcode{float} the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} \pnum The first argument provides an object of the \tcode{ostreambuf_iterator<>} class which is an iterator for class \tcode{basic_ostream<>}. It bypasses \tcode{ostream}s and uses \tcode{streambuf}s directly. Class \tcode{locale} relies on these types as its interface to iostreams, since for flexibility it has been abstracted away from direct dependence on \tcode{ostream}. The second parameter is a reference to the base class subobject of type \tcode{ios_base}. It provides formatting specifications such as field width, and a locale from which to obtain other facets. If \tcode{failed} is \tcode{true} then does \tcode{setstate(badbit)}, which may throw an exception, and returns. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(const volatile void* p); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return operator<<(const_cast(p));} \end{itemdescr} \begin{itemdecl} basic_ostream& operator<<(@\placeholder{extended-floating-point-type}@ val); \end{itemdecl} \begin{itemdescr} \pnum \effects If the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is less than or equal to that of \tcode{double}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} Otherwise, if the floating-point conversion rank of \tcode{\placeholder{extended-floating-point-type}} is less than or equal to that of \tcode{long double}, the formatting conversion occurs as if it performed the following code fragment: \begin{codeblock} bool failed = use_facet>>( getloc()).put(*this, *this, fill(), static_cast(val)).failed(); \end{codeblock} Otherwise, an invocation of the operator function is conditionally supported with \impldef{\tcode{operator<<} for large extended floating-point types} semantics. If \tcode{failed} is \tcode{true} then does \tcode{setstate(badbit)}, which may throw an exception, and returns. \pnum \returns \tcode{*this}. \end{itemdescr} \rSec4[ostream.inserters]{\tcode{basic_ostream::operator<<}} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(basic_ostream& (*pf)(basic_ostream&)); \end{itemdecl} \begin{itemdescr} \pnum \effects None. Does not behave as a formatted output function (as described in~\ref{ostream.formatted.reqmts}). \pnum \returns \tcode{pf(*this)}. \begin{footnote} See, for example, the function signature \indexlibraryglobal{endl}% \tcode{endl(basic_ostream\&)}\iref{ostream.manip}. \end{footnote} \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(basic_ios& (*pf)(basic_ios&)); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{pf(*this)}. This inserter does not behave as a formatted output function (as described in~\ref{ostream.formatted.reqmts}). \pnum \returns \tcode{*this}. \begin{footnote} See, for example, the function signature \indexlibraryglobal{dec}% \tcode{dec(ios_base\&)}\iref{basefield.manip}. \end{footnote} \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(ios_base& (*pf)(ios_base&)); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{pf(*this)}. This inserter does not behave as a formatted output function (as described in~\ref{ostream.formatted.reqmts}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(basic_streambuf* sb); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted output function\iref{ostream.unformatted}. After the \tcode{sentry} object is constructed, if \tcode{sb} is null calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}). \pnum Gets characters from \tcode{sb} and inserts them in \tcode{*this}. Characters are read from \tcode{sb} and inserted until any of the following occurs: \begin{itemize} \item end-of-file occurs on the input sequence; \item inserting in the output sequence fails (in which case the character to be inserted is not extracted); \item an exception occurs while getting a character from \tcode{sb}. \end{itemize} \pnum If the function inserts no characters, it calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::\brk{}failure}\iref{iostate.flags}). If an exception was thrown while extracting a character, the function sets \tcode{failbit} in the error state, and if \tcode{failbit} is set in \tcode{exceptions()} the caught exception is rethrown. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} basic_ostream& operator<<(nullptr_t); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return *this << s; \end{codeblock} where \tcode{s} is an \impldef{NTCTS in \tcode{basic_ostream\& op\-er\-ator<<(nullptr_t)}} NTCTS\iref{defns.ntcts}. \end{itemdescr} \rSec4[ostream.inserters.character]{Character inserter function templates} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} template basic_ostream& operator<<(basic_ostream& out, charT c); template basic_ostream& operator<<(basic_ostream& out, char c); // specialization template basic_ostream& operator<<(basic_ostream& out, char c); // signed and unsigned template basic_ostream& operator<<(basic_ostream& out, signed char c); template basic_ostream& operator<<(basic_ostream& out, unsigned char c); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as a formatted output function\iref{ostream.formatted.reqmts} of \tcode{out}. Constructs a character sequence \tcode{seq}. If \tcode{c} has type \tcode{char} and the character container type of the stream is not \tcode{char}, then \tcode{seq} consists of \tcode{out.widen(c)}; otherwise \tcode{seq} consists of \tcode{c}. Determines padding for \tcode{seq} as described in~\ref{ostream.formatted.reqmts}. Inserts \tcode{seq} into \tcode{out}. Calls \tcode{os.width(0)}. \pnum \returns \tcode{out}. \end{itemdescr} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} template basic_ostream& operator<<(basic_ostream& out, const charT* s); template basic_ostream& operator<<(basic_ostream& out, const char* s); template basic_ostream& operator<<(basic_ostream& out, const char* s); template basic_ostream& operator<<(basic_ostream& out, const signed char* s); template basic_ostream& operator<<(basic_ostream& out, const unsigned char* s); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{s} is not a null pointer. \pnum \effects Behaves like a formatted inserter (as described in~\ref{ostream.formatted.reqmts}) of \tcode{out}. Creates a character sequence \tcode{seq} of \tcode{n} characters starting at \tcode{s}, each widened using \tcode{out.widen()}\iref{basic.ios.members}, where \tcode{n} is the number that would be computed as if by: \begin{itemize} \item \tcode{traits::length(s)} for the overload where the first argument is of type \tcode{basic_ostream\&} and the second is of type \tcode{const charT*}, and also for the overload where the first argument is of type \tcode{basic_ostream\&} and the second is of type \tcode{const char*}, \item \tcode{char_traits::length(s)} for the overload where the first argument is of type \tcode{basic_ostream\&} and the second is of type \tcode{const char*}, \item \tcode{traits::length(reinterpret_cast(s))} for the other two overloads. \end{itemize} Determines padding for \tcode{seq} as described in~\ref{ostream.formatted.reqmts}. Inserts \tcode{seq} into \tcode{out}. Calls \tcode{width(0)}. \pnum \returns \tcode{out}. \end{itemdescr} \rSec4[ostream.formatted.print]{Print} \indexlibraryglobal{print}% \begin{itemdecl} template void print(ostream& os, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: \begin{codeblock} vprint_unicode(os, fmt.@\exposid{str}@, make_format_args(args...)); \end{codeblock} Otherwise, equivalent to: \begin{codeblock} vprint_nonunicode(os, fmt.@\exposid{str}@, make_format_args(args...)); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} template void println(ostream& os, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} print(os, "{}\n", format(fmt, std::forward(args)...)); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} void println(ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} print(os, "\n"); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_unicode}% \indexlibraryglobal{vprint_nonunicode}% \begin{itemdecl} void vprint_unicode(ostream& os, string_view fmt, format_args args); void vprint_nonunicode(ostream& os, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as a formatted output function\iref{ostream.formatted.reqmts} of \tcode{os}, except that: \begin{itemize} \item failure to generate output is reported as specified below, and \item any exception thrown by the call to \tcode{vformat} is propagated without regard to the value of \tcode{os.exceptions()} and without turning on \tcode{ios_base::badbit} in the error state of \tcode{os}. \end{itemize} After constructing a \tcode{sentry} object, the function initializes an automatic variable via \begin{codeblock} string out = vformat(os.getloc(), fmt, args); \end{codeblock} If the function is \tcode{vprint_unicode} and \tcode{os} is a stream that refers to a terminal capable of displaying Unicode which is determined in an implementation-defined manner, writes \tcode{out} to the terminal using the native Unicode API; if \tcode{out} contains invalid code units, \indextext{undefined}% the behavior is undefined and implementations are encouraged to diagnose it. If the native Unicode API is used, the function flushes \tcode{os} before writing \tcode{out}. Otherwise (if \tcode{os} is not such a stream or the function is \tcode{vprint_nonunicode}), inserts the character sequence \range{out.begin()}{out.end()} into \tcode{os}. If writing to the terminal or inserting into \tcode{os} fails, calls \tcode{os.setstate(ios_base::badbit)} (which may throw \tcode{ios_base::failure}). \pnum \recommended For \tcode{vprint_unicode}, if invoking the native Unicode API requires transcoding, implementations should substitute invalid code units with \unicode{fffd}{replacement character} per the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. \end{itemdescr} \rSec3[ostream.unformatted]{Unformatted output functions} \pnum Each unformatted output function begins execution by constructing an object of class \tcode{sentry}. If that object returns \tcode{true}, while converting to a value of type \tcode{bool}, the function endeavors to generate the requested output. If an exception is thrown during output, then \tcode{ios_base::badbit} is set \begin{footnote} This is done without causing an \tcode{ios_base::failure} to be thrown. \end{footnote} in \tcode{*this}'s error state. If \tcode{(exceptions() \& badbit) != 0} then the exception is rethrown. In any case, the unformatted output function ends by destroying the \tcode{sentry} object, then, if no exception was thrown, returning the value specified for the unformatted output function. \indexlibrarymember{put}{basic_ostream}% \begin{itemdecl} basic_ostream& put(char_type c); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted output function (as described above). After constructing a \tcode{sentry} object, inserts the character \tcode{c}, if possible. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} \pnum Otherwise, calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{write}{basic_ostream}% \begin{itemdecl} basic_ostream& write(const char_type* s, streamsize n); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted output function (as described above). After constructing a \tcode{sentry} object, obtains characters to insert from successive locations of an array whose first element is designated by \tcode{s}. \begin{footnote} Note that this function is not overloaded on types \tcode{signed char} and \tcode{unsigned char}. \end{footnote} Characters are inserted until either of the following occurs: \begin{itemize} \item \tcode{n} characters are inserted; \item inserting in the output sequence fails (in which case the function calls \tcode{setstate(badbit)}, which may throw \tcode{ios_base::failure}\iref{iostate.flags}). \end{itemize} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{flush}{basic_ostream}% \begin{itemdecl} basic_ostream& flush(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted output function (as described above). If \tcode{rdbuf()} is not a null pointer, constructs a \tcode{sentry} object. If that object returns \tcode{true} when converted to a value of type \tcode{bool} the function calls \tcode{rdbuf()->pubsync()}. If that function returns $-1$ calls \tcode{setstate(badbit)} (which may throw \tcode{ios_base::failure}\iref{iostate.flags}). Otherwise, if the \tcode{sentry} object returns \tcode{false}, does nothing. \pnum \returns \tcode{*this}. \end{itemdescr} \rSec3[ostream.manip]{Standard \tcode{basic_ostream} manipulators} \pnum Each instantiation of any of the function templates specified in this subclause is a designated addressable function\iref{namespace.std}. \indexlibraryglobal{endl}% \begin{itemdecl} template basic_ostream& endl(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{os.put(os.widen('\textbackslash n'))}, then \tcode{os.flush()}. \pnum \returns \tcode{os}. \end{itemdescr} \indexlibraryglobal{ends}% \begin{itemdecl} template basic_ostream& ends(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects Inserts a null character into the output sequence: calls \tcode{os.put(charT())}. \pnum \returns \tcode{os}. \end{itemdescr} \indexlibraryglobal{flush}% \begin{itemdecl} template basic_ostream& flush(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{os.flush()}. \pnum \returns \tcode{os}. \end{itemdescr} \indexlibraryglobal{emit_on_flush}% \begin{itemdecl} template basic_ostream& emit_on_flush(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{os.rdbuf()} is a \tcode{basic_syncbuf*}, called \tcode{buf} for the purpose of exposition, calls \tcode{buf->set_emit_on_sync(true)}. Otherwise this manipulator has no effect. \begin{note} To work around the issue that the \tcode{Allocator} template argument cannot be deduced, implementations can introduce an intermediate base class to \tcode{basic_syncbuf} that manages its \exposid{emit-on-sync} flag. \end{note} \pnum \returns \tcode{os}. \end{itemdescr} \indexlibraryglobal{noemit_on_flush}% \begin{itemdecl} template basic_ostream& noemit_on_flush(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{os.rdbuf()} is a \tcode{basic_syncbuf*}, called \tcode{buf} for the purpose of exposition, calls \tcode{buf->set_emit_on_sync(false)}. Otherwise this manipulator has no effect. \pnum \returns \tcode{os}. \end{itemdescr} \indexlibraryglobal{flush_emit}% \begin{itemdecl} template basic_ostream& flush_emit(basic_ostream& os); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{os.flush()}. Then, if \tcode{os.rdbuf()} is a \tcode{basic_syncbuf*}, called \tcode{buf} for the purpose of exposition, behaves as an unformatted output function\iref{ostream.unformatted} of \tcode{os}. After constructing a \tcode{sentry} object, calls \tcode{buf->emit()}. If that call returns \tcode{false}, calls \tcode{os.setstate(ios_base::badbit)}. \pnum \returns \tcode{os}. \end{itemdescr} \rSec3[ostream.rvalue]{Rvalue stream insertion} \indexlibrarymember{operator<<}{basic_ostream}% \begin{itemdecl} template Ostream&& operator<<(Ostream&& os, const T& x); \end{itemdecl} \begin{itemdescr} \pnum \constraints The expression \tcode{os << x} is well-formed when treated as an unevaluated operand and \tcode{Ostream} is publicly and unambiguously derived from \tcode{ios_base}. \pnum \effects As if by: \tcode{os << x;} \pnum \returns \tcode{std::move(os)}. \end{itemdescr} \rSec2[std.manip]{Standard manipulators} \pnum The header \libheader{iomanip} defines several functions that support extractors and inserters that alter information maintained by class \tcode{ios_base} and its derived classes. \indexlibraryglobal{resetiosflags}% \begin{itemdecl} @\unspec@ resetiosflags(ios_base::fmtflags mask); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << resetiosflags(mask)} behaves as if it called \tcode{f(out, mask)}, or if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> resetiosflags(\brk{}mask)} behaves as if it called \tcode{f(in, mask)}, where the function \tcode{f} is defined as: \begin{footnote} The expression \tcode{cin >> resetiosflags(ios_base::skipws)} clears \tcode{ios_base::skipws} in the format flags stored in the \tcode{basic_istream} object \tcode{cin} (the same as \tcode{cin >> noskipws}), and the expression \tcode{cout << resetiosflags(ios_base::showbase)} clears \tcode{ios_base::showbase} in the format flags stored in the \tcode{basic_ostream} object \tcode{cout} (the same as \tcode{cout << noshowbase}). \end{footnote} \begin{codeblock} void f(ios_base& str, ios_base::fmtflags mask) { // reset specified flags str.setf(ios_base::fmtflags(0), mask); } \end{codeblock} The expression \tcode{out << resetiosflags(mask)} has type \tcode{basic_ostream\&} and value \tcode{out}. The expression \tcode{in >> resetiosflags(mask)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{setiosflags}% \begin{itemdecl} @\unspec@ setiosflags(ios_base::fmtflags mask); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << setiosflags(mask)} behaves as if it called \tcode{f(out, mask)}, or if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> setiosflags(mask)} behaves as if it called \tcode{f(in, mask)}, where the function \tcode{f} is defined as: \indexlibrarymember{fmtflags}{ios_base}% \begin{codeblock} void f(ios_base& str, ios_base::fmtflags mask) { // set specified flags str.setf(mask); } \end{codeblock} The expression \tcode{out << setiosflags(mask)} has type \tcode{basic_ostream\&} and value \tcode{out}. The expression \tcode{in >> setiosflags(mask)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{setbase}% \begin{itemdecl} @\unspec@ setbase(int base); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << setbase(base)} behaves as if it called \tcode{f(out, base)}, or if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> setbase(base)} behaves as if it called \tcode{f(in, base)}, where the function \tcode{f} is defined as: \begin{codeblock} void f(ios_base& str, int base) { // set \tcode{basefield} str.setf(base == 8 ? ios_base::oct : base == 10 ? ios_base::dec : base == 16 ? ios_base::hex : ios_base::fmtflags(0), ios_base::basefield); } \end{codeblock} The expression \tcode{out << setbase(base)} has type \tcode{basic_ostream\&} and value \tcode{out}. The expression \tcode{in >> setbase(base)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{setfill}% \begin{itemdecl} @\unspec@ setfill(char_type c); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} and \tcode{c} has type \tcode{charT} then the expression \tcode{out << setfill(c)} behaves as if it called \tcode{f(out, c)}, where the function \tcode{f} is defined as: \begin{codeblock} template void f(basic_ios& str, charT c) { // set fill character str.fill(c); } \end{codeblock} The expression \tcode{out << setfill(c)} has type \tcode{basic_ostream\&} and value \tcode{out}. \end{itemdescr} \indexlibraryglobal{setprecision}% \begin{itemdecl} @\unspec@ setprecision(int n); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << setprecision(n)} behaves as if it called \tcode{f(out, n)}, or if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> setprecision(n)} behaves as if it called \tcode{f(in, n)}, where the function \tcode{f} is defined as: \begin{codeblock} void f(ios_base& str, int n) { // set precision str.precision(n); } \end{codeblock} The expression \tcode{out << setprecision(n)} has type \tcode{basic_ostream\&} and value \tcode{out}. The expression \tcode{in >> setprecision(n)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{setw}% \begin{itemdecl} @\unspec@ setw(int n); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an instance of \tcode{basic_ostream} then the expression \tcode{out << setw(n)} behaves as if it called \tcode{f(out, n)}, or if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> setw(n)} behaves as if it called \tcode{f(in, n)}, where the function \tcode{f} is defined as: \begin{codeblock} void f(ios_base& str, int n) { // set width str.width(n); } \end{codeblock} The expression \tcode{out << setw(n)} has type \tcode{basic_ostream\&} and value \tcode{out}. The expression \tcode{in >> setw(n)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \rSec2[ext.manip]{Extended manipulators} \pnum The header \libheader{iomanip} defines several functions that support extractors and inserters that allow for the parsing and formatting of sequences and values for money and time. \indexlibraryglobal{get_money}% \begin{itemdecl} template @\unspec@ get_money(moneyT& mon, bool intl = false); \end{itemdecl} \begin{itemdescr} \pnum \mandates The type \tcode{moneyT} is either \tcode{long double} or a specialization of the \tcode{basic_string} template\iref{strings}. \pnum \effects The expression \tcode{in >> get_money(mon, intl)} described below behaves as a formatted input function\iref{istream.formatted.reqmts}. \pnum \returns An object of unspecified type such that if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> get_money(mon, intl)} behaves as if it called \tcode{f(in, mon, intl)}, where the function \tcode{f} is defined as: \begin{codeblock} template void f(basic_ios& str, moneyT& mon, bool intl) { using Iter = istreambuf_iterator; using MoneyGet = money_get; ios_base::iostate err = ios_base::goodbit; const MoneyGet& mg = use_facet(str.getloc()); mg.get(Iter(str.rdbuf()), Iter(), intl, str, err, mon); if (ios_base::goodbit != err) str.setstate(err); } \end{codeblock} The expression \tcode{in >> get_money(mon, intl)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{put_money}% \begin{itemdecl} template @\unspec@ put_money(const moneyT& mon, bool intl = false); \end{itemdecl} \begin{itemdescr} \pnum \mandates The type \tcode{moneyT} is either \tcode{long double} or a specialization of the \tcode{basic_string} template\iref{strings}. \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << put_money(mon, intl)} behaves as a formatted output function\iref{ostream.formatted.reqmts} that calls \tcode{f(out, mon, intl)}, where the function \tcode{f} is defined as: \begin{codeblock} template void f(basic_ios& str, const moneyT& mon, bool intl) { using Iter = ostreambuf_iterator; using MoneyPut = money_put; const MoneyPut& mp = use_facet(str.getloc()); const Iter end = mp.put(Iter(str.rdbuf()), intl, str, str.fill(), mon); if (end.failed()) str.setstate(ios_base::badbit); } \end{codeblock} The expression \tcode{out << put_money(mon, intl)} has type \tcode{basic_ostream\&} and value \tcode{out}. \end{itemdescr} \indexlibraryglobal{get_time}% \begin{itemdecl} template @\unspec@ get_time(tm* tmb, const charT* fmt); \end{itemdecl} \begin{itemdescr} \pnum \expects The argument \tcode{tmb} is a valid pointer to an object of type \tcode{tm}, and \range{fmt}{fmt + char_traits::length(fmt)} is a valid range. \pnum \returns An object of unspecified type such that if \tcode{in} is an object of type \tcode{basic_istream} then the expression \tcode{in >> get_time(tmb, fmt)} behaves as if it called \tcode{f(in, tmb, fmt)}, where the function \tcode{f} is defined as: \begin{codeblock} template void f(basic_ios& str, tm* tmb, const charT* fmt) { using Iter = istreambuf_iterator; using TimeGet = time_get; ios_base::iostate err = ios_base::goodbit; const TimeGet& tg = use_facet(str.getloc()); tg.get(Iter(str.rdbuf()), Iter(), str, err, tmb, fmt, fmt + traits::length(fmt)); if (err != ios_base::goodbit) str.setstate(err); } \end{codeblock} The expression \tcode{in >> get_time(tmb, fmt)} has type \tcode{basic_istream\&} and value \tcode{in}. \end{itemdescr} \indexlibraryglobal{put_time}% \begin{itemdecl} template @\unspec@ put_time(const tm* tmb, const charT* fmt); \end{itemdecl} \begin{itemdescr} \pnum \expects The argument \tcode{tmb} is a valid pointer to an object of type \tcode{tm}, and \range{fmt}{fmt + char_traits::length(fmt)} is a valid range. \pnum \returns An object of unspecified type such that if \tcode{out} is an object of type \tcode{basic_ostream} then the expression \tcode{out << put_time(tmb, fmt)} behaves as if it called \tcode{f(out, tmb, fmt)}, where the function \tcode{f} is defined as: \begin{codeblock} template void f(basic_ios& str, const tm* tmb, const charT* fmt) { using Iter = ostreambuf_iterator; using TimePut = time_put; const TimePut& tp = use_facet(str.getloc()); const Iter end = tp.put(Iter(str.rdbuf()), str, str.fill(), tmb, fmt, fmt + traits::length(fmt)); if (end.failed()) str.setstate(ios_base::badbit); } \end{codeblock} The expression \tcode{out << put_time(tmb, fmt)} has type \tcode{basic_ostream\&} and value \tcode{out}. \end{itemdescr} \rSec2[quoted.manip]{Quoted manipulators} \pnum \begin{note} Quoted manipulators provide string insertion and extraction of quoted strings (for example, XML and CSV formats). Quoted manipulators are useful in ensuring that the content of a string with embedded spaces remains unchanged if inserted and then extracted via stream I/O. \end{note} \indexlibraryglobal{quoted}% \begin{itemdecl} template @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\')); template @\unspec@ quoted(const basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); template @\unspec@ quoted(basic_string_view s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that if \tcode{out} is an instance of \tcode{basic_ostream} with member type \tcode{char_type} the same as \tcode{charT} and with member type \tcode{traits_type}, which in the second and third forms is the same as \tcode{traits}, then the expression \tcode{out << quoted(s, delim, escape)} behaves as a formatted output function\iref{ostream.formatted.reqmts} of \tcode{out}. This forms a character sequence \tcode{seq}, initially consisting of the following elements: \begin{itemize} \item \tcode{delim}. \item Each character in \tcode{s}. If the character to be output is equal to \tcode{escape} or \tcode{delim}, as determined by \tcode{traits_type::eq}, first output \tcode{escape}. \item \tcode{delim}. \end{itemize} Let \tcode{x} be the number of elements initially in \tcode{seq}. Then padding is determined for \tcode{seq} as described in~\ref{ostream.formatted.reqmts}, \tcode{seq} is inserted as if by calling \tcode{out.rdbuf()->sputn(seq, n)}, where \tcode{n} is the larger of \tcode{out.width()} and \tcode{x}, and \tcode{out.width(0)} is called. The expression \tcode{out << quoted(s, delim, escape)} has type \tcode{basic_ostream\&} and value \tcode{out}. \end{itemdescr} \indexlibraryglobal{quoted}% \begin{itemdecl} template @\unspec@ quoted(basic_string& s, @\itcorr@ charT delim = charT('"'), charT escape = charT('\\')); \end{itemdecl} \begin{itemdescr} \pnum \returns An object of unspecified type such that: \begin{itemize} \item If \tcode{in} is an instance of \tcode{basic_istream} with member types \tcode{char_type} and \tcode{traits_type} the same as \tcode{charT} and \tcode{traits}, respectively, then the expression \tcode{in >> quoted(s, delim, escape)} behaves as if it extracts the following characters from \tcode{in} using \tcode{operator>>(basic_istream\&, charT\&)}\iref{istream.extractors} which may throw \tcode{ios_base::failure}\iref{ios.failure}: \begin{itemize} \item If the first character extracted is equal to \tcode{delim}, as determined by \tcode{traits_type::eq}, then: \begin{itemize} \item Turn off the \tcode{skipws} flag. \item \tcode{s.clear()} \item Until an unescaped \tcode{delim} character is reached or \tcode{!in}, extract characters from \tcode{in} and append them to \tcode{s}, except that if an \tcode{escape} is reached, ignore it and append the next character to \tcode{s}. \item Discard the final \tcode{delim} character. \item Restore the \tcode{skipws} flag to its original value. \end{itemize} \item Otherwise, \tcode{in >> s}. \end{itemize} \item If \tcode{out} is an instance of \tcode{basic_ostream} with member types \tcode{char_type} and \tcode{traits_type} the same as \tcode{charT} and \tcode{traits}, respectively, then the expression \tcode{out << quoted(s, delim, escape)} behaves as specified for the \tcode{const basic_string\&} overload of the \tcode{quoted} function. \item The expression \tcode{in >> quoted(s, delim, escape)} has type \tcode{basic_istream\&} and value \tcode{in}. \item The expression \tcode{out << quoted(s, delim, escape)} has type \tcode{basic_ostream\brk{}\&} and value \tcode{out}. \end{itemize} \end{itemdescr} \rSec2[print.fun]{Print functions} \indexlibraryglobal{print}% \begin{itemdecl} template void print(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} print(stdout, fmt, std::forward(args)...); \end{codeblock} \end{itemdescr} \indexlibraryglobal{print}% \begin{itemdecl} template void print(FILE* stream, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{locksafe} be \tcode{(enable_nonlocking_formatter_optimization> \&\& ...)}. If the ordinary literal encoding\iref{lex.charset} is UTF-8, equivalent to: \begin{codeblock} locksafe ? vprint_unicode(stream, fmt.str, make_format_args(args...)) : vprint_unicode_buffered(stream, fmt.str, make_format_args(args...)); \end{codeblock} Otherwise, equivalent to: \begin{codeblock} locksafe ? vprint_nonunicode(stream, fmt.str, make_format_args(args...)) : vprint_nonunicode_buffered(stream, fmt.str, make_format_args(args...)); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} template void println(format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} println(stdout, fmt, std::forward(args)...); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} void println(); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} println(stdout); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} template void println(FILE* stream, format_string fmt, Args&&... args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} print(stream, runtime_format(string(fmt.get()) + '\n'), std::forward(args)...); \end{codeblock} \end{itemdescr} \indexlibraryglobal{println}% \begin{itemdecl} void println(FILE* stream); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} print(stream, "\n"); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_unicode}% \begin{itemdecl} void vprint_unicode(string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} vprint_unicode(stdout, fmt, args); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_unicode_buffered}% \begin{itemdecl} void vprint_unicode_buffered(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} string out = vformat(fmt, args); vprint_unicode(stream, "{}", make_format_args(out)); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_unicode}% \begin{itemdecl} void vprint_unicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{stream} is a valid pointer to an output C stream. \pnum \effects Locks \tcode{stream}. Let \tcode{out} denote the character representation of formatting arguments provided by \tcode{args} formatted according to specifications given in \tcode{fmt}. If \tcode{stream} refers to a terminal capable of displaying Unicode, writes \tcode{out} to the terminal using the native Unicode API; if \tcode{out} contains invalid code units, \indextext{undefined}% the behavior is undefined and implementations are encouraged to diagnose it. Otherwise writes \tcode{out} to \tcode{stream} unchanged. If the native Unicode API is used, the function flushes \tcode{stream} before writing \tcode{out}. Unconditionally unlocks \tcode{stream} on function exit. \xrefc{7.21.2}. \begin{note} On POSIX and Windows, \tcode{stream} referring to a terminal means that, respectively, \tcode{isatty(fileno(\linebreak{}stream))} and \tcode{GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)} return nonzero. \end{note} \begin{note} On Windows, the native Unicode API is \tcode{WriteConsoleW}. \end{note} \pnum \throws Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. \tcode{system_error} if writing to the terminal or \tcode{stream} fails. May throw \tcode{bad_alloc}. \pnum \recommended If invoking the native Unicode API requires transcoding, implementations should substitute invalid code units with \unicode{fffd}{replacement character} per the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. \end{itemdescr} \indexlibraryglobal{vprint_nonunicode}% \begin{itemdecl} void vprint_nonunicode(string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} vprint_nonunicode(stdout, fmt, args); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_nonunicode_buffered}% \begin{itemdecl} void vprint_nonunicode_buffered(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} string out = vformat(fmt, args); vprint_nonunicode("{}", make_format_args(out)); \end{codeblock} \end{itemdescr} \indexlibraryglobal{vprint_nonunicode}% \begin{itemdecl} void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{stream} is a valid pointer to an output C stream. \pnum \effects While holding the lock on \tcode{stream}, writes the character representation of formatting arguments provided by \tcode{args} formatted according to specifications given in \tcode{fmt} to \tcode{stream}. \pnum \throws Any exception thrown by the call to \tcode{vformat}\iref{format.err.report}. \tcode{system_error} if writing to \tcode{stream} fails. May throw \tcode{bad_alloc}. \end{itemdescr} \rSec1[string.streams]{String-based streams} \rSec2[sstream.syn]{Header \tcode{} synopsis} \indexheader{sstream}% \indexlibraryglobal{stringbuf}% \indexlibraryglobal{basic_stringbuf}% \indexlibraryglobal{wstringbuf}% \indexlibraryglobal{basic_stringbuf}% \indexlibraryglobal{istringstream}% \indexlibraryglobal{basic_istringstream}% \indexlibraryglobal{wistringstream}% \indexlibraryglobal{basic_istringstream}% \indexlibraryglobal{ostringstream}% \indexlibraryglobal{basic_ostringstream}% \indexlibraryglobal{wostringstream}% \indexlibraryglobal{basic_ostringstream}% \indexlibraryglobal{stringstream}% \indexlibraryglobal{basic_stringstream}% \indexlibraryglobal{wstringstream}% \indexlibraryglobal{basic_stringstream}% \begin{codeblock} namespace std { // \ref{stringbuf}, class template \tcode{basic_stringbuf} template, class Allocator = allocator> class basic_stringbuf; template void swap(basic_stringbuf& x, basic_stringbuf& y) noexcept(noexcept(x.swap(y))); using stringbuf = basic_stringbuf; using wstringbuf = basic_stringbuf; // \ref{istringstream}, class template \tcode{basic_istringstream} template, class Allocator = allocator> class basic_istringstream; template void swap(basic_istringstream& x, basic_istringstream& y); using istringstream = basic_istringstream; using wistringstream = basic_istringstream; // \ref{ostringstream}, class template \tcode{basic_ostringstream} template, class Allocator = allocator> class basic_ostringstream; template void swap(basic_ostringstream& x, basic_ostringstream& y); using ostringstream = basic_ostringstream; using wostringstream = basic_ostringstream; // \ref{stringstream}, class template \tcode{basic_stringstream} template, class Allocator = allocator> class basic_stringstream; template void swap(basic_stringstream& x, basic_stringstream& y); using stringstream = basic_stringstream; using wstringstream = basic_stringstream; } \end{codeblock} \pnum The header \libheader{sstream} defines four class templates and eight types that associate stream buffers with objects of class \tcode{basic_string}, \indexlibraryglobal{basic_string}% as described in~\ref{string.classes}. \rSec2[stringbuf]{Class template \tcode{basic_stringbuf}} \rSec3[stringbuf.general]{General} \indexlibraryglobal{basic_stringbuf}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_stringbuf : public basic_streambuf { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; // \ref{stringbuf.cons}, constructors basic_stringbuf() : basic_stringbuf(ios_base::in | ios_base::out) {} explicit basic_stringbuf(ios_base::openmode which); explicit basic_stringbuf( const basic_string& s, ios_base::openmode which = ios_base::in | ios_base::out); explicit basic_stringbuf(const Allocator& a) : basic_stringbuf(ios_base::in | ios_base::out, a) {} basic_stringbuf(ios_base::openmode which, const Allocator& a); explicit basic_stringbuf( basic_string&& s, ios_base::openmode which = ios_base::in | ios_base::out); template basic_stringbuf( const basic_string& s, const Allocator& a) : basic_stringbuf(s, ios_base::in | ios_base::out, a) {} template basic_stringbuf( const basic_string& s, ios_base::openmode which, const Allocator& a); template explicit basic_stringbuf( const basic_string& s, ios_base::openmode which = ios_base::in | ios_base::out); template explicit basic_stringbuf(const T& t, ios_base::openmode which = ios_base::in | ios_base::out); template basic_stringbuf(const T& t, const Allocator& a); template basic_stringbuf(const T& t, ios_base::openmode which, const Allocator& a); basic_stringbuf(const basic_stringbuf&) = delete; basic_stringbuf(basic_stringbuf&& rhs); basic_stringbuf(basic_stringbuf&& rhs, const Allocator& a); // \ref{stringbuf.assign}, assignment and swap basic_stringbuf& operator=(const basic_stringbuf&) = delete; basic_stringbuf& operator=(basic_stringbuf&& rhs); void swap(basic_stringbuf& rhs) noexcept(@\seebelow@); // \ref{stringbuf.members}, getters and setters allocator_type get_allocator() const noexcept; basic_string str() const &; template basic_string str(const SAlloc& sa) const; basic_string str() &&; basic_string_view view() const noexcept; void str(const basic_string& s); template void str(const basic_string& s); void str(basic_string&& s); template void str(const T& t); protected: // \ref{stringbuf.virtuals}, overridden virtual functions int_type underflow() override; int_type pbackfail(int_type c = traits::eof()) override; int_type overflow (int_type c = traits::eof()) override; basic_streambuf* setbuf(charT*, streamsize) 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; private: ios_base::openmode @\exposid{mode}@; // \expos basic_string @\exposid{buf}@; // \expos void @\exposid{init-buf-ptrs}@(); // \expos }; } \end{codeblock} \pnum The class \tcode{basic_stringbuf} is derived from \tcode{basic_streambuf} to associate possibly the input sequence and possibly the output sequence with a sequence of arbitrary \term{characters}. The sequence can be initialized from, or made available as, an object of class \tcode{basic_string}. \pnum For the sake of exposition, the maintained data and internal pointer initialization is presented here as: \begin{itemize} \item \tcode{ios_base::openmode \exposid{mode}}, has \tcode{in} set if the input sequence can be read, and \tcode{out} set if the output sequence can be written. \item \tcode{basic_string \exposid{buf}} contains the underlying character sequence. \item \tcode{\exposid{init-buf-ptrs}()} sets the base class' get area\iref{streambuf.get.area} and put area\iref{streambuf.put.area} pointers after initializing, moving from, or assigning to \exposid{buf} accordingly. \end{itemize} \rSec3[stringbuf.cons]{Constructors} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} explicit basic_stringbuf(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, and \exposid{mode} with \tcode{which}. It is \impldef{whether sequence pointers are initialized to null pointers} whether the sequence pointers (\tcode{eback()}, \tcode{gptr()}, \tcode{egptr()}, \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}) are initialized to null pointers. \pnum \ensures \tcode{str().empty()} is \tcode{true}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} explicit basic_stringbuf( const basic_string& s, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, \exposid{mode} with \tcode{which}, and \exposid{buf} with \tcode{s}, then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} basic_stringbuf(ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, \exposid{mode} with \tcode{which}, and \exposid{buf} with \tcode{a}, then calls \tcode{\exposid{init-buf-ptrs}()}. \pnum \ensures \tcode{str().empty()} is \tcode{true}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} explicit basic_stringbuf( basic_string&& s, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, \exposid{mode} with \tcode{which}, and \exposid{buf} with \tcode{std::move(s)}, then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} template basic_stringbuf( const basic_string& s, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, \exposid{mode} with \tcode{which}, and \exposid{buf} with \tcode{\{s,a\}}, then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} template explicit basic_stringbuf( const basic_string& s, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{false}. \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, \exposid{mode} with \tcode{which}, and \exposid{buf} with \tcode{s}, then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} template explicit basic_stringbuf(const T& t, ios_base::openmode which = ios_base::in | ios_base::out); template basic_stringbuf(const T& t, const Allocator& a); template basic_stringbuf(const T& t, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{which} be \tcode{ios_base::in | ios_base::out} for the overload with no parameter \tcode{which}, and \tcode{a} be \tcode{Allocator()} for the overload with no parameter \tcode{a}. \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Creates a variable \tcode{sv} as if by \tcode{basic_string_view sv = t}, then value-initializes the base class, initializes \exposid{mode} with \tcode{which}, and direct-non-list-initializes \exposid{buf} with \tcode{sv, a}, then calls \tcode{\exposid{init-buf-ptrs}()}. \end{itemdescr} \indexlibraryctor{basic_stringbuf}% \begin{itemdecl} basic_stringbuf(basic_stringbuf&& rhs); basic_stringbuf(basic_stringbuf&& rhs, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Copy constructs the base class from \tcode{rhs} and initializes \exposid{mode} with \tcode{rhs.mode}. In the first form \tcode{buf} is initialized from \tcode{std::move(rhs).str()}. In the second form \exposid{buf} is initialized from \tcode{\{std::move(rhs).str(), a\}}. It is \impldef{whether sequence pointers are copied by \tcode{basic_stringbuf} move constructor} whether the sequence pointers in \tcode{*this} (\tcode{eback()}, \tcode{gptr()}, \tcode{egptr()}, \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}) obtain the values which \tcode{rhs} had. \pnum \ensures Let \tcode{rhs_p} refer to the state of \tcode{rhs} just prior to this construction and let \tcode{rhs_a} refer to the state of \tcode{rhs} just after this construction. \begin{itemize} \item \tcode{str() == rhs_p.str()} \item \tcode{gptr() - eback() == rhs_p.gptr() - rhs_p.eback()} \item \tcode{egptr() - eback() == rhs_p.egptr() - rhs_p.eback()} \item \tcode{pptr() - pbase() == rhs_p.pptr() - rhs_p.pbase()} \item \tcode{epptr() - pbase() == rhs_p.epptr() - rhs_p.pbase()} \item \tcode{if (eback()) eback() != rhs_a.eback()} \item \tcode{if (gptr()) gptr() != rhs_a.gptr()} \item \tcode{if (egptr()) egptr() != rhs_a.egptr()} \item \tcode{if (pbase()) pbase() != rhs_a.pbase()} \item \tcode{if (pptr()) pptr() != rhs_a.pptr()} \item \tcode{if (epptr()) epptr() != rhs_a.epptr()} \item \tcode{getloc() == rhs_p.getloc()} \item \tcode{rhs} is empty but usable, as if \tcode{std::move(rhs).str()} was called. \end{itemize} \end{itemdescr} \rSec3[stringbuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_stringbuf}% \begin{itemdecl} basic_stringbuf& operator=(basic_stringbuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects After the move assignment \tcode{*this} has the observable state it would have had if it had been move constructed from \tcode{rhs} (see~\ref{stringbuf.cons}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{basic_stringbuf}% \begin{itemdecl} void swap(basic_stringbuf& rhs) noexcept(@\seebelow@); \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{allocator_traits::propagate_on_container_swap::value} is \tcode{true} or \tcode{get_allocator() == rhs.get_allocator()} is \tcode{true}. \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs}. \pnum \remarks The exception specification is equivalent to:\\ \tcode{allocator_traits::propagate_on_container_swap::value ||}\\ \tcode{allocator_traits::is_always_equal::value} \end{itemdescr} \indexlibrarymember{swap}{basic_stringbuf}% \begin{itemdecl} template void swap(basic_stringbuf& x, basic_stringbuf& y) noexcept(noexcept(x.swap(y))); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[stringbuf.members]{Member functions} \pnum The member functions getting the underlying character sequence all refer to a \tcode{high_mark} value, where \tcode{high_mark} represents the position one past the highest initialized character in the buffer. Characters can be initialized by writing to the stream, by constructing the \tcode{basic_stringbuf} passing a \tcode{basic_string} argument, or by calling one of the \tcode{str} member functions passing a \tcode{basic_string} as an argument. In the latter case, all characters initialized prior to the call are now considered uninitialized (except for those characters re-initialized by the new \tcode{basic_string}). \begin{itemdecl} void @\exposid{init-buf-ptrs}@(); // \expos \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the input and output sequences from \exposid{buf} according to \exposid{mode}. \pnum \ensures \begin{itemize} \item If \tcode{ios_base::out} is set in \exposid{mode}, \tcode{pbase()} points to \tcode{\exposid{buf}.front()} and \tcode{epptr() >= pbase() + \exposid{buf}.size()} is \tcode{true}; \begin{itemize} \item in addition, if \tcode{ios_base::ate} is set in \exposid{mode}, \tcode{pptr() == pbase() + \exposid{buf}.size()} is \tcode{true}, \item otherwise \tcode{pptr() == pbase()} is \tcode{true}. \end{itemize} \item If \tcode{ios_base::in} is set in \exposid{mode}, \tcode{eback()} points to \tcode{\exposid{buf}.front()}, and \tcode{(gptr() == eback() \&\& egptr() == eback() + \exposid{buf}.size())} is \tcode{true}. \end{itemize} \pnum \begin{note} For efficiency reasons, stream buffer operations can violate invariants of \exposid{buf} while it is held encapsulated in the \tcode{basic_stringbuf}, e.g., by writing to characters in the range \range{\tcode{\exposid{buf}.data() + \exposid{buf}.size()}}{\tcode{\exposid{buf}.data() + \exposid{buf}.capacity()}}. All operations retrieving a \tcode{basic_string} from \tcode{buf} ensure that the \tcode{basic_string} invariants hold on the returned value. \end{note} \end{itemdescr} \indexlibrarymember{get_allocator}{basic_stringbuf}% \begin{itemdecl} allocator_type get_allocator() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{buf}.get_allocator()}. \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} basic_string str() const &; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return basic_string(view(), get_allocator()); \end{codeblock} \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} template basic_string str(const SAlloc& sa) const; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{SAlloc} is a type that qualifies as an allocator\iref{container.reqmts}. \pnum \effects Equivalent to: \begin{codeblock} return basic_string(view(), sa); \end{codeblock} \end{itemdescr} \begin{itemdecl} basic_string str() &&; \end{itemdecl} \begin{itemdescr} \pnum \ensures The underlying character sequence \tcode{buf} is empty and \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}, \tcode{eback()}, \tcode{gptr()}, and \tcode{egptr()} are initialized as if by calling \tcode{\exposid{init-buf-ptrs}()} with an empty \tcode{buf}. \pnum \returns A \tcode{basic_string} object move constructed from the \tcode{basic_stringbuf}'s underlying character sequence in \tcode{buf}. This can be achieved by first adjusting \tcode{buf} to have the same content as \tcode{view()}. \end{itemdescr} \indexlibrarymember{view}{basic_stringbuf}% \begin{itemdecl} basic_string_view view() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{sv} be \tcode{basic_string_view}. \pnum \returns A \tcode{sv} object referring to the \tcode{basic_stringbuf}'s underlying character sequence in \tcode{buf}: \begin{itemize} \item If \tcode{ios_base::out} is set in \exposid{mode}, then \tcode{sv(pbase(), high_mark-pbase())} is returned. \item Otherwise, if \tcode{ios_base::in} is set in \exposid{mode}, then \tcode{sv(eback(), egptr()-eback())} is returned. \item Otherwise, \tcode{sv()} is returned. \end{itemize} \pnum \begin{note} Using the returned \tcode{sv} object after destruction or invalidation of the character sequence underlying \tcode{*this} is undefined behavior, unless \tcode{sv.empty()} is \tcode{true}. \end{note} \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} @\exposid{buf}@ = s; @\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} template void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{false}. \pnum \effects Equivalent to: \begin{codeblock} @\exposid{buf}@ = s; @\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} void str(basic_string&& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} @\exposid{buf}@ = std::move(s); @\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} \indexlibrarymember{str}{basic_stringbuf}% \begin{itemdecl} template void str(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Equivalent to: \begin{codeblock} basic_string_view sv = t; @\exposid{buf}@ = sv; @\exposid{init-buf-ptrs}@(); \end{codeblock} \end{itemdescr} \rSec3[stringbuf.virtuals]{Overridden virtual functions} \indexlibrarymember{underflow}{basic_stringbuf}% \begin{itemdecl} int_type underflow() override; \end{itemdecl} \begin{itemdescr} \pnum \returns If the input sequence has a read position available, returns \tcode{traits::to_int_type(*gptr())}. Otherwise, returns \tcode{traits::eof()}. Any character in the underlying buffer which has been initialized is considered to be part of the input sequence. \end{itemdescr} \indexlibrarymember{pbackfail}{basic_stringbuf}% \begin{itemdecl} int_type pbackfail(int_type c = traits::eof()) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Puts back the character designated by \tcode{c} to the input sequence, if possible, in one of three ways: \begin{itemize} \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{false} and if the input sequence has a putback position available, and if \tcode{traits::eq(to_char_type(c), gptr()[-1])} returns \tcode{true}, assigns \tcode{gptr() - 1} to \tcode{gptr()}. Returns: \tcode{c}. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{false} and if the input sequence has a putback position available, and if \exposid{mode} \tcode{\&} \tcode{ios_base::out} is nonzero, assigns \tcode{c} to \tcode{*--gptr()}. Returns: \tcode{c}. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true} and if the input sequence has a putback position available, assigns \tcode{gptr() - 1} to \tcode{gptr()}. Returns: \tcode{traits::not_eof(c)}. \end{itemize} \pnum \returns As specified above, or \tcode{traits::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}% \end{itemdescr} \indexlibrarymember{overflow}{basic_stringbuf}% \begin{itemdecl} int_type overflow(int_type c = traits::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{traits::eq_int_type(c, traits::eof())} returns \tcode{false} and if either the output sequence has a write position available or the function makes a write position available (as described below), the function calls \tcode{sputc(c)}. Signals success by returning \tcode{c}. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true}, there is no character to append. Signals success by returning a value other than \tcode{traits::eof()}. \end{itemize} \pnum \returns As specified above, or \tcode{traits::eof()} to indicate failure. \pnum \remarks The function can alter the number of write positions available as a result of any call. \pnum The function can make a write position available only if \tcode{ios_base::out} is set in \exposid{mode}. 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 at least one additional write position. If \tcode{ios_base::in} is set in \exposid{mode}, the function alters the read end pointer \tcode{egptr()} to point just past the new write position. \end{itemdescr} \indexlibrarymember{seekoff}{basic_stringbuf}% \begin{itemdecl} pos_type seekoff(off_type off, ios_base::seekdir way, 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, as indicated in \tref{stringbuf.seekoff.pos}. \begin{libtab2}{\tcode{seekoff} positioning}{stringbuf.seekoff.pos} {p{2.5in}l}{Conditions}{Result} \tcode{ios_base::in} is set in \tcode{which} & positions the input sequence \\ \rowsep \tcode{ios_base::out} is set in \tcode{which} & positions the output sequence \\ \rowsep both \tcode{ios_base::in} and \tcode{ios_base::out} are set in \tcode{which} and either\br \tcode{way == ios_base::beg} or\br \tcode{way == ios_base::end} & positions both the input and the output sequences \\ \rowsep Otherwise & the positioning operation fails. \\ \end{libtab2} \pnum For a sequence to be positioned, the function determines \tcode{newoff} as indicated in \tref{stringbuf.seekoff.newoff}. If the sequence's next pointer (either \tcode{gptr()} or \tcode{pptr()}) is a null pointer and \tcode{newoff} is nonzero, the positioning operation fails. \begin{libtab2}{\tcode{newoff} values}{stringbuf.seekoff.newoff} {lp{2.0in}}{Condition}{\tcode{newoff} Value} \tcode{way == ios_base::beg} & 0 \\ \rowsep \tcode{way == ios_base::cur} & the next pointer minus the beginning pointer (\tcode{xnext - xbeg}). \\ \rowsep \tcode{way == ios_base::end} & the high mark pointer minus the beginning pointer (\tcode{high_mark - xbeg}). \\ \end{libtab2} \pnum If \tcode{(newoff + off) < 0}, or if \tcode{newoff + off} refers to an uninitialized character\iref{stringbuf.members}, 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}{basic_stringbuf}% \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 Equivalent to \tcode{seekoff(off_type(sp), ios_base::beg, which)}. \pnum \returns \tcode{sp} to indicate success, or \tcode{pos_type(off_type(-1))} to indicate failure. \end{itemdescr} \indexlibrarymember{setbuf}{basic_streambuf}% \begin{itemdecl} basic_streambuf* setbuf(charT* s, streamsize n) override; \end{itemdecl} \begin{itemdescr} \pnum \effects \impldef{effect of calling \tcode{basic_streambuf::setbuf} with nonzero arguments}, except that \tcode{setbuf(0, 0)} has no effect. \pnum \returns \keyword{this}. \end{itemdescr} \rSec2[istringstream]{Class template \tcode{basic_istringstream}} \rSec3[istringstream.general]{General} \indexlibraryglobal{basic_istringstream}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_istringstream : public basic_istream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; // \ref{istringstream.cons}, constructors basic_istringstream() : basic_istringstream(ios_base::in) {} explicit basic_istringstream(ios_base::openmode which); explicit basic_istringstream( const basic_string& s, ios_base::openmode which = ios_base::in); basic_istringstream(ios_base::openmode which, const Allocator& a); explicit basic_istringstream( basic_string&& s, ios_base::openmode which = ios_base::in); template basic_istringstream( const basic_string& s, const Allocator& a) : basic_istringstream(s, ios_base::in, a) {} template basic_istringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); template explicit basic_istringstream( const basic_string& s, ios_base::openmode which = ios_base::in); template explicit basic_istringstream(const T& t, ios_base::openmode which = ios_base::in); template basic_istringstream(const T& t, const Allocator& a); template basic_istringstream(const T& t, ios_base::openmode which, const Allocator& a); basic_istringstream(const basic_istringstream&) = delete; basic_istringstream(basic_istringstream&& rhs); basic_istringstream& operator=(const basic_istringstream&) = delete; basic_istringstream& operator=(basic_istringstream&& rhs); // \ref{istringstream.swap}, swap void swap(basic_istringstream& rhs); // \ref{istringstream.members}, members basic_stringbuf* rdbuf() const; basic_string str() const &; template basic_string str(const SAlloc& sa) const; basic_string str() &&; basic_string_view view() const noexcept; void str(const basic_string& s); template void str(const basic_string& s); void str(basic_string&& s); template void str(const T& t); private: basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class \tcode{basic_istringstream} supports reading objects of class \tcode{basic_string<\brk{}charT, traits, Allocator>}. It uses a \tcode{basic_stringbuf} object to control the associated storage. For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[istringstream.cons]{Constructors} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} explicit basic_istringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} explicit basic_istringstream( const basic_string& s, ios_base::openmode which = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} basic_istringstream(ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::in, a)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} explicit basic_istringstream( basic_string&& s, ios_base::openmode which = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which | ios_base::\brk{}in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} template basic_istringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} template explicit basic_istringstream( const basic_string& s, ios_base::openmode which = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{false}. \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::in)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} template explicit basic_istringstream(const T& t, ios_base::openmode which = ios_base::in); template basic_istringstream(const T& t, const Allocator& a); template basic_istringstream(const T& t, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{which} be \tcode{ios_base::in} for the overload with no parameter \tcode{which}, and \tcode{a} be \tcode{Allocator()} for the overload with no parameter \tcode{a}. \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Initializes the base class with \tcode{addressof(\exposid{sb})}, and direct-non-list-initializes \exposid{sb} with \tcode{t, which | ios_base::in, a}. \end{itemdescr} \indexlibraryctor{basic_istringstream}% \begin{itemdecl} basic_istringstream(basic_istringstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. Then calls \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} \rSec3[istringstream.swap]{Swap} \indexlibrarymember{swap}{basic_istringstream}% \begin{itemdecl} void swap(basic_istringstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_istream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_istringstream}% \begin{itemdecl} template void swap(basic_istringstream& x, basic_istringstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[istringstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_istringstream}% \begin{itemdecl} basic_stringbuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} basic_string str() const &; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str();} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} template basic_string str(const SAlloc& sa) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str(sa);} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} basic_string str() &&; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return std::move(*rdbuf()).str();} \end{itemdescr} \indexlibrarymember{view}{basic_istringstream}% \begin{itemdecl} basic_string_view view() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->view();} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} template void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} void str(basic_string&& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(std::move(s));} \end{itemdescr} \indexlibrarymember{str}{basic_istringstream}% \begin{itemdecl} template void str(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Equivalent to: \tcode{rdbuf()->str(t);} \end{itemdescr} \rSec2[ostringstream]{Class template \tcode{basic_ostringstream}} \rSec3[ostringstream.general]{General} \indexlibraryglobal{basic_ostringstream}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_ostringstream : public basic_ostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; // \ref{ostringstream.cons}, constructors basic_ostringstream() : basic_ostringstream(ios_base::out) {} explicit basic_ostringstream(ios_base::openmode which); explicit basic_ostringstream( const basic_string& s, ios_base::openmode which = ios_base::out); basic_ostringstream(ios_base::openmode which, const Allocator& a); explicit basic_ostringstream( basic_string&& s, ios_base::openmode which = ios_base::out); template basic_ostringstream( const basic_string& s, const Allocator& a) : basic_ostringstream(s, ios_base::out, a) {} template basic_ostringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); template explicit basic_ostringstream( const basic_string& s, ios_base::openmode which = ios_base::out); template explicit basic_ostringstream(const T& t, ios_base::openmode which = ios_base::out); template basic_ostringstream(const T& t, const Allocator& a); template basic_ostringstream(const T& t, ios_base::openmode which, const Allocator& a); basic_ostringstream(const basic_ostringstream&) = delete; basic_ostringstream(basic_ostringstream&& rhs); basic_ostringstream& operator=(const basic_ostringstream&) = delete; basic_ostringstream& operator=(basic_ostringstream&& rhs); // \ref{ostringstream.swap}, swap void swap(basic_ostringstream& rhs); // \ref{ostringstream.members}, members basic_stringbuf* rdbuf() const; basic_string str() const &; template basic_string str(const SAlloc& sa) const; basic_string str() &&; basic_string_view view() const noexcept; void str(const basic_string& s); template void str(const basic_string& s); void str(basic_string&& s); template void str(const T& t); private: basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class \tcode{basic_ostringstream} supports writing objects of class \tcode{basic_string<\brk{}charT, traits, Allocator>}. It uses a \tcode{basic_stringbuf} object to control the associated storage. For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[ostringstream.cons]{Constructors} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} explicit basic_ostringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} explicit basic_ostringstream( const basic_string& s, ios_base::openmode which = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} basic_ostringstream(ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} explicit basic_ostringstream( basic_string&& s, ios_base::openmode which = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which | ios_base::\brk{}out)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} template basic_ostringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} template explicit basic_ostringstream( const basic_string& s, ios_base::openmode which = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{false}. \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream} and \exposid{sb} with \tcode{basic_stringbuf(s, which | ios_base::out)}\linebreak\iref{stringbuf.cons}. % avoid Overfull \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} template explicit basic_ostringstream(const T& t, ios_base::openmode which = ios_base::out); template basic_ostringstream(const T& t, const Allocator& a); template basic_ostringstream(const T& t, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{which} be \tcode{ios_base::out} for the overload with no parameter \tcode{which}, and \tcode{a} be \tcode{Allocator()} for the overload with no parameter \tcode{a}. \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Initializes the base class with \tcode{addressof(\exposid{sb})}, and direct-non-list-initializes \exposid{sb} with \tcode{t, which | ios_base::out, a}. \end{itemdescr} \indexlibraryctor{basic_ostringstream}% \begin{itemdecl} basic_ostringstream(basic_ostringstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. Then calls \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} \rSec3[ostringstream.swap]{Swap} \indexlibrarymember{swap}{basic_ostringstream}% \begin{itemdecl} void swap(basic_ostringstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_ostringstream}% \begin{itemdecl} template void swap(basic_ostringstream& x, basic_ostringstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[ostringstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_ostringstream}% \begin{itemdecl} basic_stringbuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} basic_string str() const &; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str();} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} template basic_string str(const SAlloc& sa) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str(sa);} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} basic_string str() &&; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return std::move(*rdbuf()).str();} \end{itemdescr} \indexlibrarymember{view}{basic_ostringstream}% \begin{itemdecl} basic_string_view view() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->view();} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} template void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} void str(basic_string&& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(std::move(s));} \end{itemdescr} \indexlibrarymember{str}{basic_ostringstream}% \begin{itemdecl} template void str(const T& t); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Equivalent to: \tcode{rdbuf()->str(t);} \end{itemdescr} \rSec2[stringstream]{Class template \tcode{basic_stringstream}} \rSec3[stringstream.general]{General} \indexlibraryglobal{basic_stringstream}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_stringstream : public basic_iostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; // \ref{stringstream.cons}, constructors basic_stringstream() : basic_stringstream(ios_base::out | ios_base::in) {} explicit basic_stringstream(ios_base::openmode which); explicit basic_stringstream( const basic_string& s, ios_base::openmode which = ios_base::out | ios_base::in); basic_stringstream(ios_base::openmode which, const Allocator& a); explicit basic_stringstream( basic_string&& s, ios_base::openmode which = ios_base::out | ios_base::in); template basic_stringstream( const basic_string& s, const Allocator& a) : basic_stringstream(s, ios_base::out | ios_base::in, a) {} template basic_stringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); template explicit basic_stringstream( const basic_string& s, ios_base::openmode which = ios_base::out | ios_base::in); template explicit basic_stringstream(const T& t, ios_base::openmode which = ios_base::out | ios_base::in); template basic_stringstream(const T& t, const Allocator& a); template basic_stringstream(const T& t, ios_base::openmode which, const Allocator& a); basic_stringstream(const basic_stringstream&) = delete; basic_stringstream(basic_stringstream&& rhs); basic_stringstream& operator=(const basic_stringstream&) = delete; basic_stringstream& operator=(basic_stringstream&& rhs); // \ref{stringstream.swap}, swap void swap(basic_stringstream& rhs); // \ref{stringstream.members}, members basic_stringbuf* rdbuf() const; basic_string str() const &; template basic_string str(const SAlloc& sa) const; basic_string str() &&; basic_string_view view() const noexcept; void str(const basic_string& s); template void str(const basic_string& s); void str(basic_string&& s); template void str(const T& t); private: basic_stringbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class template \tcode{basic_stringstream} supports reading and writing from objects of class \tcode{basic_string}. It uses a \tcode{basic_stringbuf} object to control the associated sequence. For the sake of exposition, the maintained data is presented here as \begin{itemize} \item \exposid{sb}, the \tcode{stringbuf} object. \end{itemize} \rSec3[stringstream.cons]{Constructors} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} explicit basic_stringstream(ios_base::openmode which); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_string\-buf(which)}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} explicit basic_stringstream( const basic_string& s, ios_base::openmode which = ios_base::out | ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_string\-buf(s, which)}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} basic_stringstream(ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_stringbuf(which, a)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} explicit basic_stringstream( basic_string&& s, ios_base::openmode which = ios_base::out | ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_stringbuf(std::move(s), which)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} template basic_stringstream( const basic_string& s, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_stringbuf(s, which, a)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} template explicit basic_stringstream( const basic_string& s, ios_base::openmode which = ios_base::out | ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{false}. \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_stringbuf(s, which)}\iref{stringbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} template explicit basic_stringstream(const T& t, ios_base::openmode which = ios_base::out | ios_base::in); template basic_stringstream(const T& t, const Allocator& a); template basic_stringstream(const T& t, ios_base::openmode which, const Allocator& a); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{which} be \tcode{ios_base::out | ios_base::in} for the overload with no parameter \tcode{which}, and \tcode{a} be \tcode{Allocator()} for the overload with no parameter \tcode{a}. \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Initializes the base class with \tcode{addressof(\exposid{sb})}, and direct-non-list-initializes \exposid{sb} with \tcode{t, which, a}. \end{itemdescr} \indexlibraryctor{basic_stringstream}% \begin{itemdecl} basic_stringstream(basic_stringstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs from the rvalue \tcode{rhs}. This is accomplished by move constructing the base class, and the contained \tcode{basic_stringbuf}. Then calls \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} to install the contained \tcode{basic_stringbuf}. \end{itemdescr} \rSec3[stringstream.swap]{Swap} \indexlibrarymember{swap}{basic_stringstream}% \begin{itemdecl} void swap(basic_stringstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_stringstream}% \begin{itemdecl} template void swap(basic_stringstream& x, basic_stringstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[stringstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_stringstream}% \begin{itemdecl} basic_stringbuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} basic_string str() const &; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str();} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} template basic_string str(const SAlloc& sa) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->str(sa);} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} basic_string str() &&; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return std::move(*rdbuf()).str();} \end{itemdescr} \indexlibrarymember{view}{basic_stringstream}% \begin{itemdecl} basic_string_view view() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->view();} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} template void str(const basic_string& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(s);} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} void str(basic_string&& s); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{rdbuf()->str(std::move(s));} \end{itemdescr} \indexlibrarymember{str}{basic_stringstream}% \begin{itemdecl} template void str(const T&); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_convertible_v>} is \tcode{true}. \pnum \effects Equivalent to: \tcode{rdbuf()->str(t);} \end{itemdescr} \rSec1[span.streams]{Span-based streams} \rSec2[span.streams.overview]{Overview} \pnum The header \libheaderdef{spanstream} defines class templates and types that associate stream buffers with objects whose types are specializations of \tcode{span} as described in \ref{views.span}. \begin{note} A user of these classes is responsible for ensuring that the character sequence represented by the given \tcode{span} outlives the use of the sequence by objects of the classes in \ref{span.streams}. Using multiple \tcode{basic_spanbuf} objects referring to overlapping underlying sequences from different threads, where at least one \tcode{basic_spanbuf} object is used for writing to the sequence, results in a data race. \end{note} \rSec2[spanstream.syn]{Header \tcode{} synopsis} \indexlibraryglobal{spanbuf}% \indexlibraryglobal{wspanbuf}% \indexlibraryglobal{ispanstream}% \indexlibraryglobal{wispanstream}% \indexlibraryglobal{ospanstream}% \indexlibraryglobal{wospanstream}% \indexlibraryglobal{spanstream}% \indexlibraryglobal{wspanstream}% \begin{codeblock} namespace std { // \ref{spanbuf}, class template \tcode{basic_spanbuf} template> class basic_spanbuf; template void swap(basic_spanbuf& x, basic_spanbuf& y); using spanbuf = basic_spanbuf; using wspanbuf = basic_spanbuf; // \ref{ispanstream}, class template \tcode{basic_ispanstream} template> class basic_ispanstream; template void swap(basic_ispanstream& x, basic_ispanstream& y); using ispanstream = basic_ispanstream; using wispanstream = basic_ispanstream; // \ref{ospanstream}, class template \tcode{basic_ospanstream} template> class basic_ospanstream; template void swap(basic_ospanstream& x, basic_ospanstream& y); using ospanstream = basic_ospanstream; using wospanstream = basic_ospanstream; // \ref{spanstream}, class template \tcode{basic_spanstream} template> class basic_spanstream; template void swap(basic_spanstream& x, basic_spanstream& y); using spanstream = basic_spanstream; using wspanstream = basic_spanstream; } \end{codeblock} \rSec2[spanbuf]{Class template \tcode{basic_spanbuf}} \rSec3[spanbuf.general]{General} \indexlibraryglobal{basic_spanbuf}% \begin{codeblock} namespace std { template> class basic_spanbuf : public basic_streambuf { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{spanbuf.cons}, constructors basic_spanbuf() : basic_spanbuf(ios_base::in | ios_base::out) {} explicit basic_spanbuf(ios_base::openmode which) : basic_spanbuf(std::span(), which) {} explicit basic_spanbuf(std::span s, ios_base::openmode which = ios_base::in | ios_base::out); basic_spanbuf(const basic_spanbuf&) = delete; basic_spanbuf(basic_spanbuf&& rhs); // \ref{spanbuf.assign}, assignment and swap basic_spanbuf& operator=(const basic_spanbuf&) = delete; basic_spanbuf& operator=(basic_spanbuf&& rhs); void swap(basic_spanbuf& rhs); // \ref{spanbuf.members}, member functions std::span span() const noexcept; void span(std::span s) noexcept; protected: // \ref{spanbuf.virtuals}, overridden virtual functions basic_streambuf* setbuf(charT*, streamsize) 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; private: ios_base::openmode @\exposid{mode}@; // \expos std::span @\exposid{buf}@; // \expos }; } \end{codeblock} \pnum The class template \tcode{basic_spanbuf} is derived from \tcode{basic_streambuf} to associate possibly the input sequence and possibly the output sequence with a sequence of arbitrary characters. The sequence is provided by an object of class \tcode{span}. \pnum For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \tcode{ios_base::openmode \exposid{mode}}, has \tcode{in} set if the input sequence can be read, and \tcode{out} set if the output sequence can be written. \item \tcode{std::span \exposid{buf}} is the view to the underlying character sequence. \end{itemize} \rSec3[spanbuf.cons]{Constructors} \indexlibraryctor{basic_spanbuf}% \begin{itemdecl} explicit basic_spanbuf(std::span s, ios_base::openmode which = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}, and \exposid{mode} with \tcode{which}. Initializes the internal pointers as if calling \tcode{span(s)}. \end{itemdescr} \indexlibraryctor{basic_spanbuf}% \begin{itemdecl} basic_spanbuf(basic_spanbuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{std::move(rhs)} and \exposid{mode} with \tcode{std::move(rhs.\exposid{mode})} and \exposid{buf} with \tcode{std::move(rhs.\exposid{buf})}. The sequence pointers in \tcode{*this} (\tcode{eback()}, \tcode{gptr()}, \tcode{egptr()}, \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}) obtain the values which \tcode{rhs} had. It is \impldef{whether \tcode{basic_spanbuf}'s move source is empty after a move} whether \tcode{rhs.\exposid{buf}.\brk{}empty()} returns \tcode{true} after the move. \pnum \ensures Let \tcode{rhs_p} refer to the state of \tcode{rhs} just prior to this construction. \begin{itemize} \item \tcode{span().data() == rhs_p.span().data()} \item \tcode{span().size() == rhs_p.span().size()} \item \tcode{eback() == rhs_p.eback()} \item \tcode{gptr() == rhs_p.gptr()} \item \tcode{egptr() == rhs_p.egptr()} \item \tcode{pbase() == rhs_p.pbase()} \item \tcode{pptr() == rhs_p.pptr()} \item \tcode{epptr() == rhs_p.epptr()} \item \tcode{getloc() == rhs_p.getloc()} \end{itemize} \end{itemdescr} \rSec3[spanbuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_spanbuf}% \begin{itemdecl} basic_spanbuf& operator=(basic_spanbuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_spanbuf tmp{std::move(rhs)}; this->swap(tmp); return *this; \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_spanbuf}% \begin{itemdecl} void swap(basic_spanbuf& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_streambuf::swap(rhs); std::swap(@\exposid{mode}@, rhs.@\exposid{mode}@); std::swap(@\exposid{buf}@, rhs.@\exposid{buf}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_spanbuf}% \begin{itemdecl} template void swap(basic_spanbuf& x, basic_spanbuf& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[spanbuf.members]{Member functions} \indexlibrarymember{span}{basic_spanbuf}% \begin{itemdecl} std::span span() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If \tcode{ios_base::out} is set in \exposid{mode}, returns \tcode{std::span(pbase(), pptr())}, otherwise returns \exposid{buf}. \begin{note} In contrast to \tcode{basic_stringbuf}, the underlying sequence never grows and is not owned. An owning copy can be obtained by converting the result to \tcode{basic_string}. \end{note} \end{itemdescr} \indexlibrarymember{span}{basic_spanbuf}% \begin{itemdecl} void span(std::span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects \tcode{\exposid{buf} = s}. Initializes the input and output sequences according to \exposid{mode}. \pnum \ensures \begin{itemize} \item If \tcode{ios_base::out} is set in \exposid{mode}, \tcode{pbase() == s.data() \&\& epptr() == pbase() + s.size()} is \tcode{true}; \begin{itemize} \item in addition, if \tcode{ios_base::ate} is set in \exposid{mode}, \tcode{pptr() == pbase() + s.size()} is \tcode{true}, \item otherwise \tcode{pptr() == pbase()} is \tcode{true}. \end{itemize} \item If \tcode{ios_base::in} is set in \exposid{mode}, \tcode{eback() == s.data() \&\& gptr() == eback() \&\& egptr() == eback() + s.size()} is \tcode{true}. \end{itemize} \end{itemdescr} \rSec3[spanbuf.virtuals]{Overridden virtual functions} \pnum \begin{note} Because the underlying buffer is of fixed size, neither \tcode{overflow}, \tcode{underflow}, nor \tcode{pbackfail} can provide useful behavior. \end{note} \indexlibrarymember{seekoff}{basic_spanbuf}% \begin{itemdecl} pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Alters the stream position within one or both of the controlled sequences, if possible, as follows: \begin{itemize} \item If \tcode{ios_base::in} is set in \tcode{which}, positions the input sequence; \tcode{xnext} is \tcode{gptr()}, \tcode{xbeg} is \tcode{eback()}. \item If \tcode{ios_base::out} is set in \tcode{which}, positions the output sequence; \tcode{xnext} is \tcode{pptr()}, \tcode{xbeg} is \tcode{pbase()}. \end{itemize} \pnum If both \tcode{ios_base::in} and \tcode{ios_base::out} are set in \tcode{which} and \tcode{way} is \tcode{ios_base::cur}, the positioning operation fails. \pnum For a sequence to be positioned, if its next pointer \tcode{xnext} (either \tcode{gptr()} or \tcode{pptr()}) is a null pointer and the new offset \tcode{newoff} as computed below is nonzero, the positioning operation fails. Otherwise, the function determines \tcode{baseoff} as a value of type \tcode{off_type} as follows: \begin{itemize} \item \tcode{0} when \tcode{way} is \tcode{ios_base::beg}; \item \tcode{(pptr() - pbase())} for the output sequence, or \tcode{(gptr() - eback())} for the input sequence when \tcode{way} is \tcode{ios_base::cur}; \item when \tcode{way} is \tcode{ios_base::end} : \begin{itemize} \item \tcode{(pptr() - pbase())} if \tcode{ios_base::out} is set in \exposid{mode} and \tcode{ios_base::in} is not set in \exposid{mode}, \item \tcode{\exposid{buf}.size()} otherwise. \end{itemize} \end{itemize} \pnum If $\tcode{baseoff} + \tcode{off}$ would overflow, or if $\tcode{baseoff} + \tcode{off}$ is less than zero, or if $\tcode{baseoff} + \tcode{off}$ is greater than \tcode{\exposid{buf}.size()}, the positioning operation fails. Otherwise, the function computes \begin{codeblock} off_type newoff = baseoff + off; \end{codeblock} and assigns \tcode{xbeg + newoff} to the next pointer \tcode{xnext}. \pnum \returns \tcode{pos_type(off_type(-1))} if the positioning operation fails; \tcode{pos_type(newoff)} otherwise. \end{itemdescr} \indexlibrarymember{seekpos}{basic_spanbuf}% \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 Equivalent to: \begin{codeblock} return seekoff(off_type(sp), ios_base::beg, which); \end{codeblock} \end{itemdescr} \indexlibrarymember{setbuf}{basic_spanbuf}% \begin{itemdecl} basic_streambuf* setbuf(charT* s, streamsize n) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} this->span(std::span(s, n)); return this; \end{codeblock} \end{itemdescr} \rSec2[ispanstream]{Class template \tcode{basic_ispanstream}} \rSec3[ispanstream.general]{General} \indexlibraryglobal{basic_ispanstream}% \begin{codeblock} namespace std { template> class basic_ispanstream : public basic_istream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{ispanstream.cons}, constructors explicit basic_ispanstream(std::span s, ios_base::openmode which = ios_base::in); basic_ispanstream(const basic_ispanstream&) = delete; basic_ispanstream(basic_ispanstream&& rhs); template explicit basic_ispanstream(ROS&& s); basic_ispanstream& operator=(const basic_ispanstream&) = delete; basic_ispanstream& operator=(basic_ispanstream&& rhs); // \ref{ispanstream.swap}, swap void swap(basic_ispanstream& rhs); // \ref{ispanstream.members}, member functions basic_spanbuf* rdbuf() const noexcept; std::span span() const noexcept; void span(std::span s) noexcept; template void span(ROS&& s) noexcept; private: basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum \begin{note} Constructing an \tcode{ispanstream} from a \grammarterm{string-literal} includes the termination character \tcode{'\textbackslash{}0'} in the underlying \tcode{spanbuf}. \end{note} \rSec3[ispanstream.cons]{Constructors} \indexlibraryctor{basic_ispanstream}% \begin{itemdecl} explicit basic_ispanstream(std::span s, ios_base::openmode which = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))} and \exposid{sb} with \tcode{basic_spanbuf(s, which | ios_base::in)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ispanstream}% \begin{itemdecl} basic_ispanstream(basic_ispanstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{std::move(rhs)} and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. Next, \tcode{basic_istream::set_rdbuf(addressof(\exposid{sb}))} is called to install the contained \tcode{ba\-sic_\-span\-buf}. \end{itemdescr} \indexlibraryctor{basic_ispanstream}% \begin{itemdecl} template explicit basic_ispanstream(ROS&& s) \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{ROS} models \tcode{ranges::\libconcept{borrowed_range}}. \tcode{!\libconcept{convertible_to}> \&\& \libconcept{convertible_to}>} is \tcode{true}. \pnum \effects Let \tcode{sp} be \tcode{std::span(std::forward(s))}. Equivalent to: \begin{codeblock} basic_ispanstream(std::span(const_cast(sp.data()), sp.size())) \end{codeblock} \end{itemdescr} \rSec3[ispanstream.swap]{Swap} \indexlibrarymember{swap}{basic_ispanstream}% \begin{itemdecl} void swap(basic_ispanstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_istream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_ispanstream}% \begin{itemdecl} template void swap(basic_ispanstream& x, basic_ispanstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[ispanstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_ispanstream}% \begin{itemdecl} basic_spanbuf* rdbuf() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} \indexlibrarymember{span}{basic_ispanstream}% \begin{itemdecl} std::span span() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->span();} \end{itemdescr} \indexlibrarymember{span}{basic_ispanstream}% \begin{itemdecl} void span(std::span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{rdbuf()->span(s)}. \end{itemdescr} \begin{itemdecl} template void span(ROS&& s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{ROS} models \tcode{ranges::\libconcept{borrowed_range}}. \tcode{(!\libconcept{convertible_to}>) \&\& \libconcept{convertible_to}>} is \tcode{true}. \pnum \effects Let \tcode{sp} be \tcode{std::span(std::forward(s))}. Equivalent to: \begin{codeblock} this->span(std::span(const_cast(sp.data()), sp.size())); \end{codeblock} \end{itemdescr} \rSec2[ospanstream]{Class template \tcode{basic_ospanstream}} \rSec3[ospanstream.general]{General} \indexlibraryglobal{basic_ospanstream}% \begin{codeblock} namespace std { template> class basic_ospanstream : public basic_ostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{ospanstream.cons}, constructors explicit basic_ospanstream(std::span s, ios_base::openmode which = ios_base::out); basic_ospanstream(const basic_ospanstream&) = delete; basic_ospanstream(basic_ospanstream&& rhs); basic_ospanstream& operator=(const basic_ospanstream&) = delete; basic_ospanstream& operator=(basic_ospanstream&& rhs); // \ref{ospanstream.swap}, swap void swap(basic_ospanstream& rhs); // \ref{ospanstream.members}, member functions basic_spanbuf* rdbuf() const noexcept; std::span span() const noexcept; void span(std::span s) noexcept; private: basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \rSec3[ospanstream.cons]{Constructors} \indexlibraryctor{basic_ospanstream}% \begin{itemdecl} explicit basic_ospanstream(std::span s, ios_base::openmode which = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))} and \exposid{sb} with \tcode{basic_spanbuf(s, which | ios_base::out)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ospanstream}% \begin{itemdecl} basic_ospanstream(basic_ospanstream&& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{std::move(rhs)} and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. Next, \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))} is called to install the contained \tcode{ba\-sic_\-span\-buf}. \end{itemdescr} \rSec3[ospanstream.swap]{Swap} \indexlibrarymember{swap}{basic_ospanstream}% \begin{itemdecl} void swap(basic_ospanstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_ostream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_ospanstream}% \begin{itemdecl} template void swap(basic_ospanstream& x, basic_ospanstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[ospanstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_ospanstream}% \begin{itemdecl} basic_spanbuf* rdbuf() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} \indexlibrarymember{span}{basic_ospanstream}% \begin{itemdecl} std::span span() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->span();} \end{itemdescr} \indexlibrarymember{span}{basic_ospanstream}% \begin{itemdecl} void span(std::span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{rdbuf()->span(s)}. \end{itemdescr} \rSec2[spanstream]{Class template \tcode{basic_spanstream}} \rSec3[spanstream.general]{General} \indexlibraryglobal{basic_spanstream}% \begin{codeblock} namespace std { template> class basic_spanstream : public basic_iostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; // \ref{spanstream.cons}, constructors explicit basic_spanstream(std::span s, ios_base::openmode which = ios_base::out | ios_base::in); basic_spanstream(const basic_spanstream&) = delete; basic_spanstream(basic_spanstream&& rhs); basic_spanstream& operator=(const basic_spanstream&) = delete; basic_spanstream& operator=(basic_spanstream&& rhs); // \ref{spanstream.swap}, swap void swap(basic_spanstream& rhs); // \ref{spanstream.members}, members basic_spanbuf* rdbuf() const noexcept; std::span span() const noexcept; void span(std::span s) noexcept; private: basic_spanbuf @\exposid{sb}@; // \expos }; } \end{codeblock} \rSec3[spanstream.cons]{Constructors} \indexlibraryctor{basic_spanstream}% \begin{itemdecl} explicit basic_spanstream(std::span s, ios_base::openmode which = ios_base::out | ios_bas::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))} and \exposid{sb} with \tcode{basic_spanbuf(s, which)}\iref{spanbuf.cons}. \end{itemdescr} \indexlibraryctor{basic_spanstream}% \begin{itemdecl} basic_spanstream(basic_spanstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{std::move(rhs)} and \exposid{sb} with \tcode{std::move(rhs.\exposid{sb})}. Next, \tcode{basic_iostream::set_rdbuf(addressof(\exposid{sb}))} is called to install the contained \tcode{basic_spanbuf}. \end{itemdescr} \rSec3[spanstream.swap]{Swap} \indexlibrarymember{swap}{basic_spanstream}% \begin{itemdecl} void swap(basic_spanstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_iostream::swap(rhs); @\exposid{sb}@.swap(rhs.@\exposid{sb}@); \end{codeblock} \end{itemdescr} \indexlibrarymember{swap}{basic_spanstream}% \begin{itemdecl} template void swap(basic_spanstream& x, basic_spanstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[spanstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_spanstream}% \begin{itemdecl} basic_spanbuf* rdbuf() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} return const_cast*>(addressof(@\exposid{sb}@)); \end{codeblock} \end{itemdescr} \indexlibrarymember{span}{basic_spanstream}% \begin{itemdecl} std::span span() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->span();} \end{itemdescr} \indexlibrarymember{span}{basic_spanstream}% \begin{itemdecl} void span(std::span s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{rdbuf()->span(s)}. \end{itemdescr} \rSec1[file.streams]{File-based streams} \rSec2[fstream.syn]{Header \tcode{} synopsis} \indexheader{fstream}% \indexlibraryglobal{filebuf}% \indexlibraryglobal{basic_filebuf}% \indexlibraryglobal{wfilebuf}% \indexlibraryglobal{basic_filebuf}% \indexlibraryglobal{ifstream}% \indexlibraryglobal{basic_ifstream}% \indexlibraryglobal{wifstream}% \indexlibraryglobal{basic_ifstream}% \indexlibraryglobal{ofstream}% \indexlibraryglobal{basic_ofstream}% \indexlibraryglobal{wofstream}% \indexlibraryglobal{basic_ofstream}% \indexlibraryglobal{fstream}% \indexlibraryglobal{basic_fstream}% \indexlibraryglobal{wfstream}% \indexlibraryglobal{basic_fstream}% \begin{codeblock} namespace std { // \ref{filebuf}, class template \tcode{basic_filebuf} template> class basic_filebuf; template void swap(basic_filebuf& x, basic_filebuf& y); using filebuf = basic_filebuf; using wfilebuf = basic_filebuf; // \ref{ifstream}, class template \tcode{basic_ifstream} template> class basic_ifstream; template void swap(basic_ifstream& x, basic_ifstream& y); using ifstream = basic_ifstream; using wifstream = basic_ifstream; // \ref{ofstream}, class template \tcode{basic_ofstream} template> class basic_ofstream; template void swap(basic_ofstream& x, basic_ofstream& y); using ofstream = basic_ofstream; using wofstream = basic_ofstream; // \ref{fstream}, class template \tcode{basic_fstream} template> class basic_fstream; template void swap(basic_fstream& x, basic_fstream& y); using fstream = basic_fstream; using wfstream = basic_fstream; } \end{codeblock} \pnum The header \libheader{fstream} defines four class templates and eight types that associate stream buffers with files and assist reading and writing files. \pnum \begin{note} The class template \tcode{basic_filebuf} treats a file as a source or sink of bytes. In an environment that uses a large character set, the file typically holds multibyte character sequences and the \tcode{basic_filebuf} object converts those multibyte sequences into wide character sequences. \end{note} \pnum In subclause~\ref{file.streams}, member functions taking arguments of \tcode{const filesystem::path::value_type*} are only provided on systems where \tcode{filesystem::path::value_type}\iref{fs.class.path} is not \tcode{char}. \begin{note} These functions enable class \tcode{path} support for systems with a wide native path character type, such as \keyword{wchar_t}. \end{note} \rSec2[file.native]{Native handles} \indexlibraryglobal{native_handle_type}% \pnum Several classes described in \ref{file.streams} have a member \tcode{native_handle_type}. \pnum The type \tcode{native_handle_type} represents a platform-specific \defnadj{native}{handle} to a file. It is trivially copyable and models \libconcept{semiregular}. \begin{note} For operating systems based on POSIX, \tcode{native_handle_type} is \keyword{int}. For Windows-based operating systems, \tcode{native_handle_type} is \tcode{HANDLE}. \end{note} \rSec2[filebuf]{Class template \tcode{basic_filebuf}} \rSec3[filebuf.general]{General} \indexlibraryglobal{basic_filebuf}% \begin{codeblock} namespace std { template> class basic_filebuf : public basic_streambuf { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using native_handle_type = @\impdefx{type of \tcode{native_handle_type}}@; // see \ref{file.native} // \ref{filebuf.cons}, constructors/destructor basic_filebuf(); basic_filebuf(const basic_filebuf&) = delete; basic_filebuf(basic_filebuf&& rhs); virtual ~basic_filebuf(); // \ref{filebuf.assign}, assignment and swap basic_filebuf& operator=(const basic_filebuf&) = delete; basic_filebuf& operator=(basic_filebuf&& rhs); void swap(basic_filebuf& rhs); // \ref{filebuf.members}, members bool is_open() const; basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path::value_type* s, ios_base::openmode mode); // wide systems only; see \ref{fstream.syn} basic_filebuf* open(const string& s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path& s, ios_base::openmode mode); basic_filebuf* close(); native_handle_type native_handle() const noexcept; protected: // \ref{filebuf.virtuals}, overridden virtual functions streamsize showmanyc() override; int_type underflow() override; int_type uflow() override; int_type pbackfail(int_type c = traits::eof()) override; int_type overflow (int_type c = traits::eof()) override; basic_streambuf* setbuf(char_type* s, streamsize n) 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; int sync() override; void imbue(const locale& loc) override; }; } \end{codeblock} \pnum The class \tcode{basic_filebuf} associates both the input sequence and the output sequence with a file. \pnum The restrictions on reading and writing a sequence controlled by an object of class \tcode{basic_filebuf} are the same as for reading and writing with the C standard library \tcode{FILE}s. \pnum In particular: \begin{itemize} \item If the file is not open for reading the input sequence cannot be read. \item If the file is not open for writing the output sequence cannot be written. \item A joint file position is maintained for both the input sequence and the output sequence. \end{itemize} \pnum An instance of \tcode{basic_filebuf} behaves as described in~\ref{filebuf} provided \tcode{traits::pos_type} is \tcode{fpos}. Otherwise the behavior is undefined. \pnum The file associated with a \tcode{basic_filebuf} has an associated value of type \tcode{native_handle_type}, called the native handle\iref{file.native} of that file. This native handle can be obtained by calling the member function \tcode{native_handle}. \pnum For any opened \tcode{basic_filebuf f}, the native handle returned by \tcode{f.native_handle()} is invalidated when \tcode{f.close()} is called, or \tcode{f} is destroyed. \pnum In order to support file I/O and multibyte/wide character conversion, conversions are performed using members of a facet, referred to as \tcode{a_codecvt} in following subclauses, obtained as if by \begin{codeblock} const codecvt& a_codecvt = use_facet>(getloc()); \end{codeblock} \rSec3[filebuf.cons]{Constructors} \indexlibraryctor{basic_filebuf}% \begin{itemdecl} basic_filebuf(); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_streambuf()}\iref{streambuf.cons}. \pnum \ensures \tcode{is_open() == false}. \end{itemdescr} \indexlibraryctor{basic_filebuf}% \begin{itemdecl} basic_filebuf(basic_filebuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects It is \impldef{whether sequence pointers are copied by \tcode{basic_filebuf} move constructor} whether the sequence pointers in \tcode{*this} (\tcode{eback()}, \tcode{gptr()}, \tcode{egptr()}, \tcode{pbase()}, \tcode{pptr()}, \tcode{epptr()}) obtain the values which \tcode{rhs} had. Whether they do or not, \tcode{*this} and \tcode{rhs} reference separate buffers (if any at all) after the construction. Additionally \tcode{*this} references the file which \tcode{rhs} did before the construction, and \tcode{rhs} references no file after the construction. The openmode, locale and any other state of \tcode{rhs} is also copied. \pnum \ensures Let \tcode{rhs_p} refer to the state of \tcode{rhs} just prior to this construction and let \tcode{rhs_a} refer to the state of \tcode{rhs} just after this construction. \begin{itemize} \item \tcode{is_open() == rhs_p.is_open()} \item \tcode{rhs_a.is_open() == false} \item \tcode{gptr() - eback() == rhs_p.gptr() - rhs_p.eback()} \item \tcode{egptr() - eback() == rhs_p.egptr() - rhs_p.eback()} \item \tcode{pptr() - pbase() == rhs_p.pptr() - rhs_p.pbase()} \item \tcode{epptr() - pbase() == rhs_p.epptr() - rhs_p.pbase()} \item \tcode{if (eback()) eback() != rhs_a.eback()} \item \tcode{if (gptr()) gptr() != rhs_a.gptr()} \item \tcode{if (egptr()) egptr() != rhs_a.egptr()} \item \tcode{if (pbase()) pbase() != rhs_a.pbase()} \item \tcode{if (pptr()) pptr() != rhs_a.pptr()} \item \tcode{if (epptr()) epptr() != rhs_a.epptr()} \end{itemize} \end{itemdescr} \indexlibrarydtor{basic_filebuf}% \begin{itemdecl} virtual ~basic_filebuf(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{close()}. If an exception occurs during the destruction of the object, including the call to \tcode{close()}, the exception is caught but not rethrown (see~\ref{res.on.exception.handling}). \end{itemdescr} \rSec3[filebuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_filebuf}% \begin{itemdecl} basic_filebuf& operator=(basic_filebuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{close()} then move assigns from \tcode{rhs}. After the move assignment \tcode{*this} has the observable state it would have had if it had been move constructed from \tcode{rhs} (see~\ref{filebuf.cons}). \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{basic_filebuf}% \begin{itemdecl} void swap(basic_filebuf& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs}. \end{itemdescr} \indexlibrarymember{swap}{basic_filebuf}% \begin{itemdecl} template void swap(basic_filebuf& x, basic_filebuf& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[filebuf.members]{Member functions} \indexlibrarymember{is_open}{basic_filebuf}% \begin{itemdecl} bool is_open() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if a previous call to \tcode{open} succeeded (returned a non-null value) and there has been no intervening call to close. \end{itemdescr} \indexlibrarymember{open}{basic_filebuf}% \begin{itemdecl} basic_filebuf* open(const char* s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path::value_type* s, ios_base::openmode mode); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{s} points to a NTCTS\iref{defns.ntcts}. \pnum \effects If \tcode{is_open() != false}, returns a null pointer. Otherwise, initializes the \tcode{filebuf} as required. It then opens the file to which \tcode{s} resolves, if possible, as if by a call to \tcode{fopen} \indexlibraryglobal{fopen}% with the second argument determined from \tcode{mode \& \~{}ios_base::ate} as indicated in \tref{filebuf.open.modes}. If \tcode{mode} is not some combination of flags shown in the table then the open fails. \begin{floattable}{File open modes}{filebuf.open.modes} {ccccccl} \topline \multicolumn{6}{|c}{\tcode{ios_base} flag combination} & \tcode{stdio} equivalent \\ \tcode{binary} & \tcode{in} & \tcode{out} & \tcode{trunc} & \tcode{app} & \tcode{noreplace} \\ \capsep & & + & & & & \tcode{"w"} \\ \rowsep & & + & & & + & \tcode{"wx"} \\ \rowsep & & + & + & & & \tcode{"w"} \\ \rowsep & & + & + & & + & \tcode{"wx"} \\ \rowsep & & + & & + & & \tcode{"a"} \\ \rowsep & & & & + & & \tcode{"a"} \\ \rowsep & + & & & & & \tcode{"r"} \\ \rowsep & + & + & & & & \tcode{"r+"} \\ \rowsep & + & + & + & & & \tcode{"w+"} \\ \rowsep & + & + & + & & + & \tcode{"w+x"} \\ \rowsep & + & + & & + & & \tcode{"a+"} \\ \rowsep & + & & & + & & \tcode{"a+"} \\ \rowsep + & & + & & & & \tcode{"wb"} \\ \rowsep + & & + & & & + & \tcode{"wbx"} \\ \rowsep + & & + & + & & & \tcode{"wb"} \\ \rowsep + & & + & + & & + & \tcode{"wbx"} \\ \rowsep + & & + & & + & & \tcode{"ab"} \\ \rowsep + & & & & + & & \tcode{"ab"} \\ \rowsep + & + & & & & & \tcode{"rb"} \\ \rowsep + & + & + & & & & \tcode{"r+b"} \\ \rowsep + & + & + & + & & & \tcode{"w+b"} \\ \rowsep + & + & + & + & & + & \tcode{"w+bx"} \\ \rowsep + & + & + & & + & & \tcode{"a+b"} \\ \rowsep + & + & & & + & & \tcode{"a+b"} \\ \end{floattable} \pnum If the open operation succeeds and \tcode{ios_base::ate} is set in \tcode{mode}, positions the file to the end (as if by calling \tcode{fseek(file, 0, SEEK_END)}, where \tcode{file} is the pointer returned by calling \tcode{fopen}). \begin{footnote} The macro \tcode{SEEK_END} is defined, and the function signatures \indexlibraryglobal{fopen}% \tcode{fopen(const char*, const char*)} and \tcode{fseek(FILE*, long, int)} \indexlibraryglobal{fseek}% are declared, in \libheaderref{cstdio}. \end{footnote} \pnum If the repositioning operation fails, calls \tcode{close()} and returns a null pointer to indicate failure. \pnum \returns \keyword{this} if successful, a null pointer otherwise. \end{itemdescr} \indexlibrarymember{open}{basic_filebuf}% \begin{itemdecl} basic_filebuf* open(const string& s, ios_base::openmode mode); basic_filebuf* open(const filesystem::path& s, ios_base::openmode mode); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{open(s.c_str(), mode);} \end{itemdescr} \indexlibrarymember{close}{basic_filebuf}% \begin{itemdecl} basic_filebuf* close(); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{is_open() == false}, returns a null pointer. If a put area exists, calls \tcode{overflow(traits::\brk{}eof())} to flush characters. If the last virtual member function called on \tcode{*this} (between \tcode{underflow}, \tcode{overflow}, \tcode{seekoff}, and \tcode{seekpos}) was \tcode{overflow} then calls \tcode{a_codecvt.unshift} (possibly several times) to determine a termination sequence, inserts those characters and calls \tcode{overflow(traits::\brk{}eof())} again. Finally, regardless of whether any of the preceding calls fails or throws an exception, the function closes the file (as if by calling \indexlibraryglobal{fclose}% \tcode{fclose(file)}). If any of the calls made by the function, including \tcode{fclose}, fails, \tcode{close} fails by returning a null pointer. If one of these calls throws an exception, the exception is caught and rethrown after closing the file. \pnum \ensures \tcode{is_open() == false}. \pnum \returns \keyword{this} on success, a null pointer otherwise. \end{itemdescr} \indexlibrarymember{native_handle}{basic_filebuf}% \begin{itemdecl} native_handle_type native_handle() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \expects \tcode{is_open()} is \tcode{true}. \pnum \returns The native handle associated with \tcode{*this}. \end{itemdescr} \rSec3[filebuf.virtuals]{Overridden virtual functions} \indexlibrarymember{showmanyc}{basic_filebuf}% \begin{itemdecl} streamsize showmanyc() override; \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves the same as \tcode{basic_streambuf::showmanyc()}\iref{streambuf.virtuals}. \indexlibrarymember{showmanyc}{basic_streambuf}% \pnum \remarks An implementation may provide an overriding definition for this function signature if it can determine whether more characters can be read from the input sequence. \end{itemdescr} \indexlibrarymember{underflow}{basic_filebuf}% \begin{itemdecl} int_type underflow() override; \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves according to the description of \tcode{basic_streambuf::underflow()}, with the specialization that a sequence of characters is read from the input sequence as if by reading from the associated file into an internal buffer (\tcode{extern_buf}) and then as if by doing: \begin{codeblock} char extern_buf[XSIZE]; char* extern_end; charT intern_buf[ISIZE]; charT* intern_end; codecvt_base::result r = a_codecvt.in(state, extern_buf, extern_buf+XSIZE, extern_end, intern_buf, intern_buf+ISIZE, intern_end); \end{codeblock} This shall be done in such a way that the class can recover the position (\tcode{fpos_t}) corresponding to each character between \tcode{intern_buf} and \tcode{intern_end}. If the value of \tcode{r} indicates that \tcode{a_codecvt.in()} ran out of space in \tcode{intern_buf}, retry with a larger \tcode{intern_buf}. \end{itemdescr} \indexlibrarymember{uflow}{basic_filebuf}% \begin{itemdecl} int_type uflow() override; \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves according to the description of \tcode{basic_streambuf::uflow()}, with the specialization that a sequence of characters is read from the input with the same method as used by \tcode{underflow}. \end{itemdescr} \indexlibrarymember{pbackfail}{basic_filebuf}% \begin{itemdecl} int_type pbackfail(int_type c = traits::eof()) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Puts back the character designated by \tcode{c} to the input sequence, if possible, in one of three ways: \begin{itemize} \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{false} and if the function makes a putback position available and if \tcode{traits::eq(to_char_type(c), gptr()[-1])} returns \tcode{true}, decrements the next pointer for the input sequence, \tcode{gptr()}. Returns: \tcode{c}. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{false} and if the function makes a putback position available and if the function is permitted to assign to the putback position, decrements the next pointer for the input sequence, and stores \tcode{c} there. Returns: \tcode{c}. \item If \tcode{traits::eq_int_type(c, traits::eof())} returns \tcode{true}, and if either the input sequence has a putback position available or the function makes a putback position available, decrements the next pointer for the input sequence, \tcode{gptr()}. Returns: \tcode{traits::not_eof(c)}. \end{itemize} \pnum \returns As specified above, or \tcode{traits::eof()} to indicate failure. \pnum \remarks If \tcode{is_open() == false}, the function always fails. \pnum The function does not put back a character directly to the input sequence. \pnum If the function can succeed in more than one of these ways, it is unspecified which way is chosen. The function can alter the number of putback positions available as a result of any call. \end{itemdescr} \indexlibrarymember{overflow}{basic_filebuf}% \begin{itemdecl} int_type overflow(int_type c = traits::eof()) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves according to the description of \tcode{basic_streambuf::overflow(c)}, except that the behavior of ``consuming characters'' is performed by first converting as if by: \begin{codeblock} charT* b = pbase(); charT* p = pptr(); charT* end; char xbuf[XSIZE]; char* xbuf_end; codecvt_base::result r = a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end); \end{codeblock} and then \begin{itemize} \item If \tcode{r == codecvt_base::error} then fail. \item If \tcode{r == codecvt_base::noconv} then output characters from \tcode{b} up to (and not including) \tcode{p}. \item If \tcode{r == codecvt_base::partial} then output to the file characters from \tcode{xbuf} up to \tcode{xbuf_end}, and repeat using characters from \tcode{end} to \tcode{p}. If output fails, fail (without repeating). \item Otherwise output from \tcode{xbuf} to \tcode{xbuf_end}, and fail if output fails. At this point if \tcode{b != p} and \tcode{b == end} (\tcode{xbuf} isn't large enough) then increase \tcode{XSIZE} and repeat from the beginning. \end{itemize} \pnum \returns \tcode{traits::not_eof(c)} to indicate success, and \tcode{traits::eof()} to indicate failure. If \tcode{is_open() == false}, the function always fails. \end{itemdescr} \indexlibrarymember{setbuf}{basic_filebuf}% \begin{itemdecl} basic_streambuf* setbuf(char_type* s, streamsize n) override; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{setbuf(0, 0)} is called on a stream before any I/O has occurred on that stream, the stream becomes unbuffered. Otherwise the results are \impldef{effect of calling \tcode{basic_filebuf::setbuf} with nonzero arguments}. ``Unbuffered'' means that \tcode{pbase()} and \tcode{pptr()} always return null and output to the file should appear as soon as possible. \end{itemdescr} \indexlibrarymember{seekoff}{basic_filebuf}% \begin{itemdecl} pos_type seekoff(off_type off, ios_base::seekdir way, ios_base::openmode which = ios_base::in | ios_base::out) override; \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{width} denote \tcode{a_codecvt.encoding()}. If \tcode{is_open() == false}, or \tcode{off != 0 \&\& width <= 0}, then the positioning operation fails. Otherwise, if \tcode{way != basic_ios::cur} or \tcode{off != 0}, and if the last operation was output, then update the output sequence and write any unshift sequence. Next, seek to the new position: if \tcode{width > 0}, call \tcode{fseek(file, width * off, whence)}, otherwise call \tcode{fseek(file, 0, whence)}. \pnum \returns A newly constructed \tcode{pos_type} object that stores the resultant stream position, if possible. If the positioning operation fails, or if the object cannot represent the resultant stream position, returns \tcode{pos_type(off_type(-1))}. \pnum \remarks ``The last operation was output'' means either the last virtual operation was overflow or the put buffer is non-empty. ``Write any unshift sequence'' means, if \tcode{width} is less than zero then call \tcode{a_codecvt.unshift(state, xbuf, xbuf+XSIZE, xbuf_end)} and output the resulting unshift sequence. The function determines one of three values for the argument \tcode{whence}, of type \tcode{int}, as indicated in \tref{filebuf.seekoff}. \begin{libtab2}{\tcode{seekoff} effects}{filebuf.seekoff} {ll}{\tcode{way} Value}{\tcode{stdio} Equivalent} \tcode{basic_ios::beg} & \tcode{SEEK_SET} \\ \tcode{basic_ios::cur} & \tcode{SEEK_CUR} \\ \tcode{basic_ios::end} & \tcode{SEEK_END} \\ \end{libtab2} \end{itemdescr} \indexlibrarymember{seekpos}{basic_filebuf}% \begin{itemdecl} pos_type seekpos(pos_type sp, ios_base::openmode which = ios_base::in | ios_base::out) override; \end{itemdecl} \begin{itemdescr} \pnum Alters the file position, if possible, to correspond to the position stored in \tcode{sp} (as described below). Altering the file position performs as follows: \begin{enumerate} \item if \tcode{(om \& ios_base::out) != 0}, then update the output sequence and write any unshift sequence; \item set the file position to \tcode{sp} as if by a call to \tcode{fsetpos}; \item if \tcode{(om \& ios_base::in) != 0}, then update the input sequence; \end{enumerate} where \tcode{om} is the open mode passed to the last call to \tcode{open()}. The operation fails if \tcode{is_open()} returns \tcode{false}. \pnum If \tcode{sp} is an invalid stream position, or if the function positions neither sequence, the positioning operation fails. If \tcode{sp} has not been obtained by a previous successful call to one of the positioning functions (\tcode{seekoff} or \tcode{seekpos}) on the same file the effects are undefined. \pnum \returns \tcode{sp} on success. Otherwise returns \tcode{pos_type(off_type(-1))}. \end{itemdescr} \indexlibrarymember{sync}{basic_filebuf}% \begin{itemdecl} int sync() override; \end{itemdecl} \begin{itemdescr} \pnum \effects If a put area exists, calls \tcode{filebuf::overflow} to write the characters to the file, then flushes the file as if by calling \tcode{fflush(file)}. If a get area exists, the effect is \impldef{effect of calling \tcode{basic_filebuf::sync} when a get area exists}. \end{itemdescr} \indexlibrarymember{imbue}{basic_filebuf}% \begin{itemdecl} void imbue(const locale& loc) override; \end{itemdecl} \begin{itemdescr} \pnum \expects If the file is not positioned at its beginning and the encoding of the current locale as determined by \tcode{a_codecvt.encoding()} is state-dependent\iref{locale.codecvt.virtuals} then that facet is the same as the corresponding facet of \tcode{loc}. \pnum \effects Causes characters inserted or extracted after this call to be converted according to \tcode{loc} until another call of \tcode{imbue}. \pnum \remarks This may require reconversion of previously converted characters. This in turn may require the implementation to be able to reconstruct the original contents of the file. \end{itemdescr} \rSec2[ifstream]{Class template \tcode{basic_ifstream}} \rSec3[ifstream.general]{General} \indexlibraryglobal{basic_ifstream}% \begin{codeblock} namespace std { template> class basic_ifstream : public basic_istream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using native_handle_type = typename basic_filebuf::native_handle_type; // \ref{ifstream.cons}, constructors basic_ifstream(); explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in);// wide systems only; see \ref{fstream.syn} explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); template explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); basic_ifstream(const basic_ifstream&) = delete; basic_ifstream(basic_ifstream&& rhs); basic_ifstream& operator=(const basic_ifstream&) = delete; basic_ifstream& operator=(basic_ifstream&& rhs); // \ref{ifstream.swap}, swap void swap(basic_ifstream& rhs); // \ref{ifstream.members}, members basic_filebuf* rdbuf() const; native_handle_type native_handle() const noexcept; bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} void open(const string& s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); void close(); private: basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class \tcode{basic_ifstream} supports reading from named files. It uses a \tcode{basic_filebuf<\brk{}charT, traits>} object to control the associated sequence. For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \exposid{sb}, the \tcode{filebuf} object. \end{itemize} \rSec3[ifstream.cons]{Constructors} \indexlibraryctor{basic_ifstream}% \begin{itemdecl} basic_ifstream(); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream.cons} and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ifstream}% \begin{itemdecl} explicit basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in); explicit basic_ifstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_istream(addressof(\exposid{sb}))}\iref{istream.cons} and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::in)}. If that function returns a null pointer, calls \tcode{setstate(failbit)}. \end{itemdescr} \indexlibraryctor{basic_ifstream}% \begin{itemdecl} explicit basic_ifstream(const string& s, ios_base::openmode mode = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{basic_ifstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_ifstream}% \begin{itemdecl} template explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{true}. \pnum \effects Equivalent to \tcode{basic_ifstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_ifstream}% \begin{itemdecl} basic_ifstream(basic_ifstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} \rSec3[ifstream.swap]{Swap} \indexlibrarymember{swap}{basic_ifstream}% \begin{itemdecl} void swap(basic_ifstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_istream::swap(rhs)} and \tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_ifstream}% \begin{itemdecl} template void swap(basic_ifstream& x, basic_ifstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[ifstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_ifstream}% \begin{itemdecl} basic_filebuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(@\exposid{sb}@))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ifstream}% \begin{itemdecl} native_handle_type native_handle() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->native_handle();} \end{itemdescr} \indexlibrarymember{is_open}{basic_ifstream}% \begin{itemdecl} bool is_open() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{rdbuf()->is_open()}. \end{itemdescr} \indexlibrarymember{open}{basic_ifstream}% \begin{itemdecl} void open(const char* s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->open(s, mode | ios_base::in)}. If that function does not return a null pointer calls \tcode{clear()}, otherwise calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \indexlibrarymember{open}{basic_ifstream}% \begin{itemdecl} void open(const string& s, ios_base::openmode mode = ios_base::in); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::in); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{open(s.c_str(), mode)}. \end{itemdescr} \indexlibrarymember{close}{basic_ifstream}% \begin{itemdecl} void close(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->close()} and, if that function returns a null pointer, calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \rSec2[ofstream]{Class template \tcode{basic_ofstream}} \rSec3[ofstream.general]{General} \indexlibraryglobal{basic_ofstream}% \begin{codeblock} namespace std { template> class basic_ofstream : public basic_ostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using native_handle_type = typename basic_filebuf::native_handle_type; // \ref{ofstream.cons}, constructors basic_ofstream(); explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const filesystem::path::value_type* s, // wide systems only; see \ref{fstream.syn} ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); template explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); basic_ofstream(const basic_ofstream&) = delete; basic_ofstream(basic_ofstream&& rhs); basic_ofstream& operator=(const basic_ofstream&) = delete; basic_ofstream& operator=(basic_ofstream&& rhs); // \ref{ofstream.swap}, swap void swap(basic_ofstream& rhs); // \ref{ofstream.members}, members basic_filebuf* rdbuf() const; native_handle_type native_handle() const noexcept; bool is_open() const; void open(const char* s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} void open(const string& s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out); void close(); private: basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class \tcode{basic_ofstream} supports writing to named files. It uses a \tcode{basic_filebuf<\brk{}charT, traits>} object to control the associated sequence. For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \exposid{sb}, the \tcode{filebuf} object. \end{itemize} \rSec3[ofstream.cons]{Constructors} \indexlibraryctor{basic_ofstream}% \begin{itemdecl} basic_ofstream(); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream.cons} and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}. \end{itemdescr} \indexlibraryctor{basic_ofstream}% \begin{itemdecl} explicit basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out); explicit basic_ofstream(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}\iref{ostream.cons} and \exposid{sb} with \tcode{basic_filebuf()}\iref{filebuf.cons}, then calls \tcode{rdbuf()->open(s, mode | ios_base::out)}. If that function returns a null pointer, calls \tcode{setstate(\brk{}fail\-bit)}. \end{itemdescr} \indexlibraryctor{basic_ofstream}% \begin{itemdecl} explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{basic_ofstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_ofstream}% \begin{itemdecl} template explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{true}. \pnum \effects Equivalent to \tcode{basic_ofstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_ofstream}% \begin{itemdecl} basic_ofstream(basic_ofstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. Then calls \tcode{basic_ostream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} \rSec3[ofstream.swap]{Swap} \indexlibrarymember{swap}{basic_ofstream}% \begin{itemdecl} void swap(basic_ofstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_ostream::swap(rhs)} and \tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_ofstream}% \begin{itemdecl} template void swap(basic_ofstream& x, basic_ofstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[ofstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_ofstream}% \begin{itemdecl} basic_filebuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_ofstream}% \begin{itemdecl} native_handle_type native_handle() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->native_handle();} \end{itemdescr} \indexlibrarymember{is_open}{basic_ofstream}% \begin{itemdecl} bool is_open() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{rdbuf()->is_open()}. \end{itemdescr} \indexlibrarymember{open}{basic_ofstream}% \begin{itemdecl} void open(const char* s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->open(s, mode | ios_base::out)}. If that function does not return a null pointer calls \tcode{clear()}, otherwise calls \tcode{setstate(\brk{}failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \indexlibrarymember{close}{basic_ofstream}% \begin{itemdecl} void close(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->close()} and, if that function fails (returns a null pointer), calls \tcode{setstate(\brk{}failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \indexlibrarymember{open}{basic_ofstream}% \begin{itemdecl} void open(const string& s, ios_base::openmode mode = ios_base::out); void open(const filesystem::path& s, ios_base::openmode mode = ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{open(s.c_str(), mode)}. \end{itemdescr} \rSec2[fstream]{Class template \tcode{basic_fstream}} \rSec3[fstream.general]{General} \indexlibraryglobal{basic_fstream}% \begin{codeblock} namespace std { template> class basic_fstream : public basic_iostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using native_handle_type = typename basic_filebuf::native_handle_type; // \ref{fstream.cons}, constructors basic_fstream(); explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} explicit basic_fstream( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); template explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); basic_fstream(const basic_fstream&) = delete; basic_fstream(basic_fstream&& rhs); basic_fstream& operator=(const basic_fstream&) = delete; basic_fstream& operator=(basic_fstream&& rhs); // \ref{fstream.swap}, swap void swap(basic_fstream& rhs); // \ref{fstream.members}, members basic_filebuf* rdbuf() const; native_handle_type native_handle() const noexcept; bool is_open() const; void open( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in|ios_base::out); // wide systems only; see \ref{fstream.syn} void open( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path& s, ios_base::openmode mode = ios_base::in | ios_base::out); void close(); private: basic_filebuf @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum The class template \tcode{basic_fstream} supports reading and writing from named files. It uses a \tcode{basic_filebuf} object to control the associated sequences. For the sake of exposition, the maintained data is presented here as: \begin{itemize} \item \exposid{sb}, the \tcode{basic_filebuf} object. \end{itemize} \rSec3[fstream.cons]{Constructors} \indexlibraryctor{basic_fstream}% \begin{itemdecl} basic_fstream(); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_filebuf()}. \end{itemdescr} \indexlibraryctor{basic_fstream}% \begin{itemdecl} explicit basic_fstream( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); explicit basic_fstream( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes the base class with \tcode{basic_iostream(addressof(\exposid{sb}))}\iref{iostream.cons} and \exposid{sb} with \tcode{basic_filebuf()}. Then calls \tcode{rdbuf()->open(s, mode)}. If that function returns a null pointer, calls \tcode{setstate(failbit)}. \end{itemdescr} \indexlibraryctor{basic_fstream}% \begin{itemdecl} explicit basic_fstream( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{basic_fstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_fstream}% \begin{itemdecl} template explicit basic_fstream(const T& s, ios_base::openmode mode = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \constraints \tcode{is_same_v} is \tcode{true}. \pnum \effects Equivalent to \tcode{basic_fstream(s.c_str(), mode)}. \end{itemdescr} \indexlibraryctor{basic_fstream}% \begin{itemdecl} basic_fstream(basic_fstream&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs the base class, and the contained \tcode{basic_filebuf}. Then calls \tcode{basic_istream::set_rdbuf(\brk{}addressof(\exposid{sb}))} to install the contained \tcode{basic_filebuf}. \end{itemdescr} \rSec3[fstream.swap]{Swap} \indexlibrarymember{swap}{basic_fstream}% \begin{itemdecl} void swap(basic_fstream& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Exchanges the state of \tcode{*this} and \tcode{rhs} by calling \tcode{basic_iostream::swap(rhs)} and \tcode{\exposid{sb}.swap(rhs.\exposid{sb})}. \end{itemdescr} \indexlibrarymember{swap}{basic_fstream}% \begin{itemdecl} template void swap(basic_fstream& x, basic_fstream& y); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{x.swap(y)}. \end{itemdescr} \rSec3[fstream.members]{Member functions} \indexlibrarymember{rdbuf}{basic_fstream}% \begin{itemdecl} basic_filebuf* rdbuf() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{const_cast*>(addressof(\exposid{sb}))}. \end{itemdescr} \indexlibrarymember{native_handle}{basic_fstream}% \begin{itemdecl} native_handle_type native_handle() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return rdbuf()->native_handle();} \end{itemdescr} \indexlibrarymember{is_open}{basic_fstream}% \begin{itemdecl} bool is_open() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{rdbuf()->is_open()}. \end{itemdescr} \indexlibrarymember{open}{basic_fstream}% \begin{itemdecl} void open( const char* s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path::value_type* s, ios_base::openmode mode = ios_base::in | ios_base::out); // wide systems only; see \ref{fstream.syn} \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->open(s, mode)}. If that function does not return a null pointer calls \tcode{clear()}, otherwise calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \indexlibrarymember{open}{basic_fstream}% \begin{itemdecl} void open( const string& s, ios_base::openmode mode = ios_base::in | ios_base::out); void open( const filesystem::path& s, ios_base::openmode mode = ios_base::in | ios_base::out); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{open(s.c_str(), mode)}. \end{itemdescr} \indexlibrarymember{close}{basic_fstream}% \begin{itemdecl} void close(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{rdbuf()->close()} and, if that function returns a null pointer, calls \tcode{setstate(failbit)} (which may throw \tcode{ios_base::failure})\iref{iostate.flags}. \end{itemdescr} \rSec1[syncstream]{Synchronized output streams} \rSec2[syncstream.syn]{Header \tcode{} synopsis} \indexheader{syncstream}% \indexlibraryglobal{syncbuf}% \indexlibraryglobal{wsyncbuf}% \indexlibraryglobal{osyncstream}% \indexlibraryglobal{wosyncstream}% \begin{codeblock} #include // see \ref{ostream.syn} namespace std { // \ref{syncstream.syncbuf}, class template \tcode{basic_syncbuf} template, class Allocator = allocator> class basic_syncbuf; // \ref{syncstream.syncbuf.special}, specialized algorithms template void swap(basic_syncbuf&, basic_syncbuf&); using syncbuf = basic_syncbuf; using wsyncbuf = basic_syncbuf; // \ref{syncstream.osyncstream}, class template \tcode{basic_osyncstream} template, class Allocator = allocator> class basic_osyncstream; using osyncstream = basic_osyncstream; using wosyncstream = basic_osyncstream; } \end{codeblock} \pnum The header \libheader{syncstream} provides a mechanism to synchronize execution agents writing to the same stream. \rSec2[syncstream.syncbuf]{Class template \tcode{basic_syncbuf}} \rSec3[syncstream.syncbuf.overview]{Overview} \indexlibraryglobal{basic_syncbuf}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_syncbuf : public basic_streambuf { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; using streambuf_type = basic_streambuf; // \ref{syncstream.syncbuf.cons}, construction and destruction basic_syncbuf() : basic_syncbuf(nullptr) {} explicit basic_syncbuf(streambuf_type* obuf) : basic_syncbuf(obuf, Allocator()) {} basic_syncbuf(streambuf_type*, const Allocator&); basic_syncbuf(basic_syncbuf&&); ~basic_syncbuf(); // \ref{syncstream.syncbuf.assign}, assignment and swap basic_syncbuf& operator=(basic_syncbuf&&); void swap(basic_syncbuf&); // \ref{syncstream.syncbuf.members}, member functions bool emit(); streambuf_type* get_wrapped() const noexcept; allocator_type get_allocator() const noexcept; void set_emit_on_sync(bool) noexcept; protected: // \ref{syncstream.syncbuf.virtuals}, overridden virtual functions int sync() override; private: streambuf_type* @\exposid{wrapped}@; // \expos bool @\exposid{emit-on-sync}@{}; // \expos }; } \end{codeblock} \pnum Class template \tcode{basic_syncbuf} stores character data written to it, known as the associated output, into internal buffers allocated using the object's allocator. The associated output is transferred to the wrapped stream buffer object \tcode{*\exposid{wrapped}} when \tcode{emit()} is called or when the \tcode{basic_syncbuf} object is destroyed. Such transfers are atomic with respect to transfers by other \tcode{basic_syncbuf} objects with the same wrapped stream buffer object. \rSec3[syncstream.syncbuf.cons]{Construction and destruction} \indexlibraryctor{basic_syncbuf}% \begin{itemdecl} basic_syncbuf(streambuf_type* obuf, const Allocator& allocator); \end{itemdecl} \begin{itemdescr} \pnum \effects Sets \exposid{wrapped} to \tcode{obuf}. \pnum \ensures \tcode{get_wrapped() == obuf} and \tcode{get_allocator() == allocator} are \tcode{true}. \pnum \throws Nothing unless an exception is thrown by the construction of a mutex or by memory allocation. \pnum \remarks A copy of \tcode{allocator} is used to allocate memory for internal buffers holding the associated output. \end{itemdescr} \indexlibraryctor{basic_syncbuf}% \begin{itemdecl} basic_syncbuf(basic_syncbuf&& other); \end{itemdecl} \begin{itemdescr} \pnum \ensures The value returned by \tcode{this->get_wrapped()} is the value returned by \tcode{other.get_wrapped()} prior to calling this constructor. Output stored in \tcode{other} prior to calling this constructor will be stored in \tcode{*this} afterwards. \tcode{other.pbase() == other.pptr()} and \tcode{other.get_wrapped() == nullptr} are \tcode{true}. \pnum \remarks This constructor disassociates \tcode{other} from its wrapped stream buffer, ensuring destruction of \tcode{other} produces no output. \end{itemdescr} \indexlibrarydtor{basic_syncbuf}% \begin{itemdecl} ~basic_syncbuf(); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{emit()}. \pnum \throws Nothing. If an exception is thrown from \tcode{emit()}, the destructor catches and ignores that exception. \end{itemdescr} \rSec3[syncstream.syncbuf.assign]{Assignment and swap} \indexlibrarymember{operator=}{basic_syncbuf}% \begin{itemdecl} basic_syncbuf& operator=(basic_syncbuf&& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{emit()} then move assigns from \tcode{rhs}. After the move assignment \tcode{*this} has the observable state it would have had if it had been move constructed from \tcode{rhs}\iref{syncstream.syncbuf.cons}. \pnum \ensures \begin{itemize} \item \tcode{rhs.get_wrapped() == nullptr} is \tcode{true}. \item \tcode{this->get_allocator() == rhs.get_allocator()} is \tcode{true} when \begin{codeblock} allocator_traits::propagate_on_container_move_assignment::value \end{codeblock} is \tcode{true}; otherwise, the allocator is unchanged. \end{itemize} \pnum \returns \tcode{*this}. \pnum \remarks This assignment operator disassociates \tcode{rhs} from its wrapped stream buffer, ensuring destruction of \tcode{rhs} produces no output. \end{itemdescr} \indexlibrarymember{swap}{basic_syncbuf}% \begin{itemdecl} void swap(basic_syncbuf& other); \end{itemdecl} \begin{itemdescr} \pnum \expects Either \tcode{allocator_traits::propagate_on_container_swap::value} is \tcode{true} or \tcode{this->get_allocator() == other.get_allocator()} is \tcode{true}. \pnum \effects Exchanges the state of \tcode{*this} and \tcode{other}. \end{itemdescr} \rSec3[syncstream.syncbuf.members]{Member functions} \indexlibrarymember{emit}{basic_syncbuf}% \begin{itemdecl} bool emit(); \end{itemdecl} \begin{itemdescr} \pnum \effects Atomically transfers the associated output of \tcode{*this} to the stream buffer \tcode{*\exposid{wrapped}}, so that it appears in the output stream as a contiguous sequence of characters. \tcode{\exposid{wrapped}->pubsync()} is called if and only if a call was made to \tcode{sync()} since the most recent call to \tcode{emit()}, if any. \pnum \sync All \tcode{emit()} calls transferring characters to the same stream buffer object appear to execute in a total order consistent with the ``happens before'' relation\iref{intro.races}, where each \tcode{emit()} call synchronizes with subsequent \tcode{emit()} calls in that total order. \pnum \ensures On success, the associated output is empty. \pnum \returns \tcode{true} if all of the following conditions hold; otherwise \tcode{false}: \begin{itemize} \item \tcode{\exposid{wrapped} == nullptr} is \tcode{false}. \item All of the characters in the associated output were successfully transferred. \item The call to \tcode{\exposid{wrapped}->pubsync()} (if any) succeeded. \end{itemize} \pnum \remarks May call member functions of \exposid{wrapped} while holding a lock uniquely associated with \exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_wrapped}{basic_syncbuf}% \begin{itemdecl} streambuf_type* get_wrapped() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{wrapped}. \end{itemdescr} \indexlibrarymember{get_allocator}{basic_syncbuf}% \begin{itemdecl} allocator_type get_allocator() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A copy of the allocator that was set in the constructor or assignment operator. \end{itemdescr} \indexlibrarymember{set_emit_on_sync}{basic_syncbuf}% \begin{itemdecl} void set_emit_on_sync(bool b) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects \tcode{\exposid{emit-on-sync} = b}. \end{itemdescr} \rSec3[syncstream.syncbuf.virtuals]{Overridden virtual functions} \indexlibrarymember{sync}{basic_syncbuf}% \begin{itemdecl} int sync() override; \end{itemdecl} \begin{itemdescr} \pnum \effects Records that the wrapped stream buffer is to be flushed. Then, if \exposid{emit-on-sync} is \tcode{true}, calls \tcode{emit()}. \begin{note} If \exposid{emit-on-sync} is \tcode{false}, the actual flush is delayed until a call to \tcode{emit()}. \end{note} \pnum \returns If \tcode{emit()} was called and returned \tcode{false}, returns \tcode{-1}; otherwise \tcode{0}. \end{itemdescr} \rSec3[syncstream.syncbuf.special]{Specialized algorithms} \indexlibrarymember{swap}{basic_syncbuf}% \begin{itemdecl} template void swap(basic_syncbuf& a, basic_syncbuf& b); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{a.swap(b)}. \end{itemdescr} \rSec2[syncstream.osyncstream]{Class template \tcode{basic_osyncstream}} \rSec3[syncstream.osyncstream.overview]{Overview} \indexlibraryglobal{basic_osyncstream}% \begin{codeblock} namespace std { template, class Allocator = allocator> class basic_osyncstream : public basic_ostream { public: using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; using streambuf_type = basic_streambuf; using syncbuf_type = basic_syncbuf; // \ref{syncstream.osyncstream.cons}, construction and destruction basic_osyncstream(streambuf_type*, const Allocator&); explicit basic_osyncstream(streambuf_type* obuf) : basic_osyncstream(obuf, Allocator()) {} basic_osyncstream(basic_ostream& os, const Allocator& allocator) : basic_osyncstream(os.rdbuf(), allocator) {} explicit basic_osyncstream(basic_ostream& os) : basic_osyncstream(os, Allocator()) {} basic_osyncstream(basic_osyncstream&&) noexcept; ~basic_osyncstream(); // assignment basic_osyncstream& operator=(basic_osyncstream&&); // \ref{syncstream.osyncstream.members}, member functions void emit(); streambuf_type* get_wrapped() const noexcept; syncbuf_type* rdbuf() const noexcept { return const_cast(addressof(@\exposid{sb}@)); } private: syncbuf_type @\exposid{sb}@; // \expos }; } \end{codeblock} \pnum \tcode{Allocator} shall meet the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \begin{example} A named variable can be used within a block statement for streaming. \begin{codeblock} { osyncstream bout(cout); bout << "Hello, "; bout << "World!"; bout << endl; // flush is noted bout << "and more!\n"; } // characters are transferred and \tcode{cout} is flushed \end{codeblock} \end{example} \pnum \begin{example} A temporary object can be used for streaming within a single statement. \begin{codeblock} osyncstream(cout) << "Hello, " << "World!" << '\n'; \end{codeblock} In this example, \tcode{cout} is not flushed. \end{example} \rSec3[syncstream.osyncstream.cons]{Construction and destruction} \indexlibraryctor{basic_osyncstream}% \begin{itemdecl} basic_osyncstream(streambuf_type* buf, const Allocator& allocator); \end{itemdecl} \begin{itemdescr} \pnum \effects Initializes \exposid{sb} from \tcode{buf} and \tcode{allocator}. Initializes the base class with \tcode{basic_ostream(addressof(\exposid{sb}))}. \pnum \begin{note} The member functions of the provided stream buffer can be called from \tcode{emit()} while a lock is held, which might result in a deadlock if used incautiously. \end{note} \pnum \ensures \tcode{get_wrapped() == buf} is \tcode{true}. \end{itemdescr} \indexlibraryctor{basic_osyncstream}% \begin{itemdecl} basic_osyncstream(basic_osyncstream&& other) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Move constructs the base class and \exposid{sb} from the corresponding subobjects of \tcode{other}, and calls \tcode{basic_ostream::set_rdbuf(addressof(\exposid{sb}))}. \pnum \ensures The value returned by \tcode{get_wrapped()} is the value returned by \tcode{other.get_wrapped()} prior to calling this constructor. \tcode{nullptr == other.get_wrapped()} is \tcode{true}. \end{itemdescr} \rSec3[syncstream.osyncstream.members]{Member functions} \indexlibrarymember{set_emit_on_sync}{basic_osyncstream}% \begin{itemdecl} void emit(); \end{itemdecl} \begin{itemdescr} \pnum \effects Behaves as an unformatted output function\iref{ostream.unformatted}. After constructing a \tcode{sentry} object, calls \tcode{\exposid{sb}.emit()}. If that call returns \tcode{false}, calls \tcode{setstate(ios_base::badbit)}. \pnum \begin{example} A flush on a \tcode{basic_osyncstream} does not flush immediately: \begin{codeblock} { osyncstream bout(cout); bout << "Hello," << '\n'; // no flush bout.emit(); // characters transferred; \tcode{cout} not flushed bout << "World!" << endl; // flush noted; \tcode{cout} not flushed bout.emit(); // characters transferred; \tcode{cout} flushed bout << "Greetings." << '\n'; // no flush } // characters transferred; \tcode{cout} not flushed \end{codeblock} \end{example} \pnum \begin{example} The function \tcode{emit()} can be used to handle exceptions from operations on the underlying stream. \begin{codeblock} { osyncstream bout(cout); bout << "Hello, " << "World!" << '\n'; try { bout.emit(); } catch (...) { // handle exception } } \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{set_emit_on_sync}{basic_osyncstream}% \begin{itemdecl} streambuf_type* get_wrapped() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{sb}.get_wrapped()}. \pnum \begin{example} Obtaining the wrapped stream buffer with \tcode{get_wrapped()} allows wrapping it again with an \tcode{osyncstream}. For example, \begin{codeblock} { osyncstream bout1(cout); bout1 << "Hello, "; { osyncstream(bout1.get_wrapped()) << "Goodbye, " << "Planet!" << '\n'; } bout1 << "World!" << '\n'; } \end{codeblock} produces the \textit{uninterleaved} output \begin{outputblock} Goodbye, Planet! Hello, World! \end{outputblock} \end{example} \end{itemdescr} \rSec1[filesystems]{File systems} \rSec2[fs.general]{General} \pnum Subclause~\ref{filesystems} describes operations on file systems and their components, such as paths, regular files, and directories. \pnum A \defn{file system} is a collection of files and their attributes. \pnum A \defn{file} is an object within a file system that holds user or system data. Files can be written to, or read from, or both. A file has certain attributes, including type. File types include regular files and directories. Other types of files, such as symbolic links, may be supported by the implementation. \pnum A \defn{directory} is a file within a file system that acts as a container of directory entries that contain information about other files, possibly including other directory files. The \defn{parent directory} of a directory is the directory that both contains a directory entry for the given directory and is represented by the dot-dot filename\iref{fs.path.generic} in the given directory. The \defn{parent directory} of other types of files is a directory containing a directory entry for the file under discussion. \pnum A \defn{link} is an object that associates a filename with a file. Several links can associate names with the same file. A \defn{hard link} is a link to an existing file. Some file systems support multiple hard links to a file. If the last hard link to a file is removed, the file itself is removed. \begin{note} A hard link can be thought of as a shared-ownership smart pointer to a file. \end{note} A \defn{symbolic link} is a type of file with the property that when the file is encountered during pathname resolution\iref{fs.class.path}, a string stored by the file is used to modify the pathname resolution. \begin{note} Symbolic links are often called symlinks. A symbolic link can be thought of as a raw pointer to a file. If the file pointed to does not exist, the symbolic link is said to be a ``dangling'' symbolic link. \end{note} \rSec2[fs.conformance]{Conformance} \rSec3[fs.conformance.general]{General} \pnum Conformance is specified in terms of behavior. Ideal behavior is not always implementable, so the conformance subclauses take that into account. \rSec3[fs.conform.9945]{POSIX conformance} \pnum Some behavior is specified by reference to POSIX\@. How such behavior is actually implemented is unspecified. \begin{note} This constitutes an ``as if'' rule allowing implementations to call native operating system or other APIs. \end{note} \pnum Implementations should provide such behavior as it is defined by POSIX\@. Implementations shall document any behavior that differs from the behavior defined by POSIX\@. Implementations that do not support exact POSIX behavior should provide behavior as close to POSIX behavior as is reasonable given the limitations of actual operating systems and file systems. If an implementation cannot provide any reasonable behavior, the implementation shall report an error as specified in~\ref{fs.err.report}. \begin{note} This allows users to rely on an exception being thrown or an error code being set when an implementation cannot provide any reasonable behavior. \end{note} \pnum Implementations are not required to provide behavior that is not supported by a particular file system. \begin{example} The FAT file system used by some memory cards, camera memory, and floppy disks does not support hard links, symlinks, and many other features of more capable file systems, so implementations are not required to support those features on the FAT file system but instead are required to report an error as described above. \end{example} \rSec3[fs.conform.os]{Operating system dependent behavior conformance} \pnum Behavior that is specified as being \defn{operating system dependent} is dependent upon the behavior and characteristics of an operating system. The operating system an implementation is dependent upon is \impldef{operating system on which implementation depends}. \pnum It is permissible for an implementation to be dependent upon an operating system emulator rather than the actual underlying operating system. \rSec3[fs.race.behavior]{File system race behavior} \pnum A \defn{file system race} is the condition that occurs when multiple threads, processes, or computers interleave access and modification of the same object within a file system. Behavior is undefined if calls to functions provided by subclause~\ref{filesystems} introduce a file system race. \pnum If the possibility of a file system race would make it unreliable for a program to test for a precondition before calling a function described herein, % {} on next line suppresses a check failure for a missing newline after \expects. {}\expects is not specified for the function. \begin{note} As a design practice, preconditions are not specified when it is unreasonable for a program to detect them prior to calling the function. \end{note} \rSec2[fs.req]{Requirements} \pnum Throughout subclause~\ref{filesystems}, \tcode{char}, \keyword{wchar_t}, \keyword{char8_t}, \keyword{char16_t}, and \keyword{char32_t} are collectively called \defnx{encoded character types}{encoded character type}. \pnum Functions with template parameters named \tcode{EcharT} shall not participate in overload resolution unless \tcode{EcharT} is one of the encoded character types. \pnum Template parameters named \tcode{InputIterator} shall meet the \oldconcept{InputIterator} requirements\iref{input.iterators} and shall have a value type that is one of the encoded character types. \pnum \begin{note} Use of an encoded character type implies an associated character set and encoding. Since \tcode{signed char} and \tcode{unsigned char} have no implied character set and encoding, they are not included as permitted types. \end{note} \pnum Template parameters named \tcode{Allocator} shall meet the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \rSec2[fs.filesystem.syn]{Header \tcode{} synopsis} \indexheader{filesystem}% \begin{codeblock} #include // see \ref{compare.syn} namespace std::filesystem { // \ref{fs.class.path}, paths class path; // \ref{fs.path.nonmember}, \tcode{path} non-member functions void swap(path& lhs, path& rhs) noexcept; size_t hash_value(const path& p) noexcept; // \ref{fs.class.filesystem.error}, filesystem errors class filesystem_error; // \ref{fs.class.directory.entry}, directory entries class directory_entry; // \ref{fs.class.directory.iterator}, directory iterators class directory_iterator; // \ref{fs.dir.itr.nonmembers}, range access for directory iterators directory_iterator begin(directory_iterator iter) noexcept; directory_iterator end(directory_iterator) noexcept; // \ref{fs.class.rec.dir.itr}, recursive directory iterators class recursive_directory_iterator; // \ref{fs.rec.dir.itr.nonmembers}, range access for recursive directory iterators recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; recursive_directory_iterator end(recursive_directory_iterator) noexcept; // \ref{fs.class.file.status}, file status class file_status; struct space_info { uintmax_t capacity; uintmax_t free; uintmax_t available; friend bool operator==(const space_info&, const space_info&) = default; }; // \ref{fs.enum}, enumerations enum class file_type; enum class perms; enum class perm_options; enum class copy_options; enum class directory_options; using file_time_type = chrono::time_point; // \ref{fs.op.funcs}, filesystem operations path absolute(const path& p); path absolute(const path& p, error_code& ec); path canonical(const path& p); path canonical(const path& p, error_code& ec); void copy(const path& from, const path& to); void copy(const path& from, const path& to, error_code& ec); void copy(const path& from, const path& to, copy_options options); void copy(const path& from, const path& to, copy_options options, error_code& ec); bool copy_file(const path& from, const path& to); bool copy_file(const path& from, const path& to, error_code& ec); bool copy_file(const path& from, const path& to, copy_options option); bool copy_file(const path& from, const path& to, copy_options option, error_code& ec); void copy_symlink(const path& existing_symlink, const path& new_symlink); void copy_symlink(const path& existing_symlink, const path& new_symlink, error_code& ec) noexcept; bool create_directories(const path& p); bool create_directories(const path& p, error_code& ec); bool create_directory(const path& p); bool create_directory(const path& p, error_code& ec) noexcept; bool create_directory(const path& p, const path& attributes); bool create_directory(const path& p, const path& attributes, error_code& ec) noexcept; void create_directory_symlink(const path& to, const path& new_symlink); void create_directory_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept; void create_hard_link(const path& to, const path& new_hard_link); void create_hard_link(const path& to, const path& new_hard_link, error_code& ec) noexcept; void create_symlink(const path& to, const path& new_symlink); void create_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept; path current_path(); path current_path(error_code& ec); void current_path(const path& p); void current_path(const path& p, error_code& ec) noexcept; bool equivalent(const path& p1, const path& p2); bool equivalent(const path& p1, const path& p2, error_code& ec) noexcept; bool exists(file_status s) noexcept; bool exists(const path& p); bool exists(const path& p, error_code& ec) noexcept; uintmax_t file_size(const path& p); uintmax_t file_size(const path& p, error_code& ec) noexcept; uintmax_t hard_link_count(const path& p); uintmax_t hard_link_count(const path& p, error_code& ec) noexcept; bool is_block_file(file_status s) noexcept; bool is_block_file(const path& p); bool is_block_file(const path& p, error_code& ec) noexcept; bool is_character_file(file_status s) noexcept; bool is_character_file(const path& p); bool is_character_file(const path& p, error_code& ec) noexcept; bool is_directory(file_status s) noexcept; bool is_directory(const path& p); bool is_directory(const path& p, error_code& ec) noexcept; bool is_empty(const path& p); bool is_empty(const path& p, error_code& ec); bool is_fifo(file_status s) noexcept; bool is_fifo(const path& p); bool is_fifo(const path& p, error_code& ec) noexcept; bool is_other(file_status s) noexcept; bool is_other(const path& p); bool is_other(const path& p, error_code& ec) noexcept; bool is_regular_file(file_status s) noexcept; bool is_regular_file(const path& p); bool is_regular_file(const path& p, error_code& ec) noexcept; bool is_socket(file_status s) noexcept; bool is_socket(const path& p); bool is_socket(const path& p, error_code& ec) noexcept; bool is_symlink(file_status s) noexcept; bool is_symlink(const path& p); bool is_symlink(const path& p, error_code& ec) noexcept; file_time_type last_write_time(const path& p); file_time_type last_write_time(const path& p, error_code& ec) noexcept; void last_write_time(const path& p, file_time_type new_time); void last_write_time(const path& p, file_time_type new_time, error_code& ec) noexcept; void permissions(const path& p, perms prms, perm_options opts=perm_options::replace); void permissions(const path& p, perms prms, error_code& ec) noexcept; void permissions(const path& p, perms prms, perm_options opts, error_code& ec); path proximate(const path& p, error_code& ec); path proximate(const path& p, const path& base = current_path()); path proximate(const path& p, const path& base, error_code& ec); path read_symlink(const path& p); path read_symlink(const path& p, error_code& ec); path relative(const path& p, error_code& ec); path relative(const path& p, const path& base = current_path()); path relative(const path& p, const path& base, error_code& ec); bool remove(const path& p); bool remove(const path& p, error_code& ec) noexcept; uintmax_t remove_all(const path& p); uintmax_t remove_all(const path& p, error_code& ec); void rename(const path& from, const path& to); void rename(const path& from, const path& to, error_code& ec) noexcept; void resize_file(const path& p, uintmax_t size); void resize_file(const path& p, uintmax_t size, error_code& ec) noexcept; space_info space(const path& p); space_info space(const path& p, error_code& ec) noexcept; file_status status(const path& p); file_status status(const path& p, error_code& ec) noexcept; bool status_known(file_status s) noexcept; file_status symlink_status(const path& p); file_status symlink_status(const path& p, error_code& ec) noexcept; path temp_directory_path(); path temp_directory_path(error_code& ec); path weakly_canonical(const path& p); path weakly_canonical(const path& p, error_code& ec); } namespace std { // \ref{fs.path.fmtr}, formatting support template struct formatter; // \ref{fs.path.hash}, hash support template struct hash; template<> struct hash; } namespace std::ranges { template<> inline constexpr bool @\libspec{enable_borrowed_range}{directory_iterator}@ = true; template<> inline constexpr bool @\libspec{enable_borrowed_range}{recursive_directory_iterator}@ = true; template<> inline constexpr bool @\libspec{enable_view}{directory_iterator}@ = true; template<> inline constexpr bool @\libspec{enable_view}{recursive_directory_iterator}@ = true; } \end{codeblock} \pnum Implementations should ensure that the resolution and range of \tcode{file_time_type} reflect the operating system dependent resolution and range of file time values. \rSec2[fs.err.report]{Error reporting} \pnum Filesystem library functions often provide two overloads, one that throws an exception to report file system errors, and another that sets an \tcode{error_code}. \begin{note} This supports two common use cases: \begin{itemize} \item Uses where file system errors are truly exceptional and indicate a serious failure. Throwing an exception is an appropriate response. \item Uses where file system errors are routine and do not necessarily represent failure. Returning an error code is the most appropriate response. This allows application specific error handling, including simply ignoring the error. \end{itemize} \end{note} \pnum Functions not having an argument of type \tcode{error_code\&} handle errors as follows, unless otherwise specified: \begin{itemize} \item When a call by the implementation to an operating system or other underlying API results in an error that prevents the function from meeting its specifications, an exception of type \tcode{filesystem_error} shall be thrown. For functions with a single path argument, that argument shall be passed to the \tcode{filesystem_error} constructor with a single path argument. For functions with two path arguments, the first of these arguments shall be passed to the \tcode{filesystem_error} constructor as the \tcode{path1} argument, and the second shall be passed as the \tcode{path2} argument. The \tcode{filesystem_error} constructor's \tcode{error_code} argument is set as appropriate for the specific operating system dependent error. \item Failure to allocate storage is reported by throwing an exception as described in~\ref{res.on.exception.handling}. \item Destructors throw nothing. \end{itemize} \pnum Functions having an argument of type \tcode{error_code\&} handle errors as follows, unless otherwise specified: \begin{itemize} \item If a call by the implementation to an operating system or other underlying API results in an error that prevents the function from meeting its specifications, the \tcode{error_code\&} argument is set as appropriate for the specific operating system dependent error. Otherwise, \tcode{clear()} is called on the \tcode{error_code\&} argument. \end{itemize} \rSec2[fs.class.path]{Class \tcode{path}} \rSec3[fs.class.path.general]{General} \indexlibraryglobal{path}% \pnum An object of class \tcode{path} represents a path and contains a pathname. Such an object is concerned only with the lexical and syntactic aspects of a path. The path does not necessarily exist in external storage, and the pathname is not necessarily valid for the current operating system or for a particular file system. \pnum \begin{note} Class \tcode{path} is used to support the differences between the string types used by different operating systems to represent pathnames, and to perform conversions between encodings when necessary. \end{note} \pnum A \defn{path} is a sequence of elements that identify the location of a file within a filesystem. The elements are the \opt{\grammarterm{root-name}}, \opt{\grammarterm{root-directory}}, and an optional sequence of \grammarterm{filename}{s}\iref{fs.path.generic}. The maximum number of elements in the sequence is operating system dependent\iref{fs.conform.os}. \pnum An \defnadj{absolute}{path} is a path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path that determine if it is absolute are operating system dependent. A \defnadj{relative}{path} is a path that is not absolute, and as such, only unambiguously identifies the location of a file when resolved relative to an implied starting location. The elements of a path that determine if it is relative are operating system dependent. \begin{note} Pathnames ``.''\ and ``..''\ are relative paths. \end{note} \pnum A \defn{pathname} is a character string that represents the name of a path. Pathnames are formatted according to the generic pathname format grammar\iref{fs.path.generic} or according to an operating system dependent \defn{native pathname format} accepted by the host operating system. \pnum \defnx{Pathname resolution}{pathname resolution} is the operating system dependent mechanism for resolving a pathname to a particular file in a file hierarchy. There may be multiple pathnames that resolve to the same file. \begin{example} For POSIX-based operating systems, this mechanism is specified in POSIX, section 4.12, Pathname resolution. \end{example} \begin{codeblock} namespace std::filesystem { class path { public: using value_type = @\seebelow@; using string_type = basic_string; static constexpr value_type preferred_separator = @\seebelow@; // \ref{fs.enum.path.format}, enumeration \tcode{format} enum format; // \ref{fs.path.construct}, constructors and destructor path() noexcept; path(const path& p); path(path&& p) noexcept; path(string_type&& source, format fmt = auto_format); template path(const Source& source, format fmt = auto_format); template path(InputIterator first, InputIterator last, format fmt = auto_format); template path(const Source& source, const locale& loc, format fmt = auto_format); template path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); ~path(); // \ref{fs.path.assign}, assignments path& operator=(const path& p); path& operator=(path&& p) noexcept; path& operator=(string_type&& source); path& assign(string_type&& source); template path& operator=(const Source& source); template path& assign(const Source& source); template path& assign(InputIterator first, InputIterator last); // \ref{fs.path.append}, appends path& operator/=(const path& p); template path& operator/=(const Source& source); template path& append(const Source& source); template path& append(InputIterator first, InputIterator last); // \ref{fs.path.concat}, concatenation path& operator+=(const path& x); path& operator+=(const string_type& x); path& operator+=(basic_string_view x); path& operator+=(const value_type* x); path& operator+=(value_type x); template path& operator+=(const Source& x); template path& operator+=(EcharT x); template path& concat(const Source& x); template path& concat(InputIterator first, InputIterator last); // \ref{fs.path.modifiers}, modifiers void clear() noexcept; path& make_preferred(); path& remove_filename(); path& replace_filename(const path& replacement); path& replace_extension(const path& replacement = path()); void swap(path& rhs) noexcept; // \ref{fs.path.nonmember}, non-member operators friend bool operator==(const path& lhs, const path& rhs) noexcept; friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; friend path operator/(const path& lhs, const path& rhs); // \ref{fs.path.native.obs}, native format observers const string_type& native() const noexcept; const value_type* c_str() const noexcept; operator string_type() const; template, class Allocator = allocator> basic_string string(const Allocator& a = Allocator()) const; std::string string() const; std::wstring wstring() const; std::u8string u8string() const; std::u16string u16string() const; std::u32string u32string() const; // \ref{fs.path.generic.obs}, generic format observers template, class Allocator = allocator> basic_string generic_string(const Allocator& a = Allocator()) const; std::string generic_string() const; std::wstring generic_wstring() const; std::u8string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const; // \ref{fs.path.compare}, compare int compare(const path& p) const noexcept; int compare(const string_type& s) const; int compare(basic_string_view s) const; int compare(const value_type* s) const; // \ref{fs.path.decompose}, decomposition path root_name() const; path root_directory() const; path root_path() const; path relative_path() const; path parent_path() const; path filename() const; path stem() const; path extension() const; // \ref{fs.path.query}, query bool empty() const noexcept; bool has_root_name() const; bool has_root_directory() const; bool has_root_path() const; bool has_relative_path() const; bool has_parent_path() const; bool has_filename() const; bool has_stem() const; bool has_extension() const; bool is_absolute() const; bool is_relative() const; // \ref{fs.path.gen}, generation path lexically_normal() const; path lexically_relative(const path& base) const; path lexically_proximate(const path& base) const; // \ref{fs.path.itr}, iterators class iterator; using const_iterator = iterator; iterator begin() const; iterator end() const; // \ref{fs.path.io}, \tcode{path} inserter and extractor template friend basic_ostream& operator<<(basic_ostream& os, const path& p); template friend basic_istream& operator>>(basic_istream& is, path& p); }; } \end{codeblock} \indexlibrarymember{value_type}{path}% \pnum \tcode{value_type} is a \keyword{typedef} for the operating system dependent encoded character type used to represent pathnames. \indexlibrarymember{preferred_separator}{path}% \pnum The value of the \tcode{preferred_separator} member is the operating system dependent \grammarterm{preferred-separator} character\iref{fs.path.generic}. \pnum \begin{example} For POSIX-based operating systems, \tcode{value_type} is \tcode{char} and \tcode{preferred_separator} is the slash character (\tcode{'/'}). For Windows-based operating systems, \tcode{value_type} is \keyword{wchar_t} and \tcode{preferred_separator} is the backslash character (\tcode{L'\textbackslash\textbackslash'}). \end{example} \rSec3[fs.path.generic]{Generic pathname format} \def\impldefrootname{\impldef{supported \grammarterm{root-name}{s} in addition to any operating system dependent \grammarterm{root-name}{s}}} \begin{ncbnf} \nontermdef{pathname}\br \opt{root-name} \opt{root-directory} relative-path \end{ncbnf} \begin{ncbnf} \nontermdef{root-name}\br \textnormal{operating system dependent sequences of characters}\br \textnormal{\impldefrootname{} sequences of characters} \end{ncbnf} \begin{ncbnf} \nontermdef{root-directory}\br directory-separator \end{ncbnf} \begin{ncbnf} \nontermdef{relative-path}\br filename\br filename directory-separator relative-path\br \textnormal{an empty path} \end{ncbnf} \begin{ncbnf} \nontermdef{filename}\br \textnormal{non-empty sequence of characters other than \grammarterm{directory-separator} characters} \end{ncbnf} \begin{ncbnf} \nontermdef{directory-separator}\br preferred-separator \opt{directory-separator}\br fallback-separator \opt{directory-separator} \end{ncbnf} \begin{ncbnf} \nontermdef{preferred-separator}\br \textnormal{operating system dependent directory separator character} \end{ncbnf} \begin{ncbnf} \nontermdef{fallback-separator}\br \textnormal{\tcode{/}, if \grammarterm{preferred-separator} is not \tcode{/}} \end{ncbnf} \pnum A \defn{filename} is the name of a file. The \defnx{dot}{dot!filename} and \defnx{dot-dot}{dot-dot!filename} filenames, consisting solely of one and two period characters respectively, have special meaning. The following characteristics of filenames are operating system dependent: \begin{itemize} \item The permitted characters. \begin{example} Some operating systems prohibit the ASCII control characters (0x00 -- 0x1F) in filenames. \end{example} \begin{note} Wider portability can be achieved by limiting \grammarterm{filename} characters to the POSIX Portable Filename Character Set: \\ \tcode{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} \\ \tcode{a b c d e f g h i j k l m n o p q r s t u v w x y z} \\ \tcode{0 1 2 3 4 5 6 7 8 9 . _ -} \end{note} \item The maximum permitted length. \item Filenames that are not permitted. \item Filenames that have special meaning. \item Case awareness and sensitivity during path resolution. \item Special rules that may apply to file types other than regular files, such as directories. \end{itemize} \pnum Except in a \grammarterm{root-name}, multiple successive \grammarterm{directory-separator} characters are considered to be the same as one \grammarterm{directory-separator} character. \pnum The dot filename is treated as a reference to the current directory. The dot-dot filename is treated as a reference to the parent directory. What the dot-dot filename refers to relative to \grammarterm{root-directory} is \impldef{meaning of dot-dot in \grammarterm{root-directory}}. Specific filenames may have special meanings for a particular operating system. \pnum A \grammarterm{root-name} identifies the starting location for pathname resolution\iref{fs.class.path}. If there are no operating system dependent \grammarterm{root-name}{s}, at least one \impldefrootname{} \grammarterm{root-name} is required. \begin{note} Many operating systems define a name beginning with two \grammarterm{directory-separator} characters as a \grammarterm{root-name} that identifies network or other resource locations. Some operating systems define a single letter followed by a colon as a drive specifier --- a \grammarterm{root-name} identifying a specific device such as a disk drive. \end{note} \pnum If a \grammarterm{root-name} is otherwise ambiguous, the possibility with the longest sequence of characters is chosen. \begin{note} On a POSIX-like operating system, it is impossible to have a \grammarterm{root-name} and a \grammarterm{relative-path} without an intervening \grammarterm{root-directory} element. \end{note} \pnum \indextext{path!normalization|(}% \defnx{Normalization}{normalization!path|see{path, normalization}} of a generic format pathname means: \begin{enumerate} \item If the path is empty, stop. \item Replace each slash character in the \grammarterm{root-name} with a \grammarterm{preferred-separator}. \item Replace each \grammarterm{directory-separator} with a \grammarterm{preferred-separator}. \begin{note} The generic pathname grammar defines \grammarterm{directory-separator} as one or more slashes and \grammarterm{preferred-separator}{s}. \end{note} \item Remove each dot filename and any immediately following \grammarterm{directory-separator}. \item As long as any appear, remove a non-dot-dot filename immediately followed by a \grammarterm{directory-separator} and a dot-dot filename, along with any immediately following \grammarterm{directory-separator}. \item If there is a \grammarterm{root-directory}, remove all dot-dot filenames and any \grammarterm{directory-separator}{s} immediately following them. \begin{note} These dot-dot filenames attempt to refer to nonexistent parent directories. \end{note} \item If the last filename is dot-dot, remove any trailing \grammarterm{directory-separator}. \item If the path is empty, add a dot. \end{enumerate} The result of normalization is a path in \defnx{normal form}{normal form!path}, which is said to be \term{normalized}. \indextext{path!normalization|)}% \rSec3[fs.path.cvt]{Conversions} \rSec4[fs.path.fmt.cvt]{Argument format conversions} \pnum \begin{note} The format conversions described in this subclause are not applied on POSIX-based operating systems because on these systems: \begin{itemize} \item The generic format is acceptable as a native path. \item There is no need to distinguish between native format and generic format in function arguments. \item Paths for regular files and paths for directories share the same syntax. \end{itemize} \end{note} \pnum Several functions are defined to accept \term{detected-format} arguments, which are character sequences. A detected-format argument represents a path using either a pathname in the generic format\iref{fs.path.generic} or a pathname in the native format\iref{fs.class.path}. Such an argument is taken to be in the generic format if and only if it matches the generic format and is not acceptable to the operating system as a native path. \pnum \begin{note} Some operating systems have no unambiguous way to distinguish between native format and generic format arguments. This is by design as it simplifies use for operating systems that do not require disambiguation. It is possible that an implementation for an operating system where disambiguation is needed distinguishes between the formats. \end{note} \pnum Pathnames are converted as needed between the generic and native formats in an operating-system-dependent manner. Let \placeholder{G(n)} and \placeholder{N(g)} in a mathematical sense be the implementation's functions that convert native-to-generic and generic-to-native formats respectively. If \placeholder{g=G(n)} for some \placeholder{n}, then \placeholder{G(N(g))=g}; if \placeholder{n=N(g)} for some \placeholder{g}, then \placeholder{N(G(n))=n}. \begin{note} Neither \placeholder{G} nor \placeholder{N} need be invertible. \end{note} \pnum If the native format requires paths for regular files to be formatted differently from paths for directories, the path shall be treated as a directory path if its last element is a \grammarterm{directory-separator}, otherwise it shall be treated as a path to a regular file. \pnum \begin{note} A path stores a native format pathname\iref{fs.path.native.obs} and acts as if it also stores a generic format pathname, related as given below. The implementation can generate the generic format pathname based on the native format pathname (and possibly other information) when requested. \end{note} \pnum When a path is constructed from or is assigned a single representation separate from any path, the other representation is selected by the appropriate conversion function (\placeholder{G} or \placeholder{N}). \pnum When the (new) value \placeholder{p} of one representation of a path is derived from the representation of that or another path, a value \placeholder{q} is chosen for the other representation. The value \placeholder{q} converts to \placeholder{p} (by \placeholder{G} or \placeholder{N} as appropriate) if any such value does so; \placeholder{q} is otherwise unspecified. \begin{note} If \placeholder{q} is the result of converting any path at all, it is the result of converting \placeholder{p}. \end{note} \rSec4[fs.path.type.cvt]{Type and encoding conversions} \pnum The \defn{native encoding} of an ordinary character string is the operating system dependent current encoding for pathnames\iref{fs.class.path}. The \defn{native encoding} for wide character strings is the implementation-defined execution wide-character set encoding\iref{character.seq}. \pnum For member function arguments that take character sequences representing paths and for member functions returning strings, value type and encoding conversion is performed if the value type of the argument or return value differs from \tcode{path::value_type}. For the argument or return value, the method of conversion and the encoding to be converted to is determined by its value type: \begin{itemize} \item \tcode{char}: The encoding is the native ordinary encoding. The method of conversion, if any, is operating system dependent. \begin{note} For POSIX-based operating systems \tcode{path::value_type} is \tcode{char} so no conversion from \tcode{char} value type arguments or to \tcode{char} value type return values is performed. For Windows-based operating systems, the native ordinary encoding is determined by calling a Windows API function. \end{note} \begin{note} This results in behavior identical to other C and \Cpp{} standard library functions that perform file operations using ordinary character strings to identify paths. Changing this behavior would be surprising and error-prone. \end{note} \item \keyword{wchar_t}: The encoding is the native wide encoding. The method of conversion is unspecified. \begin{note} For Windows-based operating systems \tcode{path::value_type} is \keyword{wchar_t} so no conversion from \keyword{wchar_t} value type arguments or to \tcode{wchar_t} value type return values is performed. \end{note} \item \indextext{UTF-8}% \keyword{char8_t}: The encoding is UTF-8. The method of conversion is unspecified. \item \indextext{UTF-16}% \keyword{char16_t}: The encoding is UTF-16. The method of conversion is unspecified. \item \indextext{UTF-32}% \keyword{char32_t}: The encoding is UTF-32. The method of conversion is unspecified. \end{itemize} \pnum If the encoding being converted to has no representation for source characters, the resulting converted characters, if any, are unspecified. Implementations should not modify member function arguments if already of type \tcode{path::value_type}. \rSec3[fs.path.req]{Requirements} \pnum In addition to the requirements\iref{fs.req}, function template parameters named \tcode{Source} shall be one of: \begin{itemize} \item \tcode{basic_string}. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source.begin()}{source.end()}. \item \tcode{basic_string_view}. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source.begin()}{source.end()}. \item A type meeting the \oldconcept{InputIterator} requirements that iterates over a NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to \tcode{iterator_traits::value_type()}. \item A character array that after array-to-pointer decay results in a pointer to the start of a NTCTS\@. The value type shall be an encoded character type. A function argument \tcode{const Source\&} \tcode{source} shall have an effective range \range{source}{end} where \tcode{end} is the first iterator value with an element value equal to \tcode{iterator_traits>::value_type()}. \end{itemize} \pnum Functions taking template parameters named \tcode{Source} shall not participate in overload resolution unless \tcode{Source} denotes a type other than \tcode{path}, and either \begin{itemize} \item \tcode{Source} is a specialization of \tcode{basic_string} or \tcode{basic_string_view}, or \item the \grammarterm{qualified-id} \tcode{iterator_traits>::value_type} is valid and denotes a possibly const encoded character type\iref{temp.deduct}. \end{itemize} \pnum \begin{note} See path conversions\iref{fs.path.cvt} for how the value types above and their encodings convert to \tcode{path::value_type} and its encoding. \end{note} \pnum Arguments of type \tcode{Source} shall not be null pointers. \rSec3[fs.path.member]{Members} \rSec4[fs.path.construct]{Constructors} \indexlibraryctor{path}% \begin{itemdecl} path() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{empty()} is \keyword{true}. \end{itemdescr} \indexlibraryctor{path}% \begin{itemdecl} path(const path& p); path(path&& p) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs an object of class \tcode{path} having the same pathname in the native and generic formats, respectively, as the original value of \tcode{p}. In the second form, \tcode{p} is left in a valid but unspecified state. \end{itemdescr} \indexlibraryctor{path}% \begin{itemdecl} path(string_type&& source, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs an object of class \tcode{path} for which the pathname in the detected-format of \tcode{source} has the original value of \tcode{source}\iref{fs.path.fmt.cvt}, converting format if required\iref{fs.path.fmt.cvt}. \tcode{source} is left in a valid but unspecified state. \end{itemdescr} \indexlibraryctor{path}% \begin{itemdecl} template path(const Source& source, format fmt = auto_format); template path(InputIterator first, InputIterator last, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{s} be the effective range of \tcode{source}\iref{fs.path.req} or the range \range{first}{last}, with the encoding converted if required\iref{fs.path.cvt}. Finds the detected-format of \tcode{s}\iref{fs.path.fmt.cvt} and constructs an object of class \tcode{path} for which the pathname in that format is \tcode{s}. \end{itemdescr} \indexlibraryctor{path}% \begin{itemdecl} template path(const Source& source, const locale& loc, format fmt = auto_format); template path(InputIterator first, InputIterator last, const locale& loc, format fmt = auto_format); \end{itemdecl} \begin{itemdescr} \pnum \mandates The value type of \tcode{Source} and \tcode{InputIterator} is \tcode{char}. \pnum \effects Let \tcode{s} be the effective range of \tcode{source} or the range \range{first}{last}, after converting the encoding as follows: \begin{itemize} \item If \tcode{value_type} is \keyword{wchar_t}, converts to the native wide encoding\iref{fs.path.type.cvt} using the \tcode{codecvt<\brk{}wchar_t, char, mbstate_t>} facet of \tcode{loc}. \item Otherwise a conversion is performed using the \tcode{codecvt} facet of \tcode{loc}, and then a second conversion to the current ordinary encoding. \end{itemize} \pnum Finds the detected-format of \tcode{s}\iref{fs.path.fmt.cvt} and constructs an object of class \tcode{path} for which the pathname in that format is \tcode{s}. \begin{example} A string is to be read from a database that is encoded in ISO/IEC 8859-1, and used to create a directory: \begin{codeblock} namespace fs = std::filesystem; std::string latin1_string = read_latin1_data(); codecvt_8859_1 latin1_facet; std::locale latin1_locale(std::locale(), latin1_facet); fs::create_directory(fs::path(latin1_string, latin1_locale)); \end{codeblock} For POSIX-based operating systems, the path is constructed by first using \tcode{latin1_facet} to convert ISO/IEC 8859-1 encoded \tcode{latin1_string} to a wide character string in the native wide encoding\iref{fs.path.type.cvt}. The resulting wide string is then converted to an ordinary character pathname string in the current native ordinary encoding. If the native wide encoding is UTF-16 or UTF-32, and the current native ordinary encoding is UTF-8, all of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation, but for other native ordinary encodings some characters may have no representation. For Windows-based operating systems, the path is constructed by using \tcode{latin1_facet} to convert ISO/IEC 8859-1 encoded \tcode{latin1_string} to a UTF-16 encoded wide character pathname string. All of the characters in the ISO/IEC 8859-1 character set will be converted to their Unicode representation. \end{example} \end{itemdescr} \rSec4[fs.path.assign]{Assignments} \indexlibrarymember{operator=}{path}% \begin{itemdecl} path& operator=(const path& p); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{p} are the same object, has no effect. Otherwise, sets both respective pathnames of \tcode{*this} to the respective pathnames of \tcode{p}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{path}% \begin{itemdecl} path& operator=(path&& p) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{p} are the same object, has no effect. Otherwise, sets both respective pathnames of \tcode{*this} to the respective pathnames of \tcode{p}. \tcode{p} is left in a valid but unspecified state. \begin{note} A valid implementation is \tcode{swap(p)}. \end{note} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{path}% \indexlibrarymember{assign}{path}% \begin{itemdecl} path& operator=(string_type&& source); path& assign(string_type&& source); \end{itemdecl} \begin{itemdescr} \pnum \effects Sets the pathname in the detected-format of \tcode{source} to the original value of \tcode{source}. \tcode{source} is left in a valid but unspecified state. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{path}% \indexlibrarymember{assign}{path}% \begin{itemdecl} template path& operator=(const Source& source); template path& assign(const Source& source); template path& assign(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{s} be the effective range of \tcode{source}\iref{fs.path.req} or the range \range{first}{last}, with the encoding converted if required\iref{fs.path.cvt}. Finds the detected-format of \tcode{s}\iref{fs.path.fmt.cvt} and sets the pathname in that format to \tcode{s}. \pnum \returns \tcode{*this}. \end{itemdescr} \rSec4[fs.path.append]{Appends} \pnum The append operations use \tcode{operator/=} to denote their semantic effect of appending \grammarterm{preferred-separator} when needed. \indexlibrarymember{operator/=}{path}% \begin{itemdecl} path& operator/=(const path& p); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{p.is_absolute() || (p.has_root_name() \&\& p.root_name() != root_name())}, then \tcode{operator=(p)}. \pnum Otherwise, modifies \tcode{*this} as if by these steps: \begin{itemize} \item If \tcode{p.has_root_directory()}, then removes any root directory and relative path from the generic format pathname. Otherwise, if \tcode{!has_root_directory() \&\& is_absolute()} is \tcode{true} or if \tcode{has_filename()} is \tcode{true}, then appends \tcode{path::preferred_separator} to the generic format pathname. \item Then appends the native format pathname of \tcode{p}, omitting any \grammarterm{root-name} from its generic format pathname, to the native format pathname. \end{itemize} \pnum \begin{example} Even if \tcode{//host} is interpreted as a \grammarterm{root-name}, both of the paths \tcode{path("//host")/"foo"} and \tcode{path("//host/")/"foo"} equal \tcode{"//host/foo"} (although the former might use backslash as the preferred separator). Expression examples: \begin{codeblock} // On POSIX, path("foo") /= path(""); // yields \tcode{path("foo/")} path("foo") /= path("/bar"); // yields \tcode{path("/bar")} // On Windows, path("foo") /= path(""); // yields \tcode{path("foo\textbackslash\textbackslash{}")} path("foo") /= path("/bar"); // yields \tcode{path("/bar")} path("foo") /= path("c:/bar"); // yields \tcode{path("c:/bar")} path("foo") /= path("c:"); // yields \tcode{path("c:")} path("c:") /= path(""); // yields \tcode{path("c:")} path("c:foo") /= path("/bar"); // yields \tcode{path("c:/bar")} path("c:foo") /= path("c:bar"); // yields \tcode{path("c:foo\textbackslash\textbackslash{}bar")} \end{codeblock} \end{example} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator/=}{path}% \indexlibrarymember{append}{path}% \begin{itemdecl} template path& operator/=(const Source& source); template path& append(const Source& source); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return operator/=(path(source));} \end{itemdescr} \indexlibrarymember{operator/=}{path}% \indexlibrarymember{append}{path}% \begin{itemdecl} template path& append(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return operator/=(path(first, last));} \end{itemdescr} \rSec4[fs.path.concat]{Concatenation} \indexlibrarymember{operator+=}{path}% \indexlibrarymember{concat}{path}% \begin{itemdecl} path& operator+=(const path& x); path& operator+=(const string_type& x); path& operator+=(basic_string_view x); path& operator+=(const value_type* x); template path& operator+=(const Source& x); template path& concat(const Source& x); \end{itemdecl} \begin{itemdescr} \pnum \effects Appends \tcode{path(x).native()} to the pathname in the native format. \begin{note} This directly manipulates the value of \tcode{native()}, which is not necessarily portable between operating systems. \end{note} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator+=}{path}% \indexlibrarymember{concat}{path}% \begin{itemdecl} path& operator+=(value_type x); template path& operator+=(EcharT x); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return *this += basic_string_view(\&x, 1);} \end{itemdescr} \indexlibrarymember{concat}{path}% \begin{itemdecl} template path& concat(InputIterator first, InputIterator last); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return *this += path(first, last);} \end{itemdescr} \rSec4[fs.path.modifiers]{Modifiers} \indexlibrarymember{clear}{path}% \begin{itemdecl} void clear() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{empty()} is \tcode{true}. \end{itemdescr} \indexlibrarymember{make_preferred}{path}% \begin{itemdecl} path& make_preferred(); \end{itemdecl} \begin{itemdescr} \pnum \effects Each \grammarterm{directory-separator} of the pathname in the generic format is converted to \grammarterm{preferred-separator}. \pnum \returns \tcode{*this}. \pnum \begin{example} \begin{codeblock} path p("foo/bar"); std::cout << p << '\n'; p.make_preferred(); std::cout << p << '\n'; \end{codeblock} On an operating system where \grammarterm{preferred-separator} is a slash, the output is: \begin{codeblock} "foo/bar" "foo/bar" \end{codeblock} On an operating system where \grammarterm{preferred-separator} is a backslash, the output is: \begin{codeblock} "foo/bar" "foo\bar" \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{remove_filename}{path}% \begin{itemdecl} path& remove_filename(); \end{itemdecl} \begin{itemdescr} \pnum \effects Remove the generic format pathname of \tcode{filename()} from the generic format pathname. \pnum \ensures \tcode{!has_filename()}. \pnum \returns \tcode{*this}. \pnum \begin{example} \begin{codeblock} path("foo/bar").remove_filename(); // yields \tcode{"foo/"} path("foo/").remove_filename(); // yields \tcode{"foo/"} path("/foo").remove_filename(); // yields \tcode{"/"} path("/").remove_filename(); // yields \tcode{"/"} \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{replace_filename}{path}% \begin{itemdecl} path& replace_filename(const path& replacement); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} remove_filename(); operator/=(replacement); \end{codeblock} \pnum \returns \tcode{*this}. \pnum \begin{example} \begin{codeblock} path("/foo").replace_filename("bar"); // yields \tcode{"/bar"} on POSIX path("/").replace_filename("bar"); // yields \tcode{"/bar"} on POSIX \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{replace_extension}{path}% \begin{itemdecl} path& replace_extension(const path& replacement = path()); \end{itemdecl} \begin{itemdescr} \pnum \effects \begin{itemize} \item Any existing \tcode{extension()}\iref{fs.path.decompose} is removed from the pathname in the generic format, then \item If \tcode{replacement} is not empty and does not begin with a dot character, a dot character is appended to the pathname in the generic format, then \item \tcode{operator+=(replacement);}. \end{itemize} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{swap}{path}% \begin{itemdecl} void swap(path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Swaps the contents (in all formats) of the two paths. \pnum \complexity Constant time. \end{itemdescr} \rSec4[fs.path.native.obs]{Native format observers} \pnum The string returned by all native format observers is in the native pathname format\iref{fs.class.path}. \indexlibrarymember{native}{path}% \begin{itemdecl} const string_type& native() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The pathname in the native format. \end{itemdescr} \indexlibrarymember{c_str}{path}% \begin{itemdecl} const value_type* c_str() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return native().c_str();} \end{itemdescr} \indexlibrarymember{operator string_type}{path}% \begin{itemdecl} operator string_type() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{native()}. \end{itemdescr} \indexlibrarymember{string}{path}% \begin{itemdecl} template, class Allocator = allocator> basic_string string(const Allocator& a = Allocator()) const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{native()}. \pnum \remarks All memory allocation, including for the return value, shall be performed by \tcode{a}. Conversion, if any, is specified by \ref{fs.path.cvt}. \end{itemdescr} \indexlibrarymember{string}{path}% \indexlibrarymember{wstring}{path}% \indexlibrarymember{u8string}{path}% \indexlibrarymember{u16string}{path}% \indexlibrarymember{u32string}{path}% \begin{itemdecl} std::string string() const; std::wstring wstring() const; std::u8string u8string() const; std::u16string u16string() const; std::u32string u32string() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{native()}. \pnum \remarks Conversion, if any, is performed as specified by \ref{fs.path.cvt}. \end{itemdescr} \rSec4[fs.path.generic.obs]{Generic format observers} \pnum Generic format observer functions return strings formatted according to the generic pathname format\iref{fs.path.generic}. A single slash (\tcode{'/'}) character is used as the \grammarterm{directory-separator}. \pnum \begin{example} On an operating system that uses backslash as its \grammarterm{preferred-separator}, \begin{codeblock} path("foo\\bar").generic_string() \end{codeblock} returns \tcode{"foo/bar"}. \end{example} \indexlibrarymember{generic_string}{path}% \begin{itemdecl} template, class Allocator = allocator> basic_string generic_string(const Allocator& a = Allocator()) const; \end{itemdecl} \begin{itemdescr} \pnum \returns The pathname in the generic format. \pnum \remarks All memory allocation, including for the return value, shall be performed by \tcode{a}. Conversion, if any, is specified by \ref{fs.path.cvt}. \end{itemdescr} \indexlibrarymember{generic_string}{path}% \indexlibrarymember{generic_wstring}{path}% \indexlibrarymember{generic_u8string}{path}% \indexlibrarymember{generic_u16string}{path}% \indexlibrarymember{generic_u32string}{path}% \begin{itemdecl} std::string generic_string() const; std::wstring generic_wstring() const; std::u8string generic_u8string() const; std::u16string generic_u16string() const; std::u32string generic_u32string() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The pathname in the generic format. \pnum \remarks Conversion, if any, is specified by~\ref{fs.path.cvt}. \end{itemdescr} \rSec4[fs.path.compare]{Compare} \indexlibrarymember{compare}{path}% \begin{itemdecl} int compare(const path& p) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \begin{itemize} \item Let \tcode{rootNameComparison} be the result of \tcode{this->root_name().native().compare(p.root_name().native())}. If \tcode{rootNameComparison} is not \tcode{0}, \tcode{rootNameComparison}. \item Otherwise, if \tcode{!this->has_root_directory()} and \tcode{p.has_root_directory()}, a value less than \tcode{0}. \item Otherwise, if \tcode{this->has_root_directory()} and \tcode{!p.has_root_directory()}, a value greater than \tcode{0}. \item Otherwise, if \tcode{native()} for the elements of \tcode{this->relative_path()} are lexicographically less than \tcode{native()} for the elements of \tcode{p.relative_path()}, a value less than \tcode{0}. \item Otherwise, if \tcode{native()} for the elements of \tcode{this->relative_path()} are lexicographically greater than \tcode{native()} for the elements of \tcode{p.relative_path()}, a value greater than \tcode{0}. \item Otherwise, \tcode{0}. \end{itemize} \end{itemdescr} \indexlibrarymember{compare}{path}% \begin{itemdecl} int compare(const string_type& s) const; int compare(basic_string_view s) const; int compare(const value_type* s) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return compare(path(s));} \end{itemdescr} \rSec4[fs.path.decompose]{Decomposition} \indexlibrarymember{root_name}{path}% \begin{itemdecl} path root_name() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \grammarterm{root-name}, if the pathname in the generic format includes \grammarterm{root-name}, otherwise \tcode{path()}. \end{itemdescr} \indexlibrarymember{root_directory}{path}% \begin{itemdecl} path root_directory() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \grammarterm{root-directory}, if the pathname in the generic format includes \grammarterm{root-directory}, otherwise \tcode{path()}. \end{itemdescr} \indexlibrarymember{root_path}{path}% \begin{itemdecl} path root_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{root_name() / root_directory()}. \end{itemdescr} \indexlibrarymember{relative_path}{path}% \begin{itemdecl} path relative_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns A \tcode{path} composed from the pathname in the generic format, if \tcode{empty()} is \tcode{false}, beginning with the first \grammarterm{filename} after \tcode{root_path()}. Otherwise, \tcode{path()}. \end{itemdescr} \indexlibrarymember{parent_path}{path}% \begin{itemdecl} path parent_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{*this} if \tcode{has_relative_path()} is \tcode{false}, otherwise a path whose generic format pathname is the longest prefix of the generic format pathname of \tcode{*this} that produces one fewer element in its iteration. \end{itemdescr} \indexlibrarymember{filename}{path}% \begin{itemdecl} path filename() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{relative_path().empty() ? path() : *--end()}. \pnum \begin{example} \begin{codeblock} path("/foo/bar.txt").filename(); // yields \tcode{"bar.txt"} path("/foo/bar").filename(); // yields \tcode{"bar"} path("/foo/bar/").filename(); // yields \tcode{""} path("/").filename(); // yields \tcode{""} path("//host").filename(); // yields \tcode{""} path(".").filename(); // yields \tcode{"."} path("..").filename(); // yields \tcode{".."} \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{stem}{path}% \begin{itemdecl} path stem() const; \end{itemdecl} \begin{itemdescr} \pnum \returns Let \tcode{f} be the generic format pathname of \tcode{filename()}. Returns a path whose pathname in the generic format is \begin{itemize} \item \tcode{f}, if it contains no periods other than a leading period or consists solely of one or two periods; \item otherwise, the prefix of \tcode{f} ending before its last period. \end{itemize} \pnum \begin{example} \begin{codeblock} std::cout << path("/foo/bar.txt").stem(); // outputs \tcode{"bar"} path p = "foo.bar.baz.tar"; for (; !p.extension().empty(); p = p.stem()) std::cout << p.extension() << '\n'; // outputs: \tcode{.tar} // \tcode{.baz} // \tcode{.bar} \end{codeblock} \end{example} \end{itemdescr} \indexlibrarymember{extension}{path}% \begin{itemdecl} path extension() const; \end{itemdecl} \begin{itemdescr} \pnum \returns A path whose pathname in the generic format is the suffix of \tcode{filename()} not included in \tcode{stem()}. \pnum \begin{example} \begin{codeblock} path("/foo/bar.txt").extension(); // yields \tcode{".txt"} and \tcode{stem()} is \tcode{"bar"} path("/foo/bar").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{"bar"} path("/foo/.profile").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{".profile"} path(".bar").extension(); // yields \tcode{""} and \tcode{stem()} is \tcode{".bar"} path("..bar").extension(); // yields \tcode{".bar"} and \tcode{stem()} is \tcode{"."} \end{codeblock} \end{example} \pnum \begin{note} The period is included in the return value so that it is possible to distinguish between no extension and an empty extension. \end{note} \pnum \begin{note} On non-POSIX operating systems, for a path \tcode{p}, it is possible that \tcode{p.stem() + p.extension() == p.filename()} is \tcode{false}, even though the generic format pathnames are the same. \end{note} \end{itemdescr} \rSec4[fs.path.query]{Query} \indexlibrarymember{empty}{path}% \begin{itemdecl} bool empty() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if the pathname in the generic format is empty, otherwise \tcode{false}. \end{itemdescr} \indexlibrarymember{has_root_path}{path}% \begin{itemdecl} bool has_root_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!root_path().empty()}. \end{itemdescr} \indexlibrarymember{has_root_name}{path}% \begin{itemdecl} bool has_root_name() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!root_name().empty()}. \end{itemdescr} \indexlibrarymember{has_root_directory}{path}% \begin{itemdecl} bool has_root_directory() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!root_directory().empty()}. \end{itemdescr} \indexlibrarymember{has_relative_path}{path}% \begin{itemdecl} bool has_relative_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!relative_path().empty()}. \end{itemdescr} \indexlibrarymember{has_parent_path}{path}% \begin{itemdecl} bool has_parent_path() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!parent_path().empty()}. \end{itemdescr} \indexlibrarymember{has_filename}{path}% \begin{itemdecl} bool has_filename() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!filename().empty()}. \end{itemdescr} \indexlibrarymember{has_stem}{path}% \begin{itemdecl} bool has_stem() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!stem().empty()}. \end{itemdescr} \indexlibrarymember{has_extension}{path}% \begin{itemdecl} bool has_extension() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!extension().empty()}. \end{itemdescr} \indexlibrarymember{is_absolute}{path}% \begin{itemdecl} bool is_absolute() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if the pathname in the native format contains an absolute path\iref{fs.class.path}, otherwise \tcode{false}. \pnum \begin{example} \tcode{path("/").is_absolute()} is \tcode{true} for POSIX-based operating systems, and \tcode{false} for Windows-based operating systems. \end{example} \end{itemdescr} \indexlibrarymember{is_relative}{path}% \begin{itemdecl} bool is_relative() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{!is_absolute()}. \end{itemdescr} \rSec4[fs.path.gen]{Generation} \indexlibrarymember{lexically_normal}{path}% \begin{itemdecl} path lexically_normal() const; \end{itemdecl} \begin{itemdescr} \pnum \returns A path whose pathname in the generic format is the normal form\iref{fs.path.generic} of the pathname in the generic format of \tcode{*this}. \pnum \begin{example} \begin{codeblock} assert(path("foo/./bar/..").lexically_normal() == "foo/"); assert(path("foo/.///bar/../").lexically_normal() == "foo/"); \end{codeblock} The above assertions will succeed. On Windows, the returned path's \grammarterm{directory-separator} characters will be backslashes rather than slashes, but that does not affect \tcode{path} equality. \end{example} \end{itemdescr} \indexlibrarymember{lexically_relative}{path}% \begin{itemdecl} path lexically_relative(const path& base) const; \end{itemdecl} \begin{itemdescr} \pnum \effects If: \begin{itemize} \item \tcode{root_name() != base.root_name()} is \tcode{true}, or \item \tcode{is_absolute() != base.is_absolute()} is \tcode{true}, or \item \tcode{!has_root_directory() \&\& base.has_root_directory()} is \tcode{true}, or \item any \grammarterm{filename} in \tcode{relative_path()} or \tcode{base.relative_path()} can be interpreted as a \grammarterm{root-name}, \end{itemize} returns \tcode{path()}. \begin{note} On a POSIX implementation, no \grammarterm{filename} in a \grammarterm{relative-path} is acceptable as a \grammarterm{root-name}. \end{note} Determines the first mismatched element of \tcode{*this} and \tcode{base} as if by: \begin{codeblock} auto [a, b] = mismatch(begin(), end(), base.begin(), base.end()); \end{codeblock} Then, \begin{itemize} \item if \tcode{a == end()} and \tcode{b == base.end()}, returns \tcode{path(".")}; otherwise \item let \tcode{n} be the number of \grammarterm{filename} elements in \range{b}{base.end()} that are not dot or dot-dot or empty, minus the number that are dot-dot. If \tcode{n<0,} returns \tcode{path()}; otherwise \item if \tcode{n == 0} and \tcode{(a == end() || a->empty())}, returns \tcode{path(".")}; otherwise \item returns an object of class \tcode{path} that is default-constructed, followed by \begin{itemize} \item application of \tcode{operator/=(path(".."))} \tcode{n} times, and then \item application of \tcode{operator/=} for each element in \range{a}{end()}. \end{itemize} \end{itemize} \pnum \returns \tcode{*this} made relative to \tcode{base}. Does not resolve\iref{fs.class.path} symlinks. Does not first normalize\iref{fs.path.generic} \tcode{*this} or \tcode{base}. \pnum \begin{example} \begin{codeblock} assert(path("/a/d").lexically_relative("/a/b/c") == "../../d"); assert(path("/a/b/c").lexically_relative("/a/d") == "../b/c"); assert(path("a/b/c").lexically_relative("a") == "b/c"); assert(path("a/b/c").lexically_relative("a/b/c/x/y") == "../.."); assert(path("a/b/c").lexically_relative("a/b/c") == "."); assert(path("a/b").lexically_relative("c/d") == "../../a/b"); \end{codeblock} The above assertions will succeed. On Windows, the returned path's \grammarterm{directory-separator} characters will be backslashes rather than slashes, but that does not affect \tcode{path} equality. \end{example} \pnum \begin{note} If symlink following semantics are desired, use the operational function \tcode{relative()}. \end{note} \pnum \begin{note} If normalization\iref{fs.path.generic} is needed to ensure consistent matching of elements, apply \tcode{lexically_normal()} to \tcode{*this}, \tcode{base}, or both. \end{note} \end{itemdescr} \indexlibrarymember{lexically_proximate}{path}% \begin{itemdecl} path lexically_proximate(const path& base) const; \end{itemdecl} \begin{itemdescr} \pnum \returns If the value of \tcode{lexically_relative(base)} is not an empty path, return it. Otherwise return \tcode{*this}. \pnum \begin{note} If symlink following semantics are desired, use the operational function \tcode{proximate()}. \end{note} \pnum \begin{note} If normalization\iref{fs.path.generic} is needed to ensure consistent matching of elements, apply \tcode{lexically_normal()} to \tcode{*this}, \tcode{base}, or both. \end{note} \end{itemdescr} \rSec3[fs.path.itr]{Iterators} \indexlibrarymember{path}{iterator}% \pnum Path iterators iterate over the elements of the pathname in the generic format\iref{fs.path.generic}. \pnum A \tcode{path::iterator} is a constant iterator meeting all the requirements of a bidirectional iterator\iref{bidirectional.iterators} except that, for dereferenceable iterators \tcode{a} and \tcode{b} of type \tcode{path::iterator} with \tcode{a == b}, there is no requirement that \tcode{*a} and \tcode{*b} are bound to the same object. Its \tcode{value_type} is \tcode{path}. \pnum Calling any non-const member function of a \tcode{path} object invalidates all iterators referring to elements of that object. \pnum For the elements of the pathname in the generic format, the forward traversal order is as follows: \begin{itemize} \item The \grammarterm{root-name} element, if present. \item The \grammarterm{root-directory} element, if present. \begin{note} It is possible that the use of the generic format is needed to ensure correct lexicographical comparison. \end{note} \item Each successive \grammarterm{filename} element, if present. \item An empty element, if a trailing non-root \grammarterm{directory-separator} is present. \end{itemize} \pnum The backward traversal order is the reverse of forward traversal. \indexlibrarymember{begin}{path}% \begin{itemdecl} iterator begin() const; \end{itemdecl} \begin{itemdescr} \pnum \returns An iterator for the first present element in the traversal list above. If no elements are present, the end iterator. \end{itemdescr} \indexlibrarymember{end}{path}% \begin{itemdecl} iterator end() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The end iterator. \end{itemdescr} \rSec3[fs.path.io]{Inserter and extractor} \indexlibrarymember{operator<<}{path}% \begin{itemdecl} template friend basic_ostream& operator<<(basic_ostream& os, const path& p); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{os << quoted(p.string())}. \begin{note} The \tcode{quoted} function is described in~\ref{quoted.manip}. \end{note} \pnum \returns \tcode{os}. \end{itemdescr} \indexlibrarymember{operator>>}{path}% \begin{itemdecl} template friend basic_istream& operator>>(basic_istream& is, path& p); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \begin{codeblock} basic_string tmp; is >> quoted(tmp); p = tmp; \end{codeblock} \pnum \returns \tcode{is}. \end{itemdescr} \rSec3[fs.path.nonmember]{Non-member functions} \indexlibrarymember{swap}{path}% \begin{itemdecl} void swap(path& lhs, path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{lhs.swap(rhs)}. \end{itemdescr} \indexlibrarymember{hash_value}{path}% \begin{itemdecl} size_t hash_value(const path& p) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A hash value for the path \tcode{p}. If for two paths, \tcode{p1 == p2} then \tcode{hash_value(p1) == hash_value(p2)}. \end{itemdescr} \indexlibrarymember{operator==}{path}% \begin{itemdecl} friend bool operator==(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(rhs) == 0}. \indextext{path equality} \pnum \begin{note} Path equality and path equivalence have different semantics. \begin{itemize} \item Equality is determined by the \tcode{path} non-member \tcode{operator==}, which considers the two paths' lexical representations only. \begin{example} \tcode{path("foo") == "bar"} is never \tcode{true}. \end{example} \item Equivalence is determined by the \tcode{equivalent()} non-member function, which determines if two paths resolve\iref{fs.class.path} to the same file system entity. \begin{example} \tcode{equivalent("foo", "bar")} will be \tcode{true} when both paths resolve to the same file. \end{example} \end{itemize} \end{note} \end{itemdescr} \indexlibrarymember{operator<=>}{path}% \begin{itemdecl} friend strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{lhs.compare(rhs) <=> 0}. \end{itemdescr} \indexlibrarymember{operator/}{path}% \begin{itemdecl} friend path operator/(const path& lhs, const path& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return path(lhs) /= rhs;} \end{itemdescr} \rSec3[fs.path.fmtr]{Formatting support} \rSec4[fs.path.fmtr.general]{Formatting support overview} \indexlibraryglobal{formatter}% \begin{codeblock} namespace std { template struct formatter { constexpr void set_debug_format(); constexpr typename basic_format_parse_context::iterator parse(basic_format_parse_context& ctx); template typename FormatContext::iterator format(const filesystem::path& path, FormatContext& ctx) const; }; } \end{codeblock} \rSec4[fs.path.fmtr.funcs]{Formatting support functions} \pnum Formatting of paths uses formatting specifiers of the form \begin{ncbnf} \nontermdef{path-format-spec}\br \opt{fill-and-align} \opt{width} \opt{\terminal{?}} \opt{\terminal{g}} \end{ncbnf} where the productions \fmtgrammarterm{fill-and-align} and \fmtgrammarterm{width} are described in \ref{format.string}. If the \tcode{?} option is used then the path is formatted as an escaped string\iref{format.string.escaped}. \indexlibrarymember{formatter}{set_debug_format}% \begin{itemdecl} constexpr void set_debug_format(); \end{itemdecl} \begin{itemdescr} \pnum \effects Modifies the state of the \tcode{formatter} to be as if the \fmtgrammarterm{path-format-spec} parsed by the last call to \tcode{parse} contained the \tcode{?} option. \end{itemdescr} \indexlibrarymember{formatter}{basic_format_parse_context}% \begin{itemdecl} constexpr typename basic_format_parse_context::iterator parse(basic_format_parse_context& ctx); \end{itemdecl} \begin{itemdescr} \pnum \effects Parses the format specifier as a \fmtgrammarterm{path-format-spec} and stores the parsed specifiers in \tcode{*this}. \pnum \returns An iterator past the end of the \fmtgrammarterm{path-format-spec}. \end{itemdescr} \indexlibrarymember{formatter}{format}% \begin{itemdecl} template typename FormatContext::iterator format(const filesystem::path& p, FormatContext& ctx) const; \end{itemdecl} \begin{itemdescr} \pnum \effects Let \tcode{s} be \tcode{p.generic_string()} if the \tcode{g} option is used, otherwise \tcode{p.native()}. Writes \tcode{s} into \tcode{ctx.out()}, adjusted according to the \fmtgrammarterm{path-format-spec}. If \tcode{charT} is \keyword{char}, \tcode{path::value_type} is \keyword{wchar_t}, and the literal encoding is UTF-8, then the escaped path is transcoded from the native encoding for wide character strings to UTF-8 with maximal subparts of ill-formed subsequences substituted with \ucode{fffd} \uname{replacement character} per the Unicode Standard, Chapter 3.9 \ucode{fffd} Substitution in Conversion. If \tcode{charT} and \tcode{path::value_type} are the same then no transcoding is performed. Otherwise, transcoding is \impldef{transcoding of a formatted path when \tcode{charT} and \tcode{path::value_type} differ}. \pnum \returns An iterator past the end of the output range. \end{itemdescr} \rSec3[fs.path.hash]{Hash support} \begin{itemdecl} template<> struct hash; \end{itemdecl} \begin{itemdescr} \pnum For an object \tcode{p} of type \tcode{filesystem::path}, \tcode{hash()(p)} evaluates to the same result as \tcode{filesystem::hash_value(p)}. \end{itemdescr} \rSec2[fs.class.filesystem.error]{Class \tcode{filesystem_error}} \rSec3[fs.class.filesystem.error.general]{General} \indexlibraryglobal{filesystem_error}% \begin{codeblock} namespace std::filesystem { class filesystem_error : public system_error { public: filesystem_error(const string& what_arg, error_code ec); filesystem_error(const string& what_arg, const path& p1, error_code ec); filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec); const path& path1() const noexcept; const path& path2() const noexcept; const char* what() const noexcept override; }; } \end{codeblock} \pnum The class \tcode{filesystem_error} defines the type of objects thrown as exceptions to report file system errors from functions described in subclause~\ref{filesystems}. \rSec3[fs.filesystem.error.members]{Members} \pnum Constructors are provided that store zero, one, or two paths associated with an error. \indexlibraryctor{filesystem_error}% \begin{itemdecl} filesystem_error(const string& what_arg, error_code ec); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{code() == ec} is \tcode{true}, \item \tcode{path1().empty()} is \tcode{true}, \item \tcode{path2().empty()} is \tcode{true}, and \item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos} is \tcode{true}. \end{itemize} \end{itemdescr} \indexlibraryctor{filesystem_error}% \begin{itemdecl} filesystem_error(const string& what_arg, const path& p1, error_code ec); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{code() == ec} is \tcode{true}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, \item \tcode{path2().empty()} is \tcode{true}, and \item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos} is \tcode{true}. \end{itemize} \end{itemdescr} \indexlibraryctor{filesystem_error}% \begin{itemdecl} filesystem_error(const string& what_arg, const path& p1, const path& p2, error_code ec); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{code() == ec}, \item \tcode{path1()} returns a reference to the stored copy of \tcode{p1}, \item \tcode{path2()} returns a reference to the stored copy of \tcode{p2}, and \item \tcode{string_view(what()).find(what_arg.c_str())} \tcode{!= string_view::npos}. \end{itemize} \end{itemdescr} \indexlibrarymember{path1}{filesystem_error}% \begin{itemdecl} const path& path1() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A reference to the copy of \tcode{p1} stored by the constructor, or, if none, an empty path. \end{itemdescr} \indexlibrarymember{path2}{filesystem_error}% \begin{itemdecl} const path& path2() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns A reference to the copy of \tcode{p2} stored by the constructor, or, if none, an empty path. \end{itemdescr} \indexlibrarymember{what}{filesystem_error}% \begin{itemdecl} const char* what() const noexcept override; \end{itemdecl} \begin{itemdescr} \pnum \returns An \ntbs{} that incorporates the \tcode{what_arg} argument supplied to the constructor. The exact format is unspecified. Implementations should include the \tcode{system_error::what()} string and the pathnames of \tcode{path1} and \tcode{path2} in the native format in the returned string. \end{itemdescr} \rSec2[fs.enum]{Enumerations} \rSec3[fs.enum.path.format]{Enum \tcode{path::format}} \pnum This enum specifies constants used to identify the format of the character sequence, with the meanings listed in \tref{fs.enum.path.format}. \begin{floattable} {Enum \tcode{path::format}}{fs.enum.path.format}{lp{4in}} \topline \lhdr{Name} & \rhdr{Meaning} \\\capsep \tcode{native_format} & The native pathname format. \\\rowsep \tcode{generic_format} & The generic pathname format. \\\rowsep \tcode{auto_format} & The interpretation of the format of the character sequence is \impldef{interpretation of the path character sequence with format \tcode{path::auto_format}}. The implementation may inspect the content of the character sequence to determine the format. \recommended For POSIX-based systems, native and generic formats are equivalent and the character sequence should always be interpreted in the same way. \\ \end{floattable} \rSec3[fs.enum.file.type]{Enum class \tcode{file_type}} \indexlibraryglobal{file_type}% \pnum This enum class specifies constants used to identify file types, with the meanings listed in \tref{fs.enum.file.type}. The values of the constants are distinct. \begin{floattable} {Enum class \tcode{file_type}}{fs.enum.file.type} {lp{4.5in}} \topline \lhdr{Constant} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{file_type}} & The type of the file has not been determined or an error occurred while trying to determine the type. \\ \rowsep \tcode{\libmember{not_found}{file_type}} & Pseudo-type indicating the file was not found. \begin{tailnote} The file not being found is not considered an error while determining the type of a file. \end{tailnote} \\ \rowsep \tcode{\libmember{regular}{file_type}} & Regular file \\ \rowsep \tcode{\libmember{directory}{file_type}} & Directory file \\ \rowsep \tcode{\libmember{symlink}{file_type}} & Symbolic link file \\ \rowsep \tcode{\libmember{block}{file_type}} & Block special file \\ \rowsep \tcode{\libmember{character}{file_type}} & Character special file \\ \rowsep \tcode{\libmember{fifo}{file_type}} & FIFO or pipe file \\ \rowsep \tcode{\libmember{socket}{file_type}} & Socket file \\ \rowsep \tcode{\textit{\impldef{additional \tcode{file_type} enumerators for file systems supporting additional types of file}}} & Implementations that support file systems having file types in addition to the above \tcode{file_type} types shall supply \impldef{additional \tcode{file_type} enumerators for file systems supporting additional types of file} \tcode{file_type} constants to separately identify each of those additional file types \\ \rowsep \tcode{\libmember{unknown}{file_type}} & The file exists but the type cannot be determined \\ \end{floattable} \rSec3[fs.enum.copy.opts]{Enum class \tcode{copy_options}} \indexlibraryglobal{copy_options}% \pnum The \tcode{enum class} type \tcode{copy_options} is a bitmask type\iref{bitmask.types} that specifies bitmask constants used to control the semantics of copy operations. The constants are specified in option groups with the meanings listed in \tref{fs.enum.copy.opts}. The constant \tcode{none} represents the empty bitmask, and is shown in each option group for purposes of exposition; implementations shall provide only a single definition. Every other constant in the table represents a distinct bitmask element. \begin{floattable} {Enum class \tcode{copy_options}}{fs.enum.copy.opts} {lp{4in}} \topline \ohdrx{2}{Option group controlling \tcode{copy_file} function effects for existing target files} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{copy_options}} & (Default) Error; file already exists. \\ \rowsep \tcode{\libmember{skip_existing}{copy_options}} & Do not overwrite existing file, do not report an error. \\ \rowsep \tcode{\libmember{overwrite_existing}{copy_options}} & Overwrite the existing file. \\ \rowsep \tcode{\libmember{update_existing}{copy_options}} & Overwrite the existing file if it is older than the replacement file. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for subdirectories} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{copy_options}} & (Default) Do not copy subdirectories. \\ \rowsep \tcode{\libmember{recursive}{copy_options}} & Recursively copy subdirectories and their contents. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for symbolic links} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{copy_options}} & (Default) Follow symbolic links. \\ \rowsep \tcode{\libmember{copy_symlinks}{copy_options}} & Copy symbolic links as symbolic links rather than copying the files that they point to. \\ \rowsep \tcode{\libmember{skip_symlinks}{copy_options}} & Ignore symbolic links. \\ \capsep \ohdrx{2}{Option group controlling \tcode{copy} function effects for choosing the form of copying} \\ \rowsep \lhdr{Constant} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{copy_options}} & (Default) Copy content. \\ \rowsep \tcode{\libmember{directories_only}{copy_options}} & Copy directory structure only, do not copy non-directory files. \\ \rowsep \tcode{\libmember{create_symlinks}{copy_options}} & Make symbolic links instead of copies of files. The source path shall be an absolute path unless the destination path is in the current directory. \\ \rowsep \tcode{\libmember{create_hard_links}{copy_options}} & Make hard links instead of copies of files. \\ \end{floattable} \rSec3[fs.enum.perms]{Enum class \tcode{perms}} \indexlibraryglobal{perms}% \pnum The \tcode{enum class} type \tcode{perms} is a bitmask type\iref{bitmask.types} that specifies bitmask constants used to identify file permissions, with the meanings listed in \tref{fs.enum.perms}. \begin{floattable} {Enum class \tcode{perms}}{fs.enum.perms} {lrlp{3.2in}} \topline \lhdr{Name} & \chdr{Value} & \chdr{POSIX} & \rhdr{Definition or notes} \\ & \chdr{(octal)} & \chdr{macro} & \\ \capsep \tcode{\libmember{none}{perms}} & \tcode{0} & & There are no permissions set for the file. \\ \rowsep \tcode{\libmember{owner_read}{perms}} & \tcode{0400} & \tcode{S_IRUSR} & Read permission, owner \\ \rowsep \tcode{\libmember{owner_write}{perms}} & \tcode{0200} & \tcode{S_IWUSR} & Write permission, owner \\ \rowsep \tcode{\libmember{owner_exec}{perms}} & \tcode{0100} & \tcode{S_IXUSR} & Execute/search permission, owner \\ \rowsep \tcode{\libmember{owner_all}{perms}} & \tcode{0700} & \tcode{S_IRWXU} & Read, write, execute/search by owner;\br \tcode{owner_read | owner_write | owner_exec} \\ \rowsep \tcode{\libmember{group_read}{perms}} & \tcode{040} & \tcode{S_IRGRP} & Read permission, group \\ \rowsep \tcode{\libmember{group_write}{perms}} & \tcode{020} & \tcode{S_IWGRP} & Write permission, group \\ \rowsep \tcode{\libmember{group_exec}{perms}} & \tcode{010} & \tcode{S_IXGRP} & Execute/search permission, group \\ \rowsep \tcode{\libmember{group_all}{perms}} & \tcode{070} & \tcode{S_IRWXG} & Read, write, execute/search by group;\br \tcode{group_read | group_write | group_exec} \\ \rowsep \tcode{\libmember{others_read}{perms}} & \tcode{04} & \tcode{S_IROTH} & Read permission, others \\ \rowsep \tcode{\libmember{others_write}{perms}} & \tcode{02} & \tcode{S_IWOTH} & Write permission, others \\ \rowsep \tcode{\libmember{others_exec}{perms}} & \tcode{01} & \tcode{S_IXOTH} & Execute/search permission, others \\ \rowsep \tcode{\libmember{others_all}{perms}} & \tcode{07} & \tcode{S_IRWXO} & Read, write, execute/search by others;\br \tcode{others_read | others_write | others_exec} \\ \rowsep \tcode{\libmember{all}{perms}} & \tcode{0777} & & \tcode{owner_all | group_all | others_all} \\ \rowsep \tcode{\libmember{set_uid}{perms}} & \tcode{04000} & \tcode{S_ISUID} & Set-user-ID on execution \\ \rowsep \tcode{\libmember{set_gid}{perms}} & \tcode{02000} & \tcode{S_ISGID} & Set-group-ID on execution \\ \rowsep \tcode{\libmember{sticky_bit}{perms}} & \tcode{01000} & \tcode{S_ISVTX} & Operating system dependent. \\ \rowsep \tcode{\libmember{mask}{perms}} & \tcode{07777} & & \tcode{all | set_uid | set_gid | sticky_bit} \\ \rowsep \tcode{\libmember{unknown}{perms}} & \tcode{0xFFFF} & & The permissions are not known, such as when a \tcode{file_status} object is created without specifying the permissions \\ \end{floattable} \rSec3[fs.enum.perm.opts]{Enum class \tcode{perm_options}} \indexlibraryglobal{perm_options}% \pnum The \tcode{enum class} type \tcode{perm_options} is a bitmask type\iref{bitmask.types} that specifies bitmask constants used to control the semantics of permissions operations, with the meanings listed in \tref{fs.enum.perm.opts}. The bitmask constants are bitmask elements. In \tref{fs.enum.perm.opts} \tcode{perm} denotes a value of type \tcode{perms} passed to \tcode{permissions}. \begin{floattable} {Enum class \tcode{perm_options}}{fs.enum.perm.opts}{x{.15\hsize}x{.70\hsize}} \topline \lhdr{Name} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{replace}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with \tcode{perm} \\ \rowsep \tcode{\libmember{add}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with the bitwise \logop{or} of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{\libmember{remove}{perm_options}} & \tcode{permissions} shall replace the file's permission bits with the bitwise \logop{and} of the complement of \tcode{perm} and the file's current permission bits. \\ \rowsep \tcode{\libmember{nofollow}{perm_options}} & \tcode{permissions} shall change the permissions of a symbolic link itself rather than the permissions of the file the link resolves to. \\ \end{floattable} \rSec3[fs.enum.dir.opts]{Enum class \tcode{directory_options}} \indexlibraryglobal{directory_options}% \pnum The \tcode{enum class} type \tcode{directory_options} is a bitmask type\iref{bitmask.types} that specifies bitmask constants used to identify directory traversal options, with the meanings listed in \tref{fs.enum.dir.opts}. The constant \tcode{none} represents the empty bitmask; every other constant in the table represents a distinct bitmask element. \begin{floattable} {Enum class \tcode{directory_options}}{fs.enum.dir.opts} {lp{3in}} \topline \lhdr{Name} & \rhdr{Meaning} \\ \capsep \tcode{\libmember{none}{directory_options}} & (Default) Skip directory symlinks, permission denied is an error. \\ \rowsep \tcode{\libmember{follow_directory_symlink}{directory_options}} & Follow rather than skip directory symlinks. \\ \rowsep \tcode{\libmember{skip_permission_denied}{directory_options}} & Skip directories that would otherwise result in permission denied. \\ \end{floattable} \rSec2[fs.class.file.status]{Class \tcode{file_status}} \rSec3[fs.class.file.status.general]{General} \indexlibraryglobal{file_status}% \begin{codeblock} namespace std::filesystem { class file_status { public: // \ref{fs.file.status.cons}, constructors and destructor file_status() noexcept : file_status(file_type::none) {} explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; file_status(const file_status&) noexcept = default; file_status(file_status&&) noexcept = default; ~file_status(); // assignments file_status& operator=(const file_status&) noexcept = default; file_status& operator=(file_status&&) noexcept = default; // \ref{fs.file.status.mods}, modifiers void type(file_type ft) noexcept; void permissions(perms prms) noexcept; // \ref{fs.file.status.obs}, observers file_type type() const noexcept; perms permissions() const noexcept; friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } }; } \end{codeblock} \pnum An object of type \tcode{file_status} stores information about the type and permissions of a file. \rSec3[fs.file.status.cons]{Constructors} \indexlibraryctor{file_status}% \begin{itemdecl} explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{type() == ft} and \tcode{permissions() == prms}. \end{itemdescr} \rSec3[fs.file.status.obs]{Observers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} file_type type() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The value of \tcode{type()} specified by the postconditions of the most recent call to a constructor, \tcode{operator=}, or \tcode{type(file_type)} function. \end{itemdescr} \indexlibrarymember{permissions}{file_status}% \begin{itemdecl} perms permissions() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The value of \tcode{permissions()} specified by the postconditions of the most recent call to a constructor, \tcode{operator=}, or \tcode{permissions(perms)} function. \end{itemdescr} \rSec3[fs.file.status.mods]{Modifiers} \indexlibrarymember{type}{file_status}% \begin{itemdecl} void type(file_type ft) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{type() == ft}. \end{itemdescr} \indexlibrarymember{permissions}{file_status}% \begin{itemdecl} void permissions(perms prms) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{permissions() == prms}. \end{itemdescr} \rSec2[fs.class.directory.entry]{Class \tcode{directory_entry}} \rSec3[fs.class.directory.entry.general]{General} \indexlibraryglobal{directory_entry}% \begin{codeblock} namespace std::filesystem { class directory_entry { public: // \ref{fs.dir.entry.cons}, constructors and destructor directory_entry() noexcept = default; directory_entry(const directory_entry&) = default; directory_entry(directory_entry&&) noexcept = default; explicit directory_entry(const filesystem::path& p); directory_entry(const filesystem::path& p, error_code& ec); ~directory_entry(); // assignments directory_entry& operator=(const directory_entry&) = default; directory_entry& operator=(directory_entry&&) noexcept = default; // \ref{fs.dir.entry.mods}, modifiers void assign(const filesystem::path& p); void assign(const filesystem::path& p, error_code& ec); void replace_filename(const filesystem::path& p); void replace_filename(const filesystem::path& p, error_code& ec); void refresh(); void refresh(error_code& ec) noexcept; // \ref{fs.dir.entry.obs}, observers const filesystem::path& path() const noexcept; operator const filesystem::path&() const noexcept; bool exists() const; bool exists(error_code& ec) const noexcept; bool is_block_file() const; bool is_block_file(error_code& ec) const noexcept; bool is_character_file() const; bool is_character_file(error_code& ec) const noexcept; bool is_directory() const; bool is_directory(error_code& ec) const noexcept; bool is_fifo() const; bool is_fifo(error_code& ec) const noexcept; bool is_other() const; bool is_other(error_code& ec) const noexcept; bool is_regular_file() const; bool is_regular_file(error_code& ec) const noexcept; bool is_socket() const; bool is_socket(error_code& ec) const noexcept; bool is_symlink() const; bool is_symlink(error_code& ec) const noexcept; uintmax_t file_size() const; uintmax_t file_size(error_code& ec) const noexcept; uintmax_t hard_link_count() const; uintmax_t hard_link_count(error_code& ec) const noexcept; file_time_type last_write_time() const; file_time_type last_write_time(error_code& ec) const noexcept; file_status status() const; file_status status(error_code& ec) const noexcept; file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept; bool operator==(const directory_entry& rhs) const noexcept; strong_ordering operator<=>(const directory_entry& rhs) const noexcept; // \ref{fs.dir.entry.io}, inserter template friend basic_ostream& operator<<(basic_ostream& os, const directory_entry& d); private: filesystem::path @\exposid{path-object}@; // \expos }; } \end{codeblock} \pnum \indextext{file attributes}% A \tcode{directory_entry} object stores a \tcode{path} object and may store additional objects for file attributes such as hard link count, status, symlink status, file size, and last write time. \pnum Implementations should store such additional file attributes during directory iteration if their values are available and storing the values would allow the implementation to eliminate file system accesses by \tcode{directory_entry} observer functions\iref{fs.op.funcs}. Such stored file attribute values are said to be \defnx{cached}{file attributes!cached}. \pnum \begin{note} \tcode{directory_iterator} can cache already available attribute values directly into a \tcode{directory_entry} object without the cost of a call to \tcode{refresh()}. \end{note} \pnum \begin{example} \begin{codeblock} using namespace std::filesystem; // use possibly cached last write time to minimize disk accesses for (auto&& x : directory_iterator(".")) { std::cout << x.path() << " " << x.last_write_time() << std::endl; } // call \tcode{refresh()} to refresh a stale cache for (auto&& x : directory_iterator(".")) { lengthy_function(x.path()); // cache becomes stale x.refresh(); std::cout << x.path() << " " << x.last_write_time() << std::endl; } \end{codeblock} On implementations that do not cache the last write time, both loops will result in a potentially expensive call to the \tcode{std::filesystem::last_write_time} function. % On implementations that do cache the last write time, the first loop will use the cached value and so will not result in a potentially expensive call to the \tcode{std::filesystem::last_write_time} function. % The code is portable to any implementation, regardless of whether or not it employs caching. \end{example} \rSec3[fs.dir.entry.cons]{Constructors} \indexlibraryctor{directory_entry}% \begin{itemdecl} explicit directory_entry(const filesystem::path& p); directory_entry(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{refresh()} or \tcode{refresh(ec)}, respectively. \pnum \ensures \tcode{path() == p} if no error occurs, otherwise \tcode{path() == filesystem::path()}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.dir.entry.mods]{Modifiers} \indexlibrarymember{assign}{directory_entry}% \begin{itemdecl} void assign(const filesystem::path& p); void assign(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{\exposid{path-object} = p}, then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. If an error occurs, the values of any cached attributes are unspecified. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{replace_filename}{directory_entry}% \begin{itemdecl} void replace_filename(const filesystem::path& p); void replace_filename(const filesystem::path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{\exposid{path-object}.replace_filename(p)}, then \tcode{refresh()} or \tcode{refresh(ec)}, respectively. If an error occurs, the values of any cached attributes are unspecified. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{refresh}{directory_entry}% \begin{itemdecl} void refresh(); void refresh(error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Stores the current values of any cached attributes of the file \tcode{p} resolves to. If an error occurs, an error is reported\iref{fs.err.report} and the values of any cached attributes are unspecified. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} Implementations of \tcode{directory_iterator}\iref{fs.class.directory.iterator} are prohibited from directly or indirectly calling the \tcode{refresh} function as described in \ref{fs.class.directory.iterator.general}. \end{note} \end{itemdescr} \rSec3[fs.dir.entry.obs]{Observers} \pnum Unqualified function names in the \returns elements of the \tcode{directory_entry} observers described below refer to members of the \tcode{std::filesystem} namespace. \indexlibrarymember{path}{directory_entry}% \indexlibrarymember{operator const filesystem::path\&}{directory_entry}% \begin{itemdecl} const filesystem::path& path() const noexcept; operator const filesystem::path&() const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \exposid{path-object}. \end{itemdescr} \indexlibrarymember{exists}{directory_entry}% \begin{itemdecl} bool exists() const; bool exists(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{exists(this->status())} or \tcode{exists(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_block_file}{directory_entry}% \begin{itemdecl} bool is_block_file() const; bool is_block_file(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_block_file(this->status())} or \tcode{is_block_file(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_character_file}{directory_entry}% \begin{itemdecl} bool is_character_file() const; bool is_character_file(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_character_file(this->status())} or \tcode{is_character_file(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_directory}{directory_entry}% \begin{itemdecl} bool is_directory() const; bool is_directory(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_directory(this->status())} or \tcode{is_directory(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_fifo}{directory_entry}% \begin{itemdecl} bool is_fifo() const; bool is_fifo(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_fifo(this->status())} or \tcode{is_fifo(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_other}{directory_entry}% \begin{itemdecl} bool is_other() const; bool is_other(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_other(this->status())} or \tcode{is_other(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_regular_file}{directory_entry}% \begin{itemdecl} bool is_regular_file() const; bool is_regular_file(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_regular_file(this->status())} or \tcode{is_regular_file(this->status(ec))}, respective\-ly. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_socket}{directory_entry}% \begin{itemdecl} bool is_socket() const; bool is_socket(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_socket(this->status())} or \tcode{is_socket(this->status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{is_symlink}{directory_entry}% \begin{itemdecl} bool is_symlink() const; bool is_symlink(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_symlink(this->symlink_status())} or \tcode{is_symlink(this->symlink_status(ec))}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{file_size}{directory_entry}% \begin{itemdecl} uintmax_t file_size() const; uintmax_t file_size(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If cached, the file size attribute value. Otherwise, \tcode{file_size(path())} or \tcode{file_size(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{hard_link_count}{directory_entry}% \begin{itemdecl} uintmax_t hard_link_count() const; uintmax_t hard_link_count(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If cached, the hard link count attribute value. Otherwise, \tcode{hard_link_count(path())} or \tcode{hard_link_count(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{last_write_time}{directory_entry}% \begin{itemdecl} file_time_type last_write_time() const; file_time_type last_write_time(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If cached, the last write time attribute value. Otherwise, \tcode{last_write_time(path())} or \tcode{last_write_time(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{status}{directory_entry}% \begin{itemdecl} file_status status() const; file_status status(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If cached, the status attribute value. Otherwise, \tcode{status(path())} or \tcode{status(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{symlink_status}{directory_entry}% \begin{itemdecl} file_status symlink_status() const; file_status symlink_status(error_code& ec) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns If cached, the symlink status attribute value. Otherwise, \tcode{symlink_status(path())} or \tcode{symlink_status(path(), ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{operator==}{directory_entry}% \begin{itemdecl} bool operator==(const directory_entry& rhs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{path-object} == rhs.\exposid{path-object}}. \end{itemdescr} \indexlibrarymember{operator<=>}{directory_entry}% \begin{itemdecl} strong_ordering operator<=>(const directory_entry& rhs) const noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{\exposid{path-object} <=> rhs.\exposid{path-object}}. \end{itemdescr} \rSec3[fs.dir.entry.io]{Inserter} \indexlibrarymember{operator<<}{directory_entry}% \begin{itemdecl} template friend basic_ostream& operator<<(basic_ostream& os, const directory_entry& d); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to: \tcode{return os << d.path();} \end{itemdescr} \rSec2[fs.class.directory.iterator]{Class \tcode{directory_iterator}} \rSec3[fs.class.directory.iterator.general]{General} \indexlibraryglobal{directory_iterator}% \pnum An object of type \tcode{directory_iterator} provides an iterator for a sequence of \tcode{directory_entry} elements representing the path and any cached attribute values\iref{fs.class.directory.entry} for each file in a directory or in an \impldef{type of a directory-like file} directory-like file type. \begin{note} For iteration into subdirectories, see class \tcode{recursive_directory_iterator}\iref{fs.class.rec.dir.itr}. \end{note} \begin{codeblock} namespace std::filesystem { class directory_iterator { public: using iterator_category = input_iterator_tag; using value_type = directory_entry; using difference_type = ptrdiff_t; using pointer = const directory_entry*; using reference = const directory_entry&; // \ref{fs.dir.itr.members}, member functions directory_iterator() noexcept; explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec); directory_iterator(const path& p, directory_options options, error_code& ec); directory_iterator(const directory_iterator& rhs); directory_iterator(directory_iterator&& rhs) noexcept; ~directory_iterator(); directory_iterator& operator=(const directory_iterator& rhs); directory_iterator& operator=(directory_iterator&& rhs) noexcept; const directory_entry& operator*() const; const directory_entry* operator->() const; directory_iterator& operator++(); directory_iterator& increment(error_code& ec); bool operator==(default_sentinel_t) const noexcept { return *this == directory_iterator(); } // other members as required by \ref{input.iterators}, input iterators }; } \end{codeblock} \pnum \tcode{directory_iterator} meets the \oldconcept{InputIterator} requirements\iref{input.iterators}. \pnum If an iterator of type \tcode{directory_iterator} reports an error or is advanced past the last directory element, that iterator shall become equal to the end iterator value. The \tcode{directory_iterator} default constructor shall create an iterator equal to the end iterator value, and this shall be the only valid iterator for the end condition. \pnum The end iterator is not dereferenceable. \pnum Two end iterators are always equal. An end iterator shall not be equal to a non-end iterator. \pnum The result of calling the \tcode{path()} member of the \tcode{directory_entry} object obtained by dereferencing a \tcode{directory_iterator} is a reference to a \tcode{path} object composed of the directory argument from which the iterator was constructed with the filename of the directory entry appended as if by \tcode{operator/=}. \pnum Directory iteration shall not yield directory entries for the current (dot) and parent (dot-dot) directories. \pnum The order of directory entries obtained by dereferencing successive increments of a \tcode{directory_iterator} is unspecified. \pnum Constructors and non-const \tcode{directory_iterator} member functions store the values of any cached attributes\iref{fs.class.directory.entry} in the \tcode{directory_entry} element returned by \tcode{operator*()}. \tcode{directory_iterator} member functions shall not directly or indirectly call any \tcode{directory_entry} \tcode{refresh} function. \begin{note} The exact mechanism for storing cached attribute values is not exposed to users. \end{note} \pnum \begin{note} A path obtained by dereferencing a directory iterator might not actually exist; it could be a symbolic link to a non-existent file. Recursively walking directory trees for purposes of removing and renaming entries might invalidate symbolic links that are being followed. \end{note} \pnum \begin{note} If a file is removed from or added to a directory after the construction of a \tcode{directory_iterator} for the directory, it is unspecified whether or not subsequently incrementing the iterator will ever result in an iterator referencing the removed or added directory entry. See POSIX \tcode{readdir}. \end{note} \rSec3[fs.dir.itr.members]{Members} \indexlibraryctor{directory_iterator}% \begin{itemdecl} directory_iterator() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs the end iterator. \end{itemdescr} \indexlibraryctor{directory_iterator}% \begin{itemdecl} explicit directory_iterator(const path& p); directory_iterator(const path& p, directory_options options); directory_iterator(const path& p, error_code& ec); directory_iterator(const path& p, directory_options options, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects For the directory that \tcode{p} resolves to, constructs an iterator for the first element in a sequence of \tcode{directory_entry} elements representing the files in the directory, if any; otherwise the end iterator. However, if \begin{codeblock} (options & directory_options::skip_permission_denied) != directory_options::none \end{codeblock} and construction encounters an error indicating that permission to access \tcode{p} is denied, constructs the end iterator and does not report an error. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} To iterate over the current directory, use \tcode{directory_iterator(".")} rather than \tcode{directory_iterator("")}. \end{note} \end{itemdescr} \indexlibraryctor{directory_iterator}% \begin{itemdecl} directory_iterator(const directory_iterator& rhs); directory_iterator(directory_iterator&& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{*this} has the original value of \tcode{rhs}. \end{itemdescr} \indexlibrarymember{operator=}{directory_iterator}% \begin{itemdecl} directory_iterator& operator=(const directory_iterator& rhs); directory_iterator& operator=(directory_iterator&& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{rhs} are the same object, the member has no effect. \pnum \ensures \tcode{*this} has the original value of \tcode{rhs}. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{increment}{directory_iterator}% \indexlibrarymember{operator++}{directory_iterator}% \begin{itemdecl} directory_iterator& operator++(); directory_iterator& increment(error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects As specified for the prefix increment operation of Input iterators\iref{input.iterators}. \pnum \returns \tcode{*this}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.dir.itr.nonmembers]{Non-member functions} \pnum These functions enable range access for \tcode{directory_iterator}. \indexlibrarymember{begin}{directory_iterator}% \begin{itemdecl} directory_iterator begin(directory_iterator iter) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{iter}. \end{itemdescr} \indexlibrarymember{end}{directory_iterator}% \begin{itemdecl} directory_iterator end(directory_iterator) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{directory_iterator()}. \end{itemdescr} \rSec2[fs.class.rec.dir.itr]{Class \tcode{recursive_directory_iterator}} \rSec3[fs.class.rec.dir.itr.general]{General} \indexlibraryglobal{recursive_directory_iterator}% \pnum An object of type \tcode{recursive_directory_iterator} provides an iterator for a sequence of \tcode{directory_entry} elements representing the files in a directory or in an \impldef{type of a directory-like file} directory-like file type, and its subdirectories. \begin{codeblock} namespace std::filesystem { class recursive_directory_iterator { public: using iterator_category = input_iterator_tag; using value_type = directory_entry; using difference_type = ptrdiff_t; using pointer = const directory_entry*; using reference = const directory_entry&; // \ref{fs.rec.dir.itr.members}, constructors and destructor recursive_directory_iterator() noexcept; explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec); recursive_directory_iterator(const path& p, error_code& ec); recursive_directory_iterator(const recursive_directory_iterator& rhs); recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; ~recursive_directory_iterator(); // \ref{fs.rec.dir.itr.members}, observers directory_options options() const; int depth() const; bool recursion_pending() const; const directory_entry& operator*() const; const directory_entry* operator->() const; // \ref{fs.rec.dir.itr.members}, modifiers recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec); void pop(); void pop(error_code& ec); void disable_recursion_pending(); bool operator==(default_sentinel_t) const noexcept { return *this == recursive_directory_iterator(); } // other members as required by \ref{input.iterators}, input iterators }; } \end{codeblock} \pnum Calling \tcode{options}, \tcode{depth}, \tcode{recursion_pending}, \tcode{pop} or \tcode{disable_recursion_pending} on an iterator that is not dereferenceable results in undefined behavior. \pnum The behavior of a \tcode{recursive_directory_iterator} is the same as a \tcode{directory_iterator} unless otherwise specified. \pnum \begin{note} If the directory structure being iterated over contains cycles then it is possible that the end iterator is unreachable. \end{note} \rSec3[fs.rec.dir.itr.members]{Members} \indexlibraryctor{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator() noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs the end iterator. \end{itemdescr} \indexlibraryctor{recursive_directory_iterator}% \begin{itemdecl} explicit recursive_directory_iterator(const path& p); recursive_directory_iterator(const path& p, directory_options options); recursive_directory_iterator(const path& p, directory_options options, error_code& ec); recursive_directory_iterator(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Constructs an iterator representing the first entry in the directory to which \tcode{p} resolves, if any; otherwise, the end iterator. However, if \begin{codeblock} (options & directory_options::skip_permission_denied) != directory_options::none \end{codeblock} and construction encounters an error indicating that permission to access \tcode{p} is denied, constructs the end iterator and does not report an error. \pnum \ensures \tcode{options() == options} for the signatures with a \tcode{directory_options} argument, otherwise \tcode{options() == directory_options::none}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} Use \tcode{recursive_directory_iterator(".")} rather than \tcode{recursive_directory_iterator("")} to iterate over the current directory. \end{note} \pnum \begin{note} By default, \tcode{recursive_directory_iterator} does not follow directory symlinks. To follow directory symlinks, specify \tcode{options} as \tcode{directory_options::follow_directory_symlink}. \end{note} \end{itemdescr} \indexlibraryctor{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator(const recursive_directory_iterator& rhs); \end{itemdecl} \begin{itemdescr} \pnum \ensures \begin{itemize} \item \tcode{options() == rhs.options()} \item \tcode{depth() == rhs.depth()} \item \tcode{recursion_pending() == rhs.recursion_pending()} \end{itemize} \end{itemdescr} \indexlibraryctor{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{options()}, \tcode{depth()}, and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. \end{itemdescr} \indexlibrarymember{operator=}{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{rhs} are the same object, the member has no effect. \pnum \ensures \begin{itemize} \item \tcode{options() == rhs.options()} \item \tcode{depth() == rhs.depth()} \item \tcode{recursion_pending() == rhs.recursion_pending()} \end{itemize} \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{operator=}{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{*this} and \tcode{rhs} are the same object, the member has no effect. \pnum \ensures \tcode{options()}, \tcode{depth()}, and \tcode{recursion_pending()} have the values that \tcode{rhs.options()}, \tcode{rhs.depth()}, and \tcode{rhs.recursion_pending()}, respectively, had before the function call. \pnum \returns \tcode{*this}. \end{itemdescr} \indexlibrarymember{options}{recursive_directory_iterator}% \begin{itemdecl} directory_options options() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The value of the argument passed to the constructor for the \tcode{options} parameter, if present, otherwise \tcode{directory_options::none}. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{depth}{recursive_directory_iterator}% \begin{itemdecl} int depth() const; \end{itemdecl} \begin{itemdescr} \pnum \returns The current depth of the directory tree being traversed. \begin{note} The initial directory is depth \tcode{0}, its immediate subdirectories are depth \tcode{1}, and so forth. \end{note} \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{recursion_pending}{recursive_directory_iterator}% \begin{itemdecl} bool recursion_pending() const; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{true} if \tcode{disable_recursion_pending()} has not been called subsequent to the prior construction or increment operation, otherwise \tcode{false}. \pnum \throws Nothing. \end{itemdescr} \indexlibrarymember{increment}{recursive_directory_iterator}% \indexlibrarymember{operator++}{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator& operator++(); recursive_directory_iterator& increment(error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects As specified for the prefix increment operation of Input iterators\iref{input.iterators}, except that: \begin{itemize} \item If there are no more entries at the current depth, then if \tcode{depth() != 0} iteration over the parent directory resumes; otherwise \tcode{*this = recursive_directory_iterator()}. \item Otherwise if \begin{codeblock} recursion_pending() && is_directory((*this)->status()) && (!is_symlink((*this)->symlink_status()) || (options() & directory_options::follow_directory_symlink) != directory_options::none) \end{codeblock} then either directory \tcode{(*this)->path()} is recursively iterated into or, if \begin{codeblock} (options() & directory_options::skip_permission_denied) != directory_options::none \end{codeblock} and an error occurs indicating that permission to access directory \tcode{(*this)->path()} is denied, then directory \tcode{(*this)->path()} is treated as an empty directory and no error is reported. \end{itemize} \pnum \returns \tcode{*this}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibrarymember{pop}{recursive_directory_iterator}% \begin{itemdecl} void pop(); void pop(error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{depth() == 0}, set \tcode{*this} to \tcode{recursive_directory_iterator()}. Otherwise, cease iteration of the directory currently being iterated over, and continue iteration over the parent directory. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \pnum \remarks Any copies of the previous value of \tcode{*this} are no longer required to be dereferenceable nor to be in the domain of \tcode{==}. \indexlibrarymember{disable_recursion_pending}{recursive_directory_iterator}% \begin{itemdecl} void disable_recursion_pending(); \end{itemdecl} \begin{itemdescr} \pnum \ensures \tcode{recursion_pending() == false}. \pnum \begin{note} \tcode{disable_recursion_pending}\tcode{()} is used to prevent unwanted recursion into a directory. \end{note} \end{itemdescr} \rSec3[fs.rec.dir.itr.nonmembers]{Non-member functions} \pnum These functions enable use of \tcode{recursive_directory_iterator} with range-based \keyword{for} statements. \indexlibrarymember{begin}{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{iter}. \end{itemdescr} \indexlibrarymember{end}{recursive_directory_iterator}% \begin{itemdecl} recursive_directory_iterator end(recursive_directory_iterator) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{recursive_directory_iterator()}. \end{itemdescr} \rSec2[fs.op.funcs]{Filesystem operation functions} \rSec3[fs.op.funcs.general]{General} \pnum Filesystem operation functions query or modify files, including directories, in external storage. \pnum \begin{note} Because hardware failures, network failures, file system races\iref{fs.race.behavior}, and many other kinds of errors occur frequently in file system operations, any filesystem operation function, no matter how apparently innocuous, can encounter an error; see~\ref{fs.err.report}. \end{note} \rSec3[fs.op.absolute]{Absolute} \indexlibraryglobal{absolute}% \begin{itemdecl} path filesystem::absolute(const path& p); path filesystem::absolute(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Composes an absolute path referencing the same file system location as \tcode{p} according to the operating system\iref{fs.conform.os}. \pnum \returns The composed path. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum \begin{note} For the returned path, \tcode{rp}, \tcode{rp.is_absolute()} is \tcode{true} unless an error occurs. \end{note} \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} To resolve symlinks or perform other sanitization that can involve queries to secondary storage, such as hard disks, consider \tcode{canonical}\iref{fs.op.canonical}. \end{note} \pnum \begin{note} Implementations are strongly encouraged to not query secondary storage, and not consider \tcode{!exists(p)} an error. \end{note} \pnum \begin{example} For POSIX-based operating systems, \tcode{absolute(p)} is simply \tcode{current_path()/p}. For Windows-based operating systems, \tcode{absolute} might have the same semantics as \tcode{GetFullPathNameW}. \end{example} \end{itemdescr} \rSec3[fs.op.canonical]{Canonical} \indexlibraryglobal{canonical}% \begin{itemdecl} path filesystem::canonical(const path& p); path filesystem::canonical(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Converts \tcode{p} to an absolute path that has no symbolic link, dot, or dot-dot elements in its pathname in the generic format. \pnum \returns A path that refers to the same file system object as \tcode{absolute(p)}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks \tcode{!exists(p)} is an error. \end{itemdescr} \rSec3[fs.op.copy]{Copy} \indexlibrarymember{copy}{path}% \begin{itemdecl} void filesystem::copy(const path& from, const path& to); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{copy(from, to, copy_options::none)}. \end{itemdescr} \indexlibrarymember{copy}{path}% \begin{itemdecl} void filesystem::copy(const path& from, const path& to, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{copy(from, to, copy_options::none, ec)}. \end{itemdescr} \indexlibrarymember{copy}{path}% \begin{itemdecl} void filesystem::copy(const path& from, const path& to, copy_options options); void filesystem::copy(const path& from, const path& to, copy_options options, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \expects At most one element from each option group\iref{fs.enum.copy.opts} is set in \tcode{options}. \pnum \effects Before the first use of \tcode{f} and \tcode{t}: \begin{itemize} \item If \begin{codeblock} (options & copy_options::create_symlinks) != copy_options::none || (options & copy_options::skip_symlinks) != copy_options::none \end{codeblock} then \tcode{auto f = symlink_status(from)} and if needed \tcode{auto t = symlink_status(to)}. \item Otherwise, if \begin{codeblock} (options & copy_options::copy_symlinks) != copy_options::none \end{codeblock} then \tcode{auto f = symlink_status(from)} and if needed \tcode{auto t = status(to)}. \item Otherwise, \tcode{auto f = status(from)} and if needed \tcode{auto t = status(to)}. \end{itemize} Effects are then as follows: \begin{itemize} \item If \tcode{f.type()} or \tcode{t.type()} is an implementation-defined file type\iref{fs.enum.file.type}, then the effects are \impldef{effect of \tcode{filesystem::copy}}. \item Otherwise, an error is reported as specified in~\ref{fs.err.report} if \begin{itemize} \item \tcode{exists(f)} is \tcode{false}, or \item \tcode{equivalent(from, to)} is \tcode{true}, or \item \tcode{is_other(f) || is_other(t)} is \tcode{true}, or \item \tcode{is_directory(f) \&\& is_regular_file(t)} is \tcode{true}. \end{itemize} \item Otherwise, if \tcode{is_symlink(f)}, then: \begin{itemize} \item If \tcode{(options \& copy_options::skip_symlinks) != copy_options::none} then return. \item Otherwise if \begin{codeblock} !exists(t) && (options & copy_options::copy_symlinks) != copy_options::none \end{codeblock} then \tcode{copy_symlink(from, to)}. \item Otherwise report an error as specified in~\ref{fs.err.report}. \end{itemize} \item Otherwise, if \tcode{is_regular_file(f)}, then: \begin{itemize} \item If \tcode{(options \& copy_options::directories_only) != copy_options::none}, then return. \item Otherwise, if \tcode{(options \& copy_options::create_symlinks) \: != copy_options::none}, then create a symbolic link to the source file. \item Otherwise, if \tcode{(options \& copy_options::create_hard_links) != copy_options::none}, then create a hard link to the source file. \item Otherwise, if \tcode{is_directory(t)}, then \tcode{copy_file(from, to/from.filename(), options)}. \item Otherwise, \tcode{copy_file(from, to, options)}. \end{itemize} \item Otherwise, if \begin{codeblock} is_directory(f) && (options & copy_options::create_symlinks) != copy_options::none \end{codeblock} then report an error with an \tcode{error_code} argument equal to \tcode{make_error_code(errc::is_a_directory)}. \item Otherwise, if \begin{codeblock} is_directory(f) && ((options & copy_options::recursive) != copy_options::none || options == copy_options::none) \end{codeblock} then: \begin{itemize} \item If \tcode{exists(t)} is \tcode{false}, then \tcode{create_directory(to, from)}. \item Then, iterate over the files in \tcode{from}, as if by \begin{codeblock} for (const directory_entry& x : directory_iterator(from)) copy(x.path(), to/x.path().filename(), options | copy_options::@\placeholder{in-recursive-copy}@); \end{codeblock} where \tcode{\placeholder{in-recursive-copy}} is a bitmask element of \tcode{copy_options} that is not one of the elements in~\ref{fs.enum.copy.opts}. \end{itemize} \item Otherwise, for the signature with argument \tcode{ec}, \tcode{ec.clear()}. \item Otherwise, no effects. \end{itemize} \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks For the signature with argument \tcode{ec}, any library functions called by the implementation shall have an \tcode{error_code} argument if applicable. \pnum \begin{example} Given this directory structure: \begin{codeblock} /dir1 file1 file2 dir2 file3 \end{codeblock} Calling \tcode{copy("/dir1", "/dir3")} would result in: \begin{codeblock} /dir1 file1 file2 dir2 file3 /dir3 file1 file2 \end{codeblock} Alternatively, calling \tcode{copy("/dir1", "/dir3", copy_options::recursive)} would result in: \begin{codeblock} /dir1 file1 file2 dir2 file3 /dir3 file1 file2 dir2 file3 \end{codeblock} \end{example} \end{itemdescr} \rSec3[fs.op.copy.file]{Copy file} \indexlibraryglobal{copy_file}% \begin{itemdecl} bool filesystem::copy_file(const path& from, const path& to); bool filesystem::copy_file(const path& from, const path& to, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{copy_file(from, to, copy_options::none)} or\\ \tcode{copy_file(from, to, copy_options::none, ec)}, respectively. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibraryglobal{copy_file}% \begin{itemdecl} bool filesystem::copy_file(const path& from, const path& to, copy_options options); bool filesystem::copy_file(const path& from, const path& to, copy_options options, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \expects At most one element from each option group\iref{fs.enum.copy.opts} is set in \tcode{options}. \pnum \effects As follows: \begin{itemize} \item Report an error as specified in~\ref{fs.err.report} if \begin{itemize} \item \tcode{is_regular_file(from)} is \tcode{false}, or \item \tcode{exists(to)} is \tcode{true} and \tcode{is_regular_file(to)} is \tcode{false}, or \item \tcode{exists(to)} is \tcode{true} and \tcode{equivalent(from, to)} is \tcode{true}, or \item \tcode{exists(to)} is \tcode{true} and \begin{codeblock} (options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none \end{codeblock} \end{itemize} \item Otherwise, copy the contents and attributes of the file \tcode{from} resolves to, to the file \tcode{to} resolves to, if \begin{itemize} \item \tcode{exists(to)} is \tcode{false}, or \item \tcode{(options \& copy_options::overwrite_existing) != copy_options::none}, or \item \tcode{(options \& copy_options::update_existing) \: \: != copy_options::none} and \tcode{from} is more recent than \tcode{to}, determined as if by use of the \tcode{last_write_time} function\iref{fs.op.last.write.time}. \end{itemize} \item Otherwise, no effects. \end{itemize} \pnum \returns \tcode{true} if the \tcode{from} file was copied, otherwise \tcode{false}. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \complexity At most one direct or indirect invocation of \tcode{status(to)}. \end{itemdescr} \rSec3[fs.op.copy.symlink]{Copy symlink} \indexlibraryglobal{copy_symlink}% \begin{itemdecl} void filesystem::copy_symlink(const path& existing_symlink, const path& new_symlink); void filesystem::copy_symlink(const path& existing_symlink, const path& new_symlink, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Equivalent to \tcode{\textit{function}(read_symlink(existing_symlink), new_symlink)} or\\ \tcode{\textit{function}(read_symlink(existing_symlink, ec), new_symlink, ec)}, respectively, where in each case \tcode{\textit{function}} is \tcode{create_symlink} or \tcode{create_directory_symlink} as appropriate. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.create.directories]{Create directories} \indexlibraryglobal{create_directories}% \begin{itemdecl} bool filesystem::create_directories(const path& p); bool filesystem::create_directories(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Calls \tcode{create_directory()} for each element of \tcode{p} that does not exist. \pnum \returns \tcode{true} if a new directory was created for the directory \tcode{p} resolves to, otherwise \tcode{false}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \complexity \bigoh{n} where \textit{n} is the number of elements of \tcode{p}. \end{itemdescr} \rSec3[fs.op.create.directory]{Create directory} \indexlibraryglobal{create_directory}% \begin{itemdecl} bool filesystem::create_directory(const path& p); bool filesystem::create_directory(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Creates the directory \tcode{p} resolves to, as if by POSIX \tcode{mkdir} with a second argument of \tcode{static_cast(perms::all)}. If \tcode{mkdir} fails because \tcode{p} resolves to an existing directory, no error is reported. Otherwise on failure an error is reported. \pnum \returns \tcode{true} if a new directory was created, otherwise \tcode{false}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibraryglobal{create_directory}% \begin{itemdecl} bool filesystem::create_directory(const path& p, const path& existing_p); bool filesystem::create_directory(const path& p, const path& existing_p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Creates the directory \tcode{p} resolves to, with attributes copied from directory \tcode{existing_p}. The set of attributes copied is operating system dependent. If \tcode{mkdir} fails because \tcode{p} resolves to an existing directory, no error is reported. Otherwise on failure an error is reported. \begin{note} For POSIX-based operating systems, the attributes are those copied by native API \tcode{stat(existing_p.c_str(), \&attributes_stat)} followed by \tcode{mkdir(p.c_str(), attributes_stat.st_mode)}. For Windows-based operating systems, the attributes are those copied by native API \tcode{CreateDirectoryExW(existing_p.c_str(), p.c_str(), 0)}. \end{note} \pnum \returns \tcode{true} if a new directory was created with attributes copied from directory \tcode{existing_p}, otherwise \tcode{false}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.create.dir.symlk]{Create directory symlink} \indexlibraryglobal{create_directory_symlink}% \begin{itemdecl} void filesystem::create_directory_symlink(const path& to, const path& new_symlink); void filesystem::create_directory_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Establishes the postcondition, as if by POSIX \tcode{symlink()}. \pnum \ensures \tcode{new_symlink} resolves to a symbolic link file that contains an unspecified representation of \tcode{to}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} Some operating systems require symlink creation to identify that the link is to a directory. Thus, \tcode{create_symlink()} (instead of \tcode{create_directory_symlink()}) cannot be used reliably to create directory symlinks. \end{note} \pnum \begin{note} Some operating systems do not support symbolic links at all or support them only for regular files. Some file systems (such as the FAT file system) do not support symbolic links regardless of the operating system. \end{note} \end{itemdescr} \rSec3[fs.op.create.hard.lk]{Create hard link} \indexlibraryglobal{create_hard_link}% \begin{itemdecl} void filesystem::create_hard_link(const path& to, const path& new_hard_link); void filesystem::create_hard_link(const path& to, const path& new_hard_link, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Establishes the postcondition, as if by POSIX \tcode{link()}. \pnum \ensures \begin{itemize} \item \tcode{exists(to) \&\& exists(new_hard_link) \&\& equivalent(to, new_hard_link)} \item The contents of the file or directory \tcode{to} resolves to are unchanged. \end{itemize} \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} Some operating systems do not support hard links at all or support them only for regular files. Some file systems (such as the FAT file system) do not support hard links regardless of the operating system. Some file systems limit the number of links per file. \end{note} \end{itemdescr} \rSec3[fs.op.create.symlink]{Create symlink} \indexlibraryglobal{create_symlink}% \begin{itemdecl} void filesystem::create_symlink(const path& to, const path& new_symlink); void filesystem::create_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Establishes the postcondition, as if by POSIX \tcode{symlink()}. \pnum \ensures \tcode{new_symlink} resolves to a symbolic link file that contains an unspecified representation of \tcode{to}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} Some operating systems do not support symbolic links at all or support them only for regular files. Some file systems (such as the FAT file system) do not support symbolic links regardless of the operating system. \end{note} \end{itemdescr} \rSec3[fs.op.current.path]{Current path} \indexlibraryglobal{current_path}% \begin{itemdecl} path filesystem::current_path(); path filesystem::current_path(error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns The absolute path of the current working directory, whose pathname in the native format is obtained as if by POSIX \tcode{getcwd()}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks The current working directory is the directory, associated with the process, that is used as the starting location in pathname resolution for relative paths. \pnum \begin{note} The \tcode{current_path()} name was chosen to emphasize that the returned value is a path, not just a single directory name. \end{note} \pnum \begin{note} The current path as returned by many operating systems is a dangerous global variable and can be changed unexpectedly by third-party or system library functions, or by another thread. \end{note} \end{itemdescr} \indexlibraryglobal{current_path}% \begin{itemdecl} void filesystem::current_path(const path& p); void filesystem::current_path(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Establishes the postcondition, as if by POSIX \tcode{chdir()}. \pnum \ensures \tcode{equivalent(p, current_path())}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} The current path for many operating systems is a dangerous global state and can be changed unexpectedly by third-party or system library functions, or by another thread. \end{note} \end{itemdescr} \rSec3[fs.op.equivalent]{Equivalent} \indexlibraryglobal{equivalent}% \begin{itemdecl} bool filesystem::equivalent(const path& p1, const path& p2); bool filesystem::equivalent(const path& p1, const path& p2, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum Two paths are considered to resolve to the same file system entity if two candidate entities reside on the same device at the same location. \begin{note} On POSIX platforms, this is determined as if by the values of the POSIX \tcode{stat} class, obtained as if by \tcode{stat()} for the two paths, having equal \tcode{st_dev} values and equal \tcode{st_ino} values. \end{note} \pnum \returns \tcode{true}, if \tcode{p1} and \tcode{p2} resolve to the same file system entity, otherwise \tcode{false}. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks \tcode{!exists(p1) || !exists(p2)} is an error. \end{itemdescr} \rSec3[fs.op.exists]{Exists} \indexlibraryglobal{exists}% \begin{itemdecl} bool filesystem::exists(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{status_known(s) \&\& s.type() != file_type::not_found}. \end{itemdescr} \indexlibraryglobal{exists}% \begin{itemdecl} bool filesystem::exists(const path& p); bool filesystem::exists(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{s} be a \tcode{file_status}, determined as if by \tcode{status(p)} or \tcode{status(p, ec)}, respectively. \pnum \effects The signature with argument \tcode{ec} calls \tcode{ec.clear()} if \tcode{status_known(s)}. \pnum \returns \tcode{exists(s)}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.file.size]{File size} \indexlibraryglobal{file_size}% \begin{itemdecl} uintmax_t filesystem::file_size(const path& p); uintmax_t filesystem::file_size(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{exists(p)} is \tcode{false}, an error is reported\iref{fs.err.report}. \pnum \returns \begin{itemize} \item If \tcode{is_regular_file(p)}, the size in bytes of the file \tcode{p} resolves to, determined as if by the value of the POSIX \tcode{stat} class member \tcode{st_size} obtained as if by POSIX \tcode{stat()}. \item Otherwise, the result is \impldef{result of \tcode{filesystem::file_size}}. \end{itemize} The signature with argument \tcode{ec} returns \tcode{static_cast(-1)} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.hard.lk.ct]{Hard link count} \indexlibraryglobal{hard_link_count}% \begin{itemdecl} uintmax_t filesystem::hard_link_count(const path& p); uintmax_t filesystem::hard_link_count(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The number of hard links for \tcode{p}. The signature with argument \tcode{ec} returns \tcode{static_cast(-1)} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.block.file]{Is block file} \indexlibraryglobal{is_block_file}% \begin{itemdecl} bool filesystem::is_block_file(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::block}. \end{itemdescr} \indexlibraryglobal{is_block_file}% \begin{itemdecl} bool filesystem::is_block_file(const path& p); bool filesystem::is_block_file(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_block_file(status(p))} or \tcode{is_block_file(status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.char.file]{Is character file} \indexlibraryglobal{is_character_file}% \begin{itemdecl} bool filesystem::is_character_file(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::character}. \end{itemdescr} \indexlibraryglobal{is_character_file}% \begin{itemdecl} bool filesystem::is_character_file(const path& p); bool filesystem::is_character_file(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_character_file(status(p))} or \tcode{is_character_file(status(p, ec))}, respectively.\\The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.directory]{Is directory} \indexlibraryglobal{is_directory}% \begin{itemdecl} bool filesystem::is_directory(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::directory}. \end{itemdescr} \indexlibraryglobal{is_directory}% \begin{itemdecl} bool filesystem::is_directory(const path& p); bool filesystem::is_directory(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_directory(status(p))} or \tcode{is_directory(status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.empty]{Is empty} \indexlibrary{\idxcode{is_empty}!function}% \begin{itemdecl} bool filesystem::is_empty(const path& p); bool filesystem::is_empty(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects \begin{itemize} \item Determine \tcode{file_status s}, as if by \tcode{status(p)} or \tcode{status(p, ec)}, respectively. \item For the signature with argument \tcode{ec}, return \tcode{false} if an error occurred. \item Otherwise, if \tcode{is_directory(s)}: \begin{itemize} \item Create a variable \tcode{itr}, as if by \tcode{directory_iterator itr(p)} or \tcode{directory_iterator itr(p, ec)}, respectively. \item For the signature with argument \tcode{ec}, return \tcode{false} if an error occurred. \item Otherwise, return \tcode{itr == directory_iterator()}. \end{itemize} \item Otherwise: \begin{itemize} \item Determine \tcode{uintmax_t sz}, as if by \tcode{file_size(p)} or \tcode{file_size(p, ec)}, respectively. \item For the signature with argument \tcode{ec}, return \tcode{false} if an error occurred. \item Otherwise, return \tcode{sz == 0}. \end{itemize} \end{itemize} \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.fifo]{Is fifo} \indexlibraryglobal{is_fifo}% \begin{itemdecl} bool filesystem::is_fifo(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::fifo}. \end{itemdescr} \indexlibraryglobal{is_fifo}% \begin{itemdecl} bool filesystem::is_fifo(const path& p); bool filesystem::is_fifo(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_fifo(status(p))} or \tcode{is_fifo(status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.other]{Is other} \indexlibraryglobal{is_other}% \begin{itemdecl} bool filesystem::is_other(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{exists(s) \&\& !is_regular_file(s) \&\& !is_directory(s) \&\& !is_symlink(s)}. \end{itemdescr} \indexlibraryglobal{is_other}% \begin{itemdecl} bool filesystem::is_other(const path& p); bool filesystem::is_other(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_other(status(p))} or \tcode{is_other(status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.regular.file]{Is regular file} \indexlibraryglobal{is_regular_file}% \begin{itemdecl} bool filesystem::is_regular_file(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::regular}. \end{itemdescr} \indexlibraryglobal{is_regular_file}% \begin{itemdecl} bool filesystem::is_regular_file(const path& p); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_regular_file(status(p))}. \pnum \throws \tcode{filesystem_error} if \tcode{status(p)} would throw \tcode{filesystem_error}. \end{itemdescr} \indexlibraryglobal{is_regular_file}% \begin{itemdecl} bool filesystem::is_regular_file(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Sets \tcode{ec} as if by \tcode{status(p, ec)}. \begin{note} \tcode{file_type::none}, \tcode{file_type::not_found} and \tcode{file_type::unknown} cases set \tcode{ec} to error values. To distinguish between cases, call the \tcode{status} function directly. \end{note} \pnum \returns \tcode{is_regular_file(status(p, ec))}. Returns \tcode{false} if an error occurs. \end{itemdescr} \rSec3[fs.op.is.socket]{Is socket} \indexlibraryglobal{is_socket}% \begin{itemdecl} bool filesystem::is_socket(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::socket}. \end{itemdescr} \indexlibraryglobal{is_socket}% \begin{itemdecl} bool filesystem::is_socket(const path& p); bool filesystem::is_socket(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_socket(status(p))} or \tcode{is_socket(status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.is.symlink]{Is symlink} \indexlibraryglobal{is_symlink}% \begin{itemdecl} bool filesystem::is_symlink(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() == file_type::symlink}. \end{itemdescr} \indexlibraryglobal{is_symlink}% \begin{itemdecl} bool filesystem::is_symlink(const path& p); bool filesystem::is_symlink(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{is_symlink(symlink_status(p))} or \tcode{is_symlink(symlink_status(p, ec))}, respectively. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.last.write.time]{Last write time} \indexlibraryglobal{last_write_time}% \begin{itemdecl} file_time_type filesystem::last_write_time(const path& p); file_time_type filesystem::last_write_time(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns The time of last data modification of \tcode{p}, determined as if by the value of the POSIX \tcode{stat} class member \tcode{st_mtime} obtained as if by POSIX \tcode{stat()}. The signature with argument \tcode{ec} returns \tcode{file_time_type::min()} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibraryglobal{last_write_time}% \begin{itemdecl} void filesystem::last_write_time(const path& p, file_time_type new_time); void filesystem::last_write_time(const path& p, file_time_type new_time, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Sets the time of last data modification of the file resolved to by \tcode{p} to \tcode{new_time}, as if by POSIX \tcode{futimens()}. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{note} A postcondition of \tcode{last_write_time(p) == new_time} is not specified because it does not necessarily hold for file systems with coarse time granularity. \end{note} \end{itemdescr} \rSec3[fs.op.permissions]{Permissions} \indexlibraryglobal{permissions}% \begin{itemdecl} void filesystem::permissions(const path& p, perms prms, perm_options opts=perm_options::replace); void filesystem::permissions(const path& p, perms prms, error_code& ec) noexcept; void filesystem::permissions(const path& p, perms prms, perm_options opts, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \expects Exactly one of the \tcode{perm_options} constants \tcode{replace}, \tcode{add}, or \tcode{remove} is present in \tcode{opts}. \pnum \effects Applies the action specified by \tcode{opts} to the file \tcode{p} resolves to, or to file \tcode{p} itself if \tcode{p} is a symbolic link and \tcode{perm_options::nofollow} is set in \tcode{opts}. The action is applied as if by POSIX \tcode{fchmodat()}. \pnum \begin{note} Conceptually permissions are viewed as bits, but the actual implementation can use some other mechanism. \end{note} \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks The second signature behaves as if it had an additional parameter \tcode{perm_options} \tcode{opts} with an argument of \tcode{perm_options::replace}. \end{itemdescr} \rSec3[fs.op.proximate]{Proximate} \indexlibraryglobal{proximate}% \begin{itemdecl} path filesystem::proximate(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{proximate(p, current_path(), ec)}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibraryglobal{proximate}% \begin{itemdecl} path filesystem::proximate(const path& p, const path& base = current_path()); path filesystem::proximate(const path& p, const path& base, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns For the first form: \begin{codeblock} weakly_canonical(p).lexically_proximate(weakly_canonical(base)); \end{codeblock} For the second form: \begin{codeblock} weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec)); \end{codeblock} or \tcode{path()} at the first error occurrence, if any. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.read.symlink]{Read symlink} \indexlibraryglobal{read_symlink}% \begin{itemdecl} path filesystem::read_symlink(const path& p); path filesystem::read_symlink(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns If \tcode{p} resolves to a symbolic link, a \tcode{path} object containing the contents of that symbolic link. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \begin{note} It is an error if \tcode{p} does not resolve to a symbolic link. \end{note} \end{itemdescr} \rSec3[fs.op.relative]{Relative} \indexlibraryglobal{relative}% \begin{itemdecl} path filesystem::relative(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{relative(p, current_path(), ec)}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \indexlibraryglobal{relative}% \begin{itemdecl} path filesystem::relative(const path& p, const path& base = current_path()); path filesystem::relative(const path& p, const path& base, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \returns For the first form: \begin{codeblock} weakly_canonical(p).lexically_relative(weakly_canonical(base)); \end{codeblock} For the second form: \begin{codeblock} weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec)); \end{codeblock} or \tcode{path()} at the first error occurrence, if any. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.remove]{Remove} \indexlibrarymember{remove}{path}% \begin{itemdecl} bool filesystem::remove(const path& p); bool filesystem::remove(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If \tcode{exists(symlink_status(p, ec))}, the file \tcode{p} is removed as if by POSIX \tcode{remove()}. \begin{note} A symbolic link is itself removed, rather than the file it resolves to. \end{note} \pnum \ensures \tcode{exists(symlink_status(p))} is \tcode{false}. \pnum \returns \tcode{false} if \tcode{p} did not exist, otherwise \tcode{true}. The signature with argument \tcode{ec} returns \tcode{false} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.remove.all]{Remove all} \indexlibraryglobal{remove_all}% \begin{itemdecl} uintmax_t filesystem::remove_all(const path& p); uintmax_t filesystem::remove_all(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Recursively deletes the contents of \tcode{p} if it exists, then deletes file \tcode{p} itself, as if by POSIX \tcode{remove()}. \begin{note} A symbolic link is itself removed, rather than the file it resolves to. \end{note} \pnum \ensures \tcode{exists(symlink_status(p))} is \tcode{false}. \pnum \returns The number of files removed. The signature with argument \tcode{ec} returns \tcode{static_cast< uintmax_t>(-1)} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.rename]{Rename} \indexlibraryglobal{rename}% \begin{itemdecl} void filesystem::rename(const path& old_p, const path& new_p); void filesystem::rename(const path& old_p, const path& new_p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Renames \tcode{old_p} to \tcode{new_p}, as if by POSIX \tcode{rename()}. \begin{note} \begin{itemize} \item If \tcode{old_p} and \tcode{new_p} resolve to the same existing file, no action is taken. \item Otherwise, the rename can include the following effects: \begin{itemize} \item if \tcode{new_p} resolves to an existing non-directory file, \tcode{new_p} is removed; otherwise, \item if \tcode{new_p} resolves to an existing directory, \tcode{new_p} is removed if empty on POSIX compliant operating systems but might be an error on other operating systems. \end{itemize} \end{itemize} A symbolic link is itself renamed, rather than the file it resolves to. \end{note} \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.resize.file]{Resize file} \indexlibraryglobal{resize_file}% \begin{itemdecl} void filesystem::resize_file(const path& p, uintmax_t new_size); void filesystem::resize_file(const path& p, uintmax_t new_size, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Causes the size that would be returned by \tcode{file_size(p)} to be equal to \tcode{new_size}, as if by POSIX \tcode{truncate()}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec3[fs.op.space]{Space} \indexlibraryglobal{space}% \begin{itemdecl} space_info filesystem::space(const path& p); space_info filesystem::space(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns An object of type \tcode{space_info}. The value of the \tcode{space_info} object is determined as if by using POSIX \tcode{statvfs} to obtain a POSIX \tcode{struct statvfs}, and then multiplying its \tcode{f_blocks}, \tcode{f_bfree}, and \tcode{f_bavail} members by its \tcode{f_frsize} member, and assigning the results to the \tcode{capacity}, \tcode{free}, and \tcode{available} members respectively. Any members for which the value cannot be determined shall be set to \tcode{static_cast(-1)}. For the signature with argument \tcode{ec}, all members are set to \tcode{static_cast(-1)} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks The value of member \tcode{space_info::available} is operating system dependent. \begin{note} \tcode{available} might be less than \tcode{free}. \end{note} \end{itemdescr} \rSec3[fs.op.status]{Status} \indexlibraryglobal{status}% \begin{itemdecl} file_status filesystem::status(const path& p); \end{itemdecl} \begin{itemdescr} \pnum \effects As if by: \begin{codeblock} error_code ec; file_status result = status(p, ec); if (result.type() == file_type::none) throw filesystem_error(@\textit{implementation-supplied-message}@, p, ec); return result; \end{codeblock} \pnum \returns See above. \pnum \throws \tcode{filesystem_error}. \begin{note} \tcode{result} values of \tcode{file_status(file_type::not_found)} and \tcode{file_status(file_type::unknown)} are not considered failures and do not cause an exception to be thrown. \end{note} \end{itemdescr} \indexlibraryglobal{status}% \begin{itemdecl} file_status filesystem::status(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects If possible, determines the attributes of the file \tcode{p} resolves to, as if by using POSIX \tcode{stat()} to obtain a POSIX \tcode{struct stat}. If, during attribute determination, the underlying file system API reports an error, sets \tcode{ec} to indicate the specific error reported. Otherwise, \tcode{ec.clear()}. \begin{note} This allows users to inspect the specifics of underlying API errors even when the value returned by \tcode{status()} is not \tcode{file_status(file_type::none)}. \end{note} \pnum Let \tcode{prms} denote the result of \tcode{(m \& perms::mask)}, where \tcode{m} is determined as if by converting the \tcode{st_mode} member of the obtained \tcode{struct stat} to the type \tcode{perms}. \pnum \returns \begin{itemize} \item If \tcode{ec != error_code()}: \begin{itemize} \item If the specific error indicates that \tcode{p} cannot be resolved because some element of the path does not exist, returns \tcode{file_status(file_type::not_found)}. \item Otherwise, if the specific error indicates that \tcode{p} can be resolved but the attributes cannot be determined, returns \tcode{file_status(file_type::unknown)}. \item Otherwise, returns \tcode{file_status(file_type::none)}. \end{itemize} \begin{note} These semantics distinguish between \tcode{p} being known not to exist, \tcode{p} existing but not being able to determine its attributes, and there being an error that prevents even knowing if \tcode{p} exists. These distinctions are important to some use cases. \end{note} \item Otherwise, \begin{itemize} \item If the attributes indicate a regular file, as if by POSIX \tcode{S_ISREG}, returns \tcode{file_status(file_type::regular, prms)}. \begin{note} \tcode{file_type::regular} implies appropriate \libheader{fstream} operations would succeed, assuming no hardware, permission, access, or file system race errors. Lack of \tcode{file_type::regular} does not necessarily imply \libheader{fstream} operations would fail on a directory. \end{note} \item Otherwise, if the attributes indicate a directory, as if by POSIX \tcode{S_ISDIR}, returns \tcode{file_status(file_type::directory, prms)}. \begin{note} \tcode{file_type::directory} implies that calling \tcode{directory_iterator(p)} would succeed. \end{note} \item Otherwise, if the attributes indicate a block special file, as if by POSIX \tcode{S_ISBLK}, returns \tcode{file_status(file_type::block, prms)}. \item Otherwise, if the attributes indicate a character special file, as if by POSIX \tcode{S_ISCHR}, returns \tcode{file_status(file_type::character, prms)}. \item Otherwise, if the attributes indicate a fifo or pipe file, as if by POSIX \tcode{S_ISFIFO}, returns \tcode{file_status(file_type::fifo, prms)}. \item Otherwise, if the attributes indicate a socket, as if by POSIX \tcode{S_ISSOCK}, returns \tcode{file_status(file_type::socket, prms)}. \item Otherwise, if the attributes indicate an implementation-defined file type\iref{fs.enum.file.type}, returns \tcode{file_status(file_type::\placeholdernc{A}, prms)}, where \tcode{\placeholdernc{A}} is the constant for the \impldef{file type of the file argument of \tcode{filesystem::status}} file type. \item Otherwise, returns \tcode{file_status(file_type::unknown, prms)}. \end{itemize} \end{itemize} \pnum \remarks If a symbolic link is encountered during pathname resolution, pathname resolution continues using the contents of the symbolic link. \end{itemdescr} \rSec3[fs.op.status.known]{Status known} \indexlibraryglobal{status_known}% \begin{itemdecl} bool filesystem::status_known(file_status s) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \returns \tcode{s.type() != file_type::none}. \end{itemdescr} \rSec3[fs.op.symlink.status]{Symlink status} \indexlibraryglobal{symlink_status}% \begin{itemdecl} file_status filesystem::symlink_status(const path& p); file_status filesystem::symlink_status(const path& p, error_code& ec) noexcept; \end{itemdecl} \begin{itemdescr} \pnum \effects Same as \tcode{status()}, above, except that the attributes of \tcode{p} are determined as if by using POSIX \tcode{lstat()} to obtain a POSIX \tcode{struct stat}. \pnum Let \tcode{prms} denote the result of \tcode{(m \& perms::mask)}, where \tcode{m} is determined as if by converting the \tcode{st_mode} member of the obtained \tcode{struct stat} to the type \tcode{perms}. \pnum \returns Same as \tcode{status()}, above, except that if the attributes indicate a symbolic link, as if by POSIX \tcode{S_ISLNK}, returns \tcode{file_status(file_type::symlink, prms)}. The signature with argument \tcode{ec} returns \tcode{file_status(file_type::none)} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \remarks Pathname resolution terminates if \tcode{p} names a symbolic link. \end{itemdescr} \rSec3[fs.op.temp.dir.path]{Temporary directory path} \indexlibraryglobal{temp_directory_path}% \begin{itemdecl} path filesystem::temp_directory_path(); path filesystem::temp_directory_path(error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum Let \tcode{p} be an unspecified directory path suitable for temporary files. \pnum \effects If \tcode{exists(p)} is \tcode{false} or \tcode{is_directory(p)} is \tcode{false}, an error is reported\iref{fs.err.report}. \pnum \returns The path \tcode{p}. The signature with argument \tcode{ec} returns \tcode{path()} if an error occurs. \pnum \throws As specified in~\ref{fs.err.report}. \pnum \begin{example} For POSIX-based operating systems, an implementation might return the path supplied by the first environment variable found in the list TMPDIR, TMP, TEMP, TEMPDIR, or if none of these are found, \tcode{"/tmp"}. For Windows-based operating systems, an implementation might return the path reported by the Windows \tcode{GetTempPath} API function. \end{example} \end{itemdescr} \rSec3[fs.op.weakly.canonical]{Weakly canonical} \indexlibraryglobal{weakly_canonical}% \begin{itemdecl} path filesystem::weakly_canonical(const path& p); path filesystem::weakly_canonical(const path& p, error_code& ec); \end{itemdecl} \begin{itemdescr} \pnum \effects Using \tcode{status(p)} or \tcode{status(p, ec)}, respectively, to determine existence, return a path composed by \tcode{operator/=} from the result of calling \tcode{canonical()} with a path argument composed of the leading elements of \tcode{p} that exist, if any, followed by the elements of \tcode{p} that do not exist, if any. For the first form, \tcode{canonical()} is called without an \tcode{error_code} argument. For the second form, \tcode{canonical()} is called with \tcode{ec} as an \tcode{error_code} argument, and \tcode{path()} is returned at the first error occurrence, if any. \pnum \ensures The returned path is in normal form\iref{fs.path.generic}. \pnum \returns \tcode{p} with symlinks resolved and the result normalized\iref{fs.path.generic}. \pnum \throws As specified in~\ref{fs.err.report}. \end{itemdescr} \rSec1[c.files]{C library files} \rSec2[cstdio.syn]{Header \tcode{} synopsis} \indexheader{cstdio}% \indexlibraryglobal{size_t}% \indexlibraryglobal{FILE}% \indexlibraryglobal{fpos_t}% \indexlibraryglobal{NULL}% \indexlibraryglobal{_IOFBF}% \indexlibraryglobal{_IOLBF}% \indexlibraryglobal{_IONBF}% \indexlibraryglobal{BUFSIZ}% \indexlibraryglobal{EOF}% \indexlibraryglobal{FOPEN_MAX}% \indexlibraryglobal{FILENAME_MAX}% \indexlibraryglobal{L_tmpnam}% \indexlibraryglobal{SEEK_CUR}% \indexlibraryglobal{SEEK_END}% \indexlibraryglobal{SEEK_SET}% \indexlibraryglobal{TMP_MAX}% \indexlibraryglobal{stderr}% \indexlibraryglobal{stdin}% \indexlibraryglobal{stdout}% \indexlibraryglobal{remove}% \indexlibraryglobal{rename}% \indexlibraryglobal{tmpfile}% \indexlibraryglobal{tmpnam}% \indexlibraryglobal{fclose}% \indexlibraryglobal{fflush}% \indexlibraryglobal{fopen}% \indexlibraryglobal{freopen}% \indexlibraryglobal{setbuf}% \indexlibraryglobal{setvbuf}% \indexlibraryglobal{fprintf}% \indexlibraryglobal{fscanf}% \indexlibraryglobal{printf}% \indexlibraryglobal{scanf}% \indexlibraryglobal{snprintf}% \indexlibraryglobal{sprintf}% \indexlibraryglobal{sscanf}% \indexlibraryglobal{vfprintf}% \indexlibraryglobal{vfscanf}% \indexlibraryglobal{vprintf}% \indexlibraryglobal{vscanf}% \indexlibraryglobal{vsnprintf}% \indexlibraryglobal{vsprintf}% \indexlibraryglobal{vsscanf}% \indexlibraryglobal{fgetc}% \indexlibraryglobal{fgets}% \indexlibraryglobal{fputc}% \indexlibraryglobal{fputs}% \indexlibraryglobal{getc}% \indexlibraryglobal{getchar}% \indexlibraryglobal{putc}% \indexlibraryglobal{putchar}% \indexlibraryglobal{puts}% \indexlibraryglobal{ungetc}% \indexlibraryglobal{fread}% \indexlibraryglobal{fwrite}% \indexlibraryglobal{fgetpos}% \indexlibraryglobal{fseek}% \indexlibraryglobal{fsetpos}% \indexlibraryglobal{ftell}% \indexlibraryglobal{rewind}% \indexlibraryglobal{clearerr}% \indexlibraryglobal{feof}% \indexlibraryglobal{ferror}% \indexlibraryglobal{perror}% \begin{codeblock} namespace std { using size_t = @\textit{see \ref{support.types.layout}}@; using FILE = @\seebelow@; using fpos_t = @\seebelow@; } #define NULL @\textit{see \ref{support.types.nullptr}}@ #define _IOFBF @\seebelow@ #define _IOLBF @\seebelow@ #define _IONBF @\seebelow@ #define BUFSIZ @\seebelow@ #define EOF @\seebelow@ #define FOPEN_MAX @\seebelow@ #define FILENAME_MAX @\seebelow@ #define L_tmpnam @\seebelow@ #define SEEK_CUR @\seebelow@ #define SEEK_END @\seebelow@ #define SEEK_SET @\seebelow@ #define TMP_MAX @\seebelow@ #define stderr @\seebelow@ #define stdin @\seebelow@ #define stdout @\seebelow@ namespace std { int remove(const char* filename); int rename(const char* old_p, const char* new_p); FILE* tmpfile(); char* tmpnam(char* s); int fclose(FILE* stream); int fflush(FILE* stream); FILE* fopen(const char* filename, const char* mode); FILE* freopen(const char* filename, const char* mode, FILE* stream); void setbuf(FILE* stream, char* buf); int setvbuf(FILE* stream, char* buf, int mode, size_t size); int fprintf(FILE* stream, const char* format, ...); int fscanf(FILE* stream, const char* format, ...); int printf(const char* format, ...); int scanf(const char* format, ...); int snprintf(char* s, size_t n, const char* format, ...); int sprintf(char* s, const char* format, ...); int sscanf(const char* s, const char* format, ...); int vfprintf(FILE* stream, const char* format, va_list arg); int vfscanf(FILE* stream, const char* format, va_list arg); int vprintf(const char* format, va_list arg); int vscanf(const char* format, va_list arg); int vsnprintf(char* s, size_t n, const char* format, va_list arg); int vsprintf(char* s, const char* format, va_list arg); int vsscanf(const char* s, const char* format, va_list arg); int fgetc(FILE* stream); char* fgets(char* s, int n, FILE* stream); int fputc(int c, FILE* stream); int fputs(const char* s, FILE* stream); int getc(FILE* stream); int getchar(); int putc(int c, FILE* stream); int putchar(int c); int puts(const char* s); int ungetc(int c, FILE* stream); size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream); size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream); int fgetpos(FILE* stream, fpos_t* pos); int fseek(FILE* stream, long int offset, int whence); int fsetpos(FILE* stream, const fpos_t* pos); long int ftell(FILE* stream); void rewind(FILE* stream); void clearerr(FILE* stream); int feof(FILE* stream); int ferror(FILE* stream); void perror(const char* s); } \end{codeblock} \pnum The contents and meaning of the header \libheader{cstdio} are the same as the C standard library header \libheader{stdio.h}. \pnum Calls to the function \tcode{tmpnam} with an argument that is a null pointer value may introduce a data race\iref{res.on.data.races} with other calls to \tcode{tmpnam} with an argument that is a null pointer value. \xrefc{7.21} \rSec2[cinttypes.syn]{Header \tcode{} synopsis} \indexheader{cinttypes}% \indexlibraryglobal{imaxdiv_t}% \indexlibraryglobal{imaxabs}% \indexlibraryglobal{imaxdiv}% \indexlibraryglobal{strtoimax}% \indexlibraryglobal{strtoumax}% \indexlibraryglobal{wcstoimax}% \indexlibraryglobal{wcstoumax}% \indexlibraryglobal{abs}% \indexlibraryglobal{div}% \indexlibraryglobal{PRIdN}% \indexlibraryglobal{PRIiN}% \indexlibraryglobal{PRIoN}% \indexlibraryglobal{PRIuN}% \indexlibraryglobal{PRIxN}% \indexlibraryglobal{PRIXN}% \indexlibraryglobal{SCNdN}% \indexlibraryglobal{SCNiN}% \indexlibraryglobal{SCNoN}% \indexlibraryglobal{SCNuN}% \indexlibraryglobal{SCNxN}% \indexlibraryglobal{PRIdLEASTN}% \indexlibraryglobal{PRIiLEASTN}% \indexlibraryglobal{PRIoLEASTN}% \indexlibraryglobal{PRIuLEASTN}% \indexlibraryglobal{PRIxLEASTN}% \indexlibraryglobal{PRIXLEASTN}% \indexlibraryglobal{SCNdLEASTN}% \indexlibraryglobal{SCNiLEASTN}% \indexlibraryglobal{SCNoLEASTN}% \indexlibraryglobal{SCNuLEASTN}% \indexlibraryglobal{SCNxLEASTN}% \indexlibraryglobal{PRIdFASTN}% \indexlibraryglobal{PRIiFASTN}% \indexlibraryglobal{PRIoFASTN}% \indexlibraryglobal{PRIuFASTN}% \indexlibraryglobal{PRIxFASTN}% \indexlibraryglobal{PRIXFASTN}% \indexlibraryglobal{SCNdFASTN}% \indexlibraryglobal{SCNiFASTN}% \indexlibraryglobal{SCNoFASTN}% \indexlibraryglobal{SCNuFASTN}% \indexlibraryglobal{SCNxFASTN}% \indexlibraryglobal{PRIdMAX}% \indexlibraryglobal{PRIiMAX}% \indexlibraryglobal{PRIoMAX}% \indexlibraryglobal{PRIuMAX}% \indexlibraryglobal{PRIxMAX}% \indexlibraryglobal{PRIXMAX}% \indexlibraryglobal{SCNdMAX}% \indexlibraryglobal{SCNiMAX}% \indexlibraryglobal{SCNoMAX}% \indexlibraryglobal{SCNuMAX}% \indexlibraryglobal{SCNxMAX}% \indexlibraryglobal{PRIdPTR}% \indexlibraryglobal{PRIiPTR}% \indexlibraryglobal{PRIoPTR}% \indexlibraryglobal{PRIuPTR}% \indexlibraryglobal{PRIxPTR}% \indexlibraryglobal{PRIXPTR}% \indexlibraryglobal{SCNdPTR}% \indexlibraryglobal{SCNiPTR}% \indexlibraryglobal{SCNoPTR}% \indexlibraryglobal{SCNuPTR}% \indexlibraryglobal{SCNxPTR}% \begin{codeblock} #include // see \ref{cstdint.syn} namespace std { using imaxdiv_t = @\seebelow@; constexpr intmax_t imaxabs(intmax_t j); constexpr imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); intmax_t strtoimax(const char* nptr, char** endptr, int base); uintmax_t strtoumax(const char* nptr, char** endptr, int base); intmax_t wcstoimax(const wchar_t* nptr, wchar_t** endptr, int base); uintmax_t wcstoumax(const wchar_t* nptr, wchar_t** endptr, int base); constexpr intmax_t abs(intmax_t); // optional, see below constexpr imaxdiv_t div(intmax_t, intmax_t); // optional, see below } #define PRId@\placeholdernc{N}@ @\seebelow@ #define PRIi@\placeholdernc{N}@ @\seebelow@ #define PRIo@\placeholdernc{N}@ @\seebelow@ #define PRIu@\placeholdernc{N}@ @\seebelow@ #define PRIx@\placeholdernc{N}@ @\seebelow@ #define PRIX@\placeholdernc{N}@ @\seebelow@ #define SCNd@\placeholdernc{N}@ @\seebelow@ #define SCNi@\placeholdernc{N}@ @\seebelow@ #define SCNo@\placeholdernc{N}@ @\seebelow@ #define SCNu@\placeholdernc{N}@ @\seebelow@ #define SCNx@\placeholdernc{N}@ @\seebelow@ #define PRIdLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIiLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIoLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIuLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIxLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIXLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNdLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNiLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNoLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNuLEAST@\placeholdernc{N}@ @\seebelow@ #define SCNxLEAST@\placeholdernc{N}@ @\seebelow@ #define PRIdFAST@\placeholdernc{N}@ @\seebelow@ #define PRIiFAST@\placeholdernc{N}@ @\seebelow@ #define PRIoFAST@\placeholdernc{N}@ @\seebelow@ #define PRIuFAST@\placeholdernc{N}@ @\seebelow@ #define PRIxFAST@\placeholdernc{N}@ @\seebelow@ #define PRIXFAST@\placeholdernc{N}@ @\seebelow@ #define SCNdFAST@\placeholdernc{N}@ @\seebelow@ #define SCNiFAST@\placeholdernc{N}@ @\seebelow@ #define SCNoFAST@\placeholdernc{N}@ @\seebelow@ #define SCNuFAST@\placeholdernc{N}@ @\seebelow@ #define SCNxFAST@\placeholdernc{N}@ @\seebelow@ #define PRIdMAX @\seebelow@ #define PRIiMAX @\seebelow@ #define PRIoMAX @\seebelow@ #define PRIuMAX @\seebelow@ #define PRIxMAX @\seebelow@ #define PRIXMAX @\seebelow@ #define SCNdMAX @\seebelow@ #define SCNiMAX @\seebelow@ #define SCNoMAX @\seebelow@ #define SCNuMAX @\seebelow@ #define SCNxMAX @\seebelow@ #define PRIdPTR @\seebelow@ #define PRIiPTR @\seebelow@ #define PRIoPTR @\seebelow@ #define PRIuPTR @\seebelow@ #define PRIxPTR @\seebelow@ #define PRIXPTR @\seebelow@ #define SCNdPTR @\seebelow@ #define SCNiPTR @\seebelow@ #define SCNoPTR @\seebelow@ #define SCNuPTR @\seebelow@ #define SCNxPTR @\seebelow@ \end{codeblock} \pnum The contents and meaning of the header \libheader{cinttypes} are the same as the C standard library header \libheader{inttypes.h}, with the following changes: \begin{itemize} \item The header \libheader{cinttypes} includes the header \libheaderref{cstdint} instead of \libheader{stdint.h}, and \item \tcode{intmax_t} and \tcode{uintmax_t} are not required to be able to represent all values of extended integer types wider than \tcode{long long} and \tcode{unsigned long long}, respectively, and \item if and only if the type \tcode{intmax_t} designates an extended integer type\iref{basic.fundamental}, the following function signatures are added: \begin{codeblock} constexpr intmax_t abs(intmax_t); constexpr imaxdiv_t div(intmax_t, intmax_t); \end{codeblock} which shall have the same semantics as the function signatures \tcode{constexpr intmax_t imaxabs(intmax_t)} and \tcode{constexpr imaxdiv_t imaxdiv(intmax_t, intmax_t)}, respectively. \end{itemize} \xrefc{7.8} \pnum Each of the \tcode{PRI} macros listed in this subclause is defined if and only if the implementation defines the corresponding \grammarterm{typedef-name} in~\ref{cstdint.syn}. Each of the \tcode{SCN} macros listed in this subclause is defined if and only if the implementation defines the corresponding \grammarterm{typedef-name} in~\ref{cstdint.syn} and has a suitable \tcode{fscanf} length modifier for the type.