%!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{<iosfwd>}     \\ \rowsep
\ref{iostream.objects}        & Standard iostream objects   & \tcode{<iostream>}   \\ \rowsep
\ref{iostreams.base}          & Iostreams base classes      & \tcode{<ios>}        \\ \rowsep
\ref{stream.buffers}          & Stream buffers              & \tcode{<streambuf>}  \\ \rowsep
\ref{iostream.format}         & Formatting and manipulators &
  \tcode{<istream>}, \tcode{<ostream>}, \tcode{<iomanip>}, \tcode{<print>}   \\ \rowsep
\ref{string.streams}          & String streams              & \tcode{<sstream>}    \\ \rowsep
\ref{span.streams}            & Span-based streams          & \tcode{<spanstream>} \\ \rowsep
\ref{file.streams}            & File streams                & \tcode{<fstream>}    \\ \rowsep
\ref{syncstream}              & Synchronized output streams & \tcode{<syncstream>} \\ \rowsep
\ref{filesystems}             & File systems                & \tcode{<filesystem>} \\ \rowsep
\ref{c.files}                 & C library files             &
  \tcode{<cstdio>}, \tcode{<cinttypes>}  \\
\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<mbstate_t>},
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{<iosfwd>} 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<class charT> struct char_traits;
  template<> struct char_traits<char>;
  template<> struct char_traits<char8_t>;
  template<> struct char_traits<char16_t>;
  template<> struct char_traits<char32_t>;
  template<> struct char_traits<wchar_t>;

  template<class T> class allocator;

  template<class charT, class traits = char_traits<charT>>
    class basic_ios;
  template<class charT, class traits = char_traits<charT>>
    class basic_streambuf;
  template<class charT, class traits = char_traits<charT>>
    class basic_istream;
  template<class charT, class traits = char_traits<charT>>
    class basic_ostream;
  template<class charT, class traits = char_traits<charT>>
    class basic_iostream;

  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_stringbuf;
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_istringstream;
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_ostringstream;
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_stringstream;

  template<class charT, class traits = char_traits<charT>>
    class basic_spanbuf;
  template<class charT, class traits = char_traits<charT>>
    class basic_ispanstream;
  template<class charT, class traits = char_traits<charT>>
    class basic_ospanstream;
  template<class charT, class traits = char_traits<charT>>
    class basic_spanstream;

  template<class charT, class traits = char_traits<charT>>
    class basic_filebuf;
  template<class charT, class traits = char_traits<charT>>
    class basic_ifstream;
  template<class charT, class traits = char_traits<charT>>
    class basic_ofstream;
  template<class charT, class traits = char_traits<charT>>
    class basic_fstream;

  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_syncbuf;
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_osyncstream;

  template<class charT, class traits = char_traits<charT>>
    class istreambuf_iterator;
  template<class charT, class traits = char_traits<charT>>
    class ostreambuf_iterator;

  using ios  = basic_ios<char>;
  using wios = basic_ios<wchar_t>;

  using streambuf = basic_streambuf<char>;
  using istream   = basic_istream<char>;
  using ostream   = basic_ostream<char>;
  using iostream  = basic_iostream<char>;

  using stringbuf     = basic_stringbuf<char>;
  using istringstream = basic_istringstream<char>;
  using ostringstream = basic_ostringstream<char>;
  using stringstream  = basic_stringstream<char>;

  using spanbuf     = basic_spanbuf<char>;
  using ispanstream = basic_ispanstream<char>;
  using ospanstream = basic_ospanstream<char>;
  using spanstream  = basic_spanstream<char>;

  using filebuf  = basic_filebuf<char>;
  using ifstream = basic_ifstream<char>;
  using ofstream = basic_ofstream<char>;
  using fstream  = basic_fstream<char>;

  using syncbuf = basic_syncbuf<char>;
  using osyncstream = basic_osyncstream<char>;

  using wstreambuf = basic_streambuf<wchar_t>;
  using wistream   = basic_istream<wchar_t>;
  using wostream   = basic_ostream<wchar_t>;
  using wiostream  = basic_iostream<wchar_t>;

  using wstringbuf     = basic_stringbuf<wchar_t>;
  using wistringstream = basic_istringstream<wchar_t>;
  using wostringstream = basic_ostringstream<wchar_t>;
  using wstringstream  = basic_stringstream<wchar_t>;

  using wspanbuf     = basic_spanbuf<wchar_t>;
  using wispanstream = basic_ispanstream<wchar_t>;
  using wospanstream = basic_ospanstream<wchar_t>;
  using wspanstream  = basic_spanstream<wchar_t>;

  using wfilebuf  = basic_filebuf<wchar_t>;
  using wifstream = basic_ifstream<wchar_t>;
  using wofstream = basic_ofstream<wchar_t>;
  using wfstream  = basic_fstream<wchar_t>;

  using wsyncbuf = basic_syncbuf<wchar_t>;
  using wosyncstream = basic_osyncstream<wchar_t>;

  template<class state> class fpos;
  using streampos  = fpos<char_traits<char>::state_type>;
  using wstreampos = fpos<char_traits<wchar_t>::state_type>;
  using u8streampos = fpos<char_traits<char8_t>::state_type>;
  using u16streampos = fpos<char_traits<char16_t>::state_type>;
  using u32streampos = fpos<char_traits<char32_t>::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<charT, traits>}
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<charT, traits>}
and
\tcode{basic_ostream<charT, traits>}.

\pnum
The
class template specialization
\tcode{basic_streambuf<charT, traits>}
serves as a base class for class templates
\tcode{basic_stringbuf},
\tcode{basic_filebuf},
\tcode{basic_syncbuf},
and
\tcode{basic_spanbuf}.

\pnum
The
class template specialization
\tcode{basic_istream<charT, traits>}
serves as a base class for class templates
\tcode{basic_istringstream},
\tcode{basic_ifstream},
and
\tcode{basic_ispanstream}.

\pnum
The
class template specialization
\tcode{basic_ostream<charT, traits>}
serves as a base class for class templates
\tcode{basic_ostringstream},
\tcode{basic_ofstream},
\tcode{basic_osyncstream},
and
\tcode{basic_ospanstream}.

\pnum
The
class template specialization
\tcode{basic_iostream<charT, traits>}
serves as a base class for class templates
\tcode{basic_stringstream},
\tcode{basic_fstream},
and
\tcode{basic_spanstream}.

\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} designate
class template specializations 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<char>}.
An implementation can avoid this circularity by substituting equivalent
types.
\end{note}

\rSec1[iostream.objects]{Standard iostream objects}

\rSec2[iostream.syn]{Header \tcode{<iostream>} synopsis}

\indexheader{iostream}%
\begin{codeblock}
#include <ios>          // see \ref{ios.syn}
#include <streambuf>    // see \ref{streambuf.syn}
#include <istream>      // see \ref{istream.syn}
#include <ostream>      // 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.
The dynamic types of the stream buffers
initially associated with these objects are unspecified,
but they have the behavior specified for
\tcode{std::basic_filebuf<char>}
or
\tcode{std::basic_filebuf<wchar_t>}.

\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.23.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<char>::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<char>::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<wchar_t>::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<wchar_t>::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{<ios>} synopsis}

\indexheader{ios}%
\indexlibraryglobal{io_errc}%
\begin{codeblock}
#include <iosfwd>   // see \ref{iosfwd.syn}

namespace std {
  // \ref{stream.types}, types
  using streamoff  = @\impdef@;
  using streamsize = @\impdef@;
  // \ref{fpos}, class template \tcode{fpos}
  template<class stateT> class fpos;

  // \ref{ios.base}, class \tcode{ios_base}
  class ios_base;
  // \ref{ios}, class template \tcode{basic_ios}
  template<class charT, class traits = char_traits<charT>>
    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<io_errc> : 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<char>}%
\indexlibraryglobal{wios}%
\indexlibraryglobal{basic_ios<wchar_t>}%
\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 stateT> 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<stateT>} is \tcode{true},
then \tcode{fpos<stateT>} has a trivial copy constructor.
If \tcode{is_trivially_copy_assignable_v<stateT>} is \tcode{true},
then \tcode{fpos<stateT>} has a trivial copy assignment operator.
If \tcode{is_trivially_destructible_v<stateT>} is \tcode{true},
then \tcode{fpos<stateT>} 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 charT, class traits = char_traits<charT>>
  class basic_ios : public ios_base {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = 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<charT, traits>* sb);
    virtual ~basic_ios();

    // \ref{basic.ios.members}, members
    basic_ostream<charT, traits>* tie() const;
    basic_ostream<charT, traits>* tie(basic_ostream<charT, traits>* tiestr);

    basic_streambuf<charT, traits>* rdbuf() const;
    basic_streambuf<charT, traits>* rdbuf(basic_streambuf<charT, traits>* 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<charT, traits>* sb);
    void move(basic_ios& rhs);
    void move(basic_ios&& rhs);
    void swap(basic_ios& rhs) noexcept;
    void set_rdbuf(basic_streambuf<charT, traits>* sb);
  };
}
\end{codeblock}

\rSec3[basic.ios.cons]{Constructors}

\indexlibraryctor{basic_ios}%
\begin{itemdecl}
explicit basic_ios(basic_streambuf<charT, traits>* 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<charT, traits>* 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<charT, traits>* 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<charT, traits>* tie(basic_ostream<charT, traits>* 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<charT, traits>* 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<charT, traits>* rdbuf(basic_streambuf<charT, traits>* 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<ctype<char_type>>(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<ctype<char_type>>(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<charT, traits>* 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<int>(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<int>(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{<streambuf>} synopsis}

\indexheader{streambuf}%
\indexlibraryglobal{streambuf}%
\indexlibraryglobal{basic_streambuf<char>}%
\indexlibraryglobal{wstreambuf}%
\indexlibraryglobal{basic_streambuf<wchar_t>}%
\begin{codeblock}
namespace std {
  // \ref{streambuf}, class template \tcode{basic_streambuf}
  template<class charT, class traits = char_traits<charT>>
    class basic_streambuf;
  using streambuf  = basic_streambuf<char>;
  using wstreambuf = basic_streambuf<wchar_t>;
}
\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 charT, class traits = char_traits<charT>>
  class basic_streambuf {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = 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 affects 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{<istream>} synopsis}

\indexheader{istream}%
\begin{codeblock}
namespace std {
  // \ref{istream}, class template \tcode{basic_istream}
  template<class charT, class traits = char_traits<charT>>
    class basic_istream;

  using istream  = basic_istream<char>;
  using wistream = basic_istream<wchar_t>;

  // \ref{iostreamclass}, class template \tcode{basic_iostream}
  template<class charT, class traits = char_traits<charT>>
    class basic_iostream;

  using iostream  = basic_iostream<char>;
  using wiostream = basic_iostream<wchar_t>;

  // \ref{istream.manip}, standard \tcode{basic_istream} manipulators
  template<class charT, class traits>
    basic_istream<charT, traits>& ws(basic_istream<charT, traits>& is);

  // \ref{istream.rvalue}, rvalue stream extraction
  template<class Istream, class T>
    Istream&& operator>>(Istream&& is, T&& x);
}
\end{codeblock}

\indexlibraryglobal{istream}%
\indexlibraryglobal{basic_istream<char>}%
\indexlibraryglobal{wistream}%
\indexlibraryglobal{basic_istream<wchar_t>}%

\rSec2[ostream.syn]{Header \tcode{<ostream>} synopsis}

\indexheader{ostream}%
\begin{codeblock}
namespace std {
  // \ref{ostream}, class template \tcode{basic_ostream}
  template<class charT, class traits = char_traits<charT>>
    class basic_ostream;

  using ostream  = basic_ostream<char>;
  using wostream = basic_ostream<wchar_t>;

  // \ref{ostream.manip}, standard \tcode{basic_ostream} manipulators
  template<class charT, class traits>
    basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& os);
  template<class charT, class traits>
    basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& os);
  template<class charT, class traits>
    basic_ostream<charT, traits>& flush(basic_ostream<charT, traits>& os);

  template<class charT, class traits>
    basic_ostream<charT, traits>& emit_on_flush(basic_ostream<charT, traits>& os);
  template<class charT, class traits>
    basic_ostream<charT, traits>& noemit_on_flush(basic_ostream<charT, traits>& os);
  template<class charT, class traits>
    basic_ostream<charT, traits>& flush_emit(basic_ostream<charT, traits>& os);

  // \ref{ostream.rvalue}, rvalue stream insertion
  template<class Ostream, class T>
    Ostream&& operator<<(Ostream&& os, const T& x);

  // \ref{ostream.formatted.print}, print functions
  template<class... Args>
    void print(ostream& os, format_string<Args...> fmt, Args&&... args);
  template<class... Args>
    void println(ostream& os, format_string<Args...> 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<char>}%
\indexlibraryglobal{wostream}%
\indexlibraryglobal{basic_ostream<wchar_t>}%

\rSec2[iomanip.syn]{Header \tcode{<iomanip>} 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<class charT> @\unspec@ setfill(charT c);
  @\unspec@ setprecision(int n);
  @\unspec@ setw(int n);

  // \ref{ext.manip}, extended manipulators
  template<class moneyT> @\unspec@ get_money(moneyT& mon, bool intl = false);
  template<class moneyT> @\unspec@ put_money(const moneyT& mon, bool intl = false);
  template<class charT> @\unspec@ get_time(tm* tmb, const charT* fmt);
  template<class charT> @\unspec@ put_time(const tm* tmb, const charT* fmt);

  // \ref{quoted.manip}, quoted manipulators
  template<class charT>
    @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\'));

  template<class charT, class traits, class Allocator>
    @\unspec@ quoted(const basic_string<charT, traits, Allocator>& s,
    @\itcorr@                   charT delim = charT('"'), charT escape = charT('\\'));

  template<class charT, class traits, class Allocator>
    @\unspec@ quoted(basic_string<charT, traits, Allocator>& s,
    @\itcorr@                   charT delim = charT('"'), charT escape = charT('\\'));

  template<class charT, class traits>
    @\unspec@ quoted(basic_string_view<charT, traits> s,
    @\itcorr@                   charT delim = charT('"'), charT escape = charT('\\'));
}
\end{codeblock}

\rSec2[print.syn]{Header \tcode{<print>} synopsis}

\indexheader{print}%
\begin{codeblock}
namespace std {
  // \ref{print.fun}, print functions
  template<class... Args>
    void print(format_string<Args...> fmt, Args&&... args);
  template<class... Args>
    void print(FILE* stream, format_string<Args...> fmt, Args&&... args);

  template<class... Args>
    void println(format_string<Args...> fmt, Args&&... args);
  void println();
  template<class... Args>
    void println(FILE* stream, format_string<Args...> 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 charT, class traits = char_traits<charT>>
  class basic_istream : virtual public basic_ios<charT, traits> {
  public:
    // types (inherited from \tcode{basic_ios}\iref{ios})
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{istream.cons}, constructor/destructor
    explicit basic_istream(basic_streambuf<charT, traits>* 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<charT, traits>& (*pf)(basic_ios<charT, traits>&));
    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<char_type, traits>* 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<char_type, traits>& sb);
    basic_istream& get(basic_streambuf<char_type, traits>& 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());
    basic_istream& ignore(streamsize n, char_type delim);
    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<class charT, class traits>
    basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT&);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, unsigned char&);
  template<class traits>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, signed char&);

  template<class charT, class traits, size_t N>
    basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>&, charT(&)[N]);
  template<class traits, size_t N>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, unsigned char(&)[N]);
  template<class traits, size_t N>
    basic_istream<char, traits>& operator>>(basic_istream<char, traits>&, 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<charT, traits>* 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<charT, traits>::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<charT, traits>::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 charT, class traits>
  class basic_istream<charT, traits>::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<charT>& ctype = use_facet<ctype<charT>>(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<charT, istreambuf_iterator<charT, traits>>;
use_facet<numget>(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<charT, istreambuf_iterator<charT, traits>>;
long lval;
use_facet<numget>(loc).get(*this, 0, *this, state, lval);
if (lval < numeric_limits<short>::min()) {
  state |= ios_base::failbit;
  val = numeric_limits<short>::min();
} else if (numeric_limits<short>::max() < lval) {
  state |= ios_base::failbit;
  val = numeric_limits<short>::max();
} else
  val = static_cast<short>(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<charT, istreambuf_iterator<charT, traits>>;
long lval;
use_facet<numget>(loc).get(*this, 0, *this, state, lval);
if (lval < numeric_limits<int>::min()) {
  state |= ios_base::failbit;
  val = numeric_limits<int>::min();
} else if (numeric_limits<int>::max() < lval) {
  state |= ios_base::failbit;
  val = numeric_limits<int>::max();
} else
  val = static_cast<int>(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<charT, istreambuf_iterator<charT, traits>>;
FP fval;
use_facet<numget>(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<charT, traits>& (*pf)(basic_ios<charT, traits>&));
\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<class charT, class traits, size_t N>
  basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT (&s)[N]);
template<class traits, size_t N>
  basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, unsigned char (&s)[N]);
template<class traits, size_t N>
  basic_istream<char, traits>& operator>>(basic_istream<char, traits>& 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<ctype<charT>>(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<class charT, class traits>
  basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in, charT& c);
template<class traits>
  basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in, unsigned char& c);
template<class traits>
  basic_istream<char, traits>& operator>>(basic_istream<char, traits>& 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<charT, traits>* 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<streamsize>::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<char_type, traits>& 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<char_type, traits>& 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 <iostream>

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<streamsize>::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{ignore}{basic_istream}%
\begin{itemdecl}
basic_istream& ignore(streamsize n, char_type delim);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<char_type, char>} is \tcode{true}.

\pnum
\effects
Equivalent to: \tcode{return ignore(n, traits::to_int_type(delim));}
\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<class charT, class traits>
  basic_istream<charT, traits>& ws(basic_istream<charT, traits>& 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<class Istream, class T>
  Istream&& operator>>(Istream&& is, T&& x);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
The expression \tcode{is >> std::forward<T>(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<T>(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 charT, class traits = char_traits<charT>>
  class basic_iostream
    : public basic_istream<charT, traits>,
      public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{iostream.cons}, constructor
    explicit basic_iostream(basic_streambuf<charT, traits>* 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<charT, traits>* sb);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class subobjects with
\tcode{basic_istream<charT, traits>(sb)}\iref{istream}
and
\tcode{basic_ostream<charT, traits>(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<charT, traits>::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 charT, class traits = char_traits<charT>>
  class basic_ostream : virtual public basic_ios<charT, traits> {
  public:
    // types (inherited from \tcode{basic_ios}\iref{ios})
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{ostream.cons}, constructor/destructor
    explicit basic_ostream(basic_streambuf<char_type, traits>* 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<charT, traits>& (*pf)(basic_ios<charT, traits>&));
    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<char_type, traits>* 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<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, charT);
  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, char);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char);

  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, signed char);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, unsigned char);

  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, wchar_t) = delete;
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char8_t) = delete;
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char16_t) = delete;
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char32_t) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, char8_t) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, char16_t) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, char32_t) = delete;

  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const charT*);
  template<class charT, class traits>
    basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);

  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const signed char*);
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const unsigned char*);

  template<class traits>
    basic_ostream<char, traits>&
      operator<<(basic_ostream<char, traits>&, const wchar_t*) = delete;
  template<class traits>
    basic_ostream<char, traits>&
      operator<<(basic_ostream<char, traits>&, const char8_t*) = delete;
  template<class traits>
    basic_ostream<char, traits>&
      operator<<(basic_ostream<char, traits>&, const char16_t*) = delete;
  template<class traits>
    basic_ostream<char, traits>&
      operator<<(basic_ostream<char, traits>&, const char32_t*) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, const char8_t*) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, const char16_t*) = delete;
  template<class traits>
    basic_ostream<wchar_t, traits>&
      operator<<(basic_ostream<wchar_t, traits>&, 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<charT, traits>* sb);
\end{itemdecl}

\indexlibrarymember{init}{basic_ostream}%
\begin{itemdescr}
\pnum
\effects
Initializes the base class subobject with
\tcode{basic_ios<charT, traits>::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<charT, traits>::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<charT, traits>::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 charT, class traits>
  class basic_ostream<charT, traits>::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$ or
exits via an exception, 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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(),
    baseflags == ios_base::oct || baseflags == ios_base::hex
      ? static_cast<long>(static_cast<unsigned short>(val))
      : static_cast<long>(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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(),
    baseflags == ios_base::oct || baseflags == ios_base::hex
      ? static_cast<long>(static_cast<unsigned int>(val))
      : static_cast<long>(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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(), static_cast<unsigned long>(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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(), static_cast<double>(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<const void*>(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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(), static_cast<double>(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<num_put<charT, ostreambuf_iterator<charT, traits>>>(
  getloc()).put(*this, *this, fill(), static_cast<long double>(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<charT, traits>& (*pf)(basic_ios<charT, traits>&));
\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<charT, traits>* 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<charT, traits>\& 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<class charT, class traits>
  basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, charT c);
template<class charT, class traits>
  basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, char c);
// specialization
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, char c);
// signed and unsigned
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, signed char c);
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& 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<class charT, class traits>
  basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, const charT* s);
template<class charT, class traits>
  basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& out, const char* s);
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, const char* s);
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& out, const signed char* s);
template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>& 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<charT, traits>\&}
and the second is of type
\tcode{const charT*},
and also for the overload where the first argument is of type
\tcode{basic_ostream<char, traits>\&}
and the second is of type
\tcode{const char*},
\item
\tcode{char_traits<char>::length(s)}
for the overload where the first argument is of type
\tcode{basic_ostream<charT, traits>\&}
and the second is of type
\tcode{const char*},
\item
\tcode{traits::length(reinterpret_cast<const char*>(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<class... Args>
  void print(ostream& os, format_string<Args...> 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<class... Args>
  void println(ostream& os, format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
print(os, "{}\n", format(os.getloc(), fmt, std::forward<Args>(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}

\par % This paragraph is part of the \effects clause.
After constructing a \tcode{sentry} object,
the function initializes a variable with automatic storage duration via
\begin{codeblock}
string out = vformat(os.getloc(), fmt, args);
\end{codeblock}
\begin{itemize}
\item
If the function is \tcode{vprint_unicode} and
\tcode{os} is a stream that refers to a terminal that
is capable of displaying Unicode only via a native Unicode API,
which is determined in an implementation-defined manner,
flushes \tcode{os} and then
writes \tcode{out} to the terminal using the native Unicode API;
if \tcode{out} contains invalid code units,
\indextext{undefined}%
the behavior is undefined.
Then establishes an observable checkpoint\iref{intro.abstract}.
\item
Otherwise
inserts the character sequence
\range{out.begin()}{out.end()} into \tcode{os}.
\end{itemize}

\par % This paragraph is part of the \effects clause.
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<class charT, class traits>
  basic_ostream<charT, traits>& endl(basic_ostream<charT, traits>& 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<class charT, class traits>
  basic_ostream<charT, traits>& ends(basic_ostream<charT, traits>& 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<class charT, class traits>
  basic_ostream<charT, traits>& flush(basic_ostream<charT, traits>& os);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls
\tcode{os.flush()}.

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\indexlibraryglobal{emit_on_flush}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>& emit_on_flush(basic_ostream<charT, traits>& os);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{os.rdbuf()} is a
\tcode{basic_syncbuf<charT, traits, Allocator>*},
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<class charT, class traits>
  basic_ostream<charT, traits>& noemit_on_flush(basic_ostream<charT, traits>& os);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If \tcode{os.rdbuf()} is a
\tcode{basic_syncbuf<charT, traits, Allocator>*},
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<class charT, class traits>
  basic_ostream<charT, traits>& flush_emit(basic_ostream<charT, traits>& os);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Calls \tcode{os.flush()}.
Then, if \tcode{os.rdbuf()} is a
\tcode{basic_syncbuf<charT, traits, Allocator>*},
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<class Ostream, class T>
  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<charT, traits>} 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<charT, traits>} 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<charT, traits>} 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<charT, traits>} 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<charT, traits>\&} and value \tcode{out}. The
expression \tcode{in >> resetiosflags(mask)} has type
\tcode{basic_istream<charT, traits>\&} 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<charT, traits>}
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<charT, traits>}
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<charT, traits>\&}
and value
\tcode{out}.
The expression
\tcode{in >> setiosflags(mask)}
has type
\tcode{basic_istream<charT, traits>\&}
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<charT, traits>}
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<charT, traits>}
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<charT, traits>\&}
and value
\tcode{out}.
The expression
\tcode{in >> setbase(base)}
has type
\tcode{basic_istream<charT, traits>\&}
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<charT, traits>}
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<class charT, class traits>
void f(basic_ios<charT, traits>& str, charT c) {
  // set fill character
  str.fill(c);
}
\end{codeblock}

The expression
\tcode{out << setfill(c)}
has type
\tcode{basic_ostream<charT, traits>\&}
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<charT, traits>}
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<charT, traits>}
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<charT, traits>\&}
and value
\tcode{out}.
The expression
\tcode{in >> setprecision(n)}
has type
\tcode{basic_istream<charT, traits>\&}
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<charT, traits>}
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<charT, traits>}
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<charT, traits>\&}
and value
\tcode{out}.
The expression
\tcode{in >> setw(n)}
has type
\tcode{basic_istream<charT, traits>\&}
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<class moneyT> @\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<charT, traits>}
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<class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, moneyT& mon, bool intl) {
  using Iter     = istreambuf_iterator<charT, traits>;
  using MoneyGet = money_get<charT, Iter>;

  ios_base::iostate err = ios_base::goodbit;
  const MoneyGet& mg = use_facet<MoneyGet>(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<charT, traits>\&} and value \tcode{in}.
\end{itemdescr}

\indexlibraryglobal{put_money}%
\begin{itemdecl}
template<class moneyT> @\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<charT, traits>}
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<class charT, class traits, class moneyT>
void f(basic_ios<charT, traits>& str, const moneyT& mon, bool intl) {
  using Iter     = ostreambuf_iterator<charT, traits>;
  using MoneyPut = money_put<charT, Iter>;

  const MoneyPut& mp = use_facet<MoneyPut>(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<charT, traits>\&} and value \tcode{out}.
\end{itemdescr}

\indexlibraryglobal{get_time}%
\begin{itemdecl}
template<class charT> @\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<charT>::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<charT, traits>} 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<class charT, class traits>
void f(basic_ios<charT, traits>& str, tm* tmb, const charT* fmt) {
  using Iter    = istreambuf_iterator<charT, traits>;
  using TimeGet = time_get<charT, Iter>;

  ios_base::iostate err = ios_base::goodbit;
  const TimeGet& tg = use_facet<TimeGet>(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<charT, traits>\&} and value \tcode{in}.
\end{itemdescr}

\indexlibraryglobal{put_time}%
\begin{itemdecl}
template<class charT> @\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<charT>::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<charT, traits>} 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<class charT, class traits>
void f(basic_ios<charT, traits>& str, const tm* tmb, const charT* fmt) {
  using Iter    = ostreambuf_iterator<charT, traits>;
  using TimePut = time_put<charT, Iter>;

  const TimePut& tp = use_facet<TimePut>(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<charT, traits>\&} 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<class charT>
  @\unspec@ quoted(const charT* s, charT delim = charT('"'), charT escape = charT('\\'));
template<class charT, class traits, class Allocator>
  @\unspec@ quoted(const basic_string<charT, traits, Allocator>& s,
  @\itcorr@                   charT delim = charT('"'), charT escape = charT('\\'));
template<class charT, class traits>
  @\unspec@ quoted(basic_string_view<charT, traits> 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<charT, traits>\&} and value \tcode{out}.
\end{itemdescr}

\indexlibraryglobal{quoted}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  @\unspec@ quoted(basic_string<charT, traits, Allocator>& 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, traits>\&, 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<charT, traits, Allocator>\&} overload of the
\tcode{quoted} function.
\item
The expression \tcode{in >> quoted(s, delim, escape)} has type
\tcode{basic_istream<charT, traits>\&} and value \tcode{in}.
\item
The expression \tcode{out << quoted(s, delim, escape)} has type
\tcode{basic_ostream\brk{}<charT, traits>\&} and value \tcode{out}.
\end{itemize}
\end{itemdescr}

\rSec2[print.fun]{Print functions}

\indexlibraryglobal{print}%
\begin{itemdecl}
template<class... Args>
  void print(format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
print(stdout, fmt, std::forward<Args>(args)...);
\end{codeblock}
\end{itemdescr}

\indexlibraryglobal{print}%
\begin{itemdecl}
template<class... Args>
  void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Let \tcode{locksafe} be
\tcode{(enable_nonlocking_formatter_optimization<remove_cvref_t<Args>> \&\& ...)}.
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<class... Args>
  void println(format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
println(stdout, fmt, std::forward<Args>(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<class... Args>
  void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
print(stream, dynamic_format(string(fmt.get()) + '\n'), std::forward<Args>(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}.
\begin{itemize}
\item
If \tcode{stream} refers to a terminal that
is capable of displaying Unicode only via a native Unicode API,
flushes \tcode{stream} and then
writes \tcode{out} to the terminal using the native Unicode API;
if \tcode{out} contains invalid code units,
\indextext{undefined}%
the behavior is undefined.
Then establishes an observable checkpoint\iref{intro.abstract}.
\item
Otherwise writes \tcode{out} to \tcode{stream} unchanged.
\end{itemize}
Unconditionally unlocks \tcode{stream} on function exit.

\xrefc{7.23.2}.

\begin{note}
On Windows the native Unicode API is \tcode{WriteConsoleW} and
\tcode{stream} referring to a terminal means that
\tcode{GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)}
returns nonzero.
\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(stream, "{}", 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{<sstream>} synopsis}

\indexheader{sstream}%
\indexlibraryglobal{stringbuf}%
\indexlibraryglobal{basic_stringbuf<char>}%
\indexlibraryglobal{wstringbuf}%
\indexlibraryglobal{basic_stringbuf<wchar_t>}%
\indexlibraryglobal{istringstream}%
\indexlibraryglobal{basic_istringstream<char>}%
\indexlibraryglobal{wistringstream}%
\indexlibraryglobal{basic_istringstream<wchar_t>}%
\indexlibraryglobal{ostringstream}%
\indexlibraryglobal{basic_ostringstream<char>}%
\indexlibraryglobal{wostringstream}%
\indexlibraryglobal{basic_ostringstream<wchar_t>}%
\indexlibraryglobal{stringstream}%
\indexlibraryglobal{basic_stringstream<char>}%
\indexlibraryglobal{wstringstream}%
\indexlibraryglobal{basic_stringstream<wchar_t>}%
\begin{codeblock}
namespace std {
  // \ref{stringbuf}, class template \tcode{basic_stringbuf}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_stringbuf;

  template<class charT, class traits, class Allocator>
    void swap(basic_stringbuf<charT, traits, Allocator>& x,
              basic_stringbuf<charT, traits, Allocator>& y) noexcept(noexcept(x.swap(y)));

  using stringbuf  = basic_stringbuf<char>;
  using wstringbuf = basic_stringbuf<wchar_t>;

  // \ref{istringstream}, class template \tcode{basic_istringstream}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_istringstream;

  template<class charT, class traits, class Allocator>
    void swap(basic_istringstream<charT, traits, Allocator>& x,
              basic_istringstream<charT, traits, Allocator>& y);

  using istringstream  = basic_istringstream<char>;
  using wistringstream = basic_istringstream<wchar_t>;

  // \ref{ostringstream}, class template \tcode{basic_ostringstream}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_ostringstream;

  template<class charT, class traits, class Allocator>
    void swap(basic_ostringstream<charT, traits, Allocator>& x,
              basic_ostringstream<charT, traits, Allocator>& y);

  using ostringstream  = basic_ostringstream<char>;
  using wostringstream = basic_ostringstream<wchar_t>;

  // \ref{stringstream}, class template \tcode{basic_stringstream}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_stringstream;

  template<class charT, class traits, class Allocator>
    void swap(basic_stringstream<charT, traits, Allocator>& x,
              basic_stringstream<charT, traits, Allocator>& y);

  using stringstream  = basic_stringstream<char>;
  using wstringstream = basic_stringstream<wchar_t>;
}
\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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_stringbuf : public basic_streambuf<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = traits::int_type;
    using pos_type       = traits::pos_type;
    using off_type       = 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<charT, traits, Allocator>& 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<charT, traits, Allocator>&& s,
      ios_base::openmode which = ios_base::in | ios_base::out);
    template<class SAlloc>
      basic_stringbuf(
        const basic_string<charT, traits, SAlloc>& s, const Allocator& a)
        : basic_stringbuf(s, ios_base::in | ios_base::out, a) {}
    template<class SAlloc>
      basic_stringbuf(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which, const Allocator& a);
    template<class SAlloc>
      explicit basic_stringbuf(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which = ios_base::in | ios_base::out);
    template<class T>
      explicit basic_stringbuf(const T& t,
                               ios_base::openmode which = ios_base::in | ios_base::out);
    template<class T>
      basic_stringbuf(const T& t, const Allocator& a);
    template<class T>
      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<charT, traits, Allocator> str() const &;
    template<class SAlloc>
      basic_string<charT,traits,SAlloc> str(const SAlloc& sa) const;
    basic_string<charT, traits, Allocator> str() &&;
    basic_string_view<charT, traits> view() const noexcept;

    void str(const basic_string<charT, traits, Allocator>& s);
    template<class SAlloc>
      void str(const basic_string<charT, traits, SAlloc>& s);
    void str(basic_string<charT, traits, Allocator>&& s);
    template<class T>
      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<charT, traits>* 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<charT, traits, Allocator> @\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<charT, traits, Allocator> \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<charT, traits, Allocator>& 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<charT, traits, Allocator>&& 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<class SAlloc>
  basic_stringbuf(
    const basic_string<charT, traits, SAlloc>& 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<class SAlloc>
  explicit basic_stringbuf(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which = ios_base::in | ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<SAlloc, Allocator>} 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<class T>
  explicit basic_stringbuf(const T& t, ios_base::openmode which = ios_base::in | ios_base::out);
template<class T>
  basic_stringbuf(const T& t, const Allocator& a);
template<class T>
  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<const T\&, basic_string_view<charT, traits>>}
is \tcode{true}.

\pnum
\effects
Creates a variable \tcode{sv} as if by
\tcode{basic_string_view<charT, traits> 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<Allocator>::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<Allocator>::propagate_on_container_swap::value ||}\\
\tcode{allocator_traits<Allocator>::is_always_equal::value}
\end{itemdescr}

\indexlibrarymember{swap}{basic_stringbuf}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  void swap(basic_stringbuf<charT, traits, Allocator>& x,
            basic_stringbuf<charT, traits, Allocator>& 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}@();
\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<charT, traits, Allocator> str() const &;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return basic_string<charT, traits, Allocator>(view(), get_allocator());
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{str}{basic_stringbuf}%
\begin{itemdecl}
template<class SAlloc>
  basic_string<charT, traits, SAlloc> 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<charT, traits, SAlloc>(view(), sa);
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
basic_string<charT, traits, Allocator> 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<charT, traits, Allocator>} 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<charT, traits> view() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{sv} be \tcode{basic_string_view<charT, traits>}.

\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<charT, traits, Allocator>& 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<class SAlloc>
  void str(const basic_string<charT, traits, SAlloc>& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<SAlloc, Allocator>} 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<charT, traits, Allocator>&& 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<class T>
  void str(const T& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const T\&, basic_string_view<charT, traits>>}
is \tcode{true}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
basic_string_view<charT, traits> 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<charT, traits>* 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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_istringstream : public basic_istream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = traits::int_type;
    using pos_type       = traits::pos_type;
    using off_type       = 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<charT, traits, Allocator>& s,
      ios_base::openmode which = ios_base::in);
    basic_istringstream(ios_base::openmode which, const Allocator& a);
    explicit basic_istringstream(
      basic_string<charT, traits, Allocator>&& s,
      ios_base::openmode which = ios_base::in);
    template<class SAlloc>
      basic_istringstream(
        const basic_string<charT, traits, SAlloc>& s, const Allocator& a)
        : basic_istringstream(s, ios_base::in, a) {}
    template<class SAlloc>
      basic_istringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which, const Allocator& a);
    template<class SAlloc>
      explicit basic_istringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which = ios_base::in);
    template<class T>
      explicit basic_istringstream(const T& t, ios_base::openmode which = ios_base::in);
    template<class T>
      basic_istringstream(const T& t, const Allocator& a);
    template<class T>
      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<charT, traits, Allocator>* rdbuf() const;
    basic_string<charT, traits, Allocator> str() const &;
    template<class SAlloc>
      basic_string<charT,traits,SAlloc> str(const SAlloc& sa) const;
    basic_string<charT, traits, Allocator> str() &&;
    basic_string_view<charT, traits> view() const noexcept;

    void str(const basic_string<charT, traits, Allocator>& s);
    template<class SAlloc>
      void str(const basic_string<charT, traits, SAlloc>& s);
    void str(basic_string<charT, traits, Allocator>&& s);
    template<class T>
      void str(const T& t);

  private:
    basic_stringbuf<charT, traits, Allocator> @\exposid{sb}@;   // \expos
  };
}
\end{codeblock}

\pnum
The class
\tcode{basic_istringstream<charT, traits, Allocator>}
supports reading objects of class
\tcode{basic_string<\brk{}charT, traits, Allocator>}.
It uses a
\tcode{basic_stringbuf<charT, traits, Allocator>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(which | ios_base::in)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_istringstream}%
\begin{itemdecl}
explicit basic_istringstream(
  const basic_string<charT, traits, Allocator>& s,
  ios_base::openmode which = ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_istream<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(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<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(which | ios_base::in, a)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_istringstream}%
\begin{itemdecl}
explicit basic_istringstream(
  basic_string<charT, traits, Allocator>&& s,
  ios_base::openmode which = ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_istream<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(std::move(s), which | ios_base::\brk{}in)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_istringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_istringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_istream<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which | ios_base::in, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull
\end{itemdescr}

\indexlibraryctor{basic_istringstream}%
\begin{itemdecl}
template<class SAlloc>
  explicit basic_istringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which = ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<SAlloc, Allocator>} is \tcode{false}.

\pnum
\effects
Initializes the base class with
\tcode{basic_istream<charT, traits>(addressof(\exposid{sb}))}\iref{istream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which | ios_base::in)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_istringstream}%
\begin{itemdecl}
template<class T>
  explicit basic_istringstream(const T& t, ios_base::openmode which = ios_base::in);
template<class T>
  basic_istringstream(const T& t, const Allocator& a);
template<class T>
  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<const T\&, basic_string_view<charT, traits>>}
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<charT, traits>::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<charT, traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}


\indexlibrarymember{swap}{basic_istringstream}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  void swap(basic_istringstream<charT, traits, Allocator>& x,
            basic_istringstream<charT, traits, Allocator>& 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<charT, traits, Allocator>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_stringbuf<charT, traits, Allocator>*>(addressof(\exposid{sb}))}.
\end{itemdescr}

\indexlibrarymember{str}{basic_istringstream}%
\begin{itemdecl}
basic_string<charT, traits, Allocator> str() const &;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return rdbuf()->str();}
\end{itemdescr}

\indexlibrarymember{str}{basic_istringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_string<charT,traits,SAlloc> 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<charT,traits,Allocator> 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<charT, traits> 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<charT, traits, Allocator>& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(s);}
\end{itemdescr}

\indexlibrarymember{str}{basic_istringstream}%
\begin{itemdecl}
template<class SAlloc>
  void str(const basic_string<charT, traits, SAlloc>& 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<charT, traits, Allocator>&& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(std::move(s));}
\end{itemdescr}

\indexlibrarymember{str}{basic_istringstream}%
\begin{itemdecl}
template<class T>
  void str(const T& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const T\&, basic_string_view<charT, traits>>}
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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_ostringstream : public basic_ostream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = traits::int_type;
    using pos_type       = traits::pos_type;
    using off_type       = 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<charT, traits, Allocator>& s,
      ios_base::openmode which = ios_base::out);
    basic_ostringstream(ios_base::openmode which, const Allocator& a);
    explicit basic_ostringstream(
      basic_string<charT, traits, Allocator>&& s,
      ios_base::openmode which = ios_base::out);
    template<class SAlloc>
      basic_ostringstream(
        const basic_string<charT, traits, SAlloc>& s, const Allocator& a)
        : basic_ostringstream(s, ios_base::out, a) {}
    template<class SAlloc>
      basic_ostringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which, const Allocator& a);
    template<class SAlloc>
      explicit basic_ostringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which = ios_base::out);
    template<class T>
      explicit basic_ostringstream(const T& t, ios_base::openmode which = ios_base::out);
    template<class T>
      basic_ostringstream(const T& t, const Allocator& a);
    template<class T>
      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<charT, traits, Allocator>* rdbuf() const;

    basic_string<charT, traits, Allocator> str() const &;
    template<class SAlloc>
      basic_string<charT,traits,SAlloc> str(const SAlloc& sa) const;
    basic_string<charT, traits, Allocator> str() &&;
    basic_string_view<charT, traits> view() const noexcept;

    void str(const basic_string<charT, traits, Allocator>& s);
    template<class SAlloc>
      void str(const basic_string<charT, traits, SAlloc>& s);
    void str(basic_string<charT, traits, Allocator>&& s);
    template<class T>
      void str(const T& t);

  private:
    basic_stringbuf<charT, traits, Allocator> @\exposid{sb}@;   // \expos
  };
}
\end{codeblock}

\pnum
The class
\tcode{basic_ostringstream<charT, traits, Allocator>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(which | ios_base::out)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_ostringstream}%
\begin{itemdecl}
explicit basic_ostringstream(
  const basic_string<charT, traits, Allocator>& s,
  ios_base::openmode which = ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_ostream<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(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<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull
\end{itemdescr}

\indexlibraryctor{basic_ostringstream}%
\begin{itemdecl}
explicit basic_ostringstream(
  basic_string<charT, traits, Allocator>&& s,
  ios_base::openmode which = ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_ostream<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(std::move(s), which | ios_base::\brk{}out)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_ostringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_ostringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_ostream<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which | ios_base::out, a)}\linebreak\iref{stringbuf.cons}. % avoid Overfull
\end{itemdescr}

\indexlibraryctor{basic_ostringstream}%
\begin{itemdecl}
template<class SAlloc>
  explicit basic_ostringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which = ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<SAlloc, Allocator>} is \tcode{false}.

\pnum
\effects
Initializes the base class with
\tcode{basic_ostream<charT, traits>(addressof(\exposid{sb}))}\iref{ostream}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which | ios_base::out)}\linebreak\iref{stringbuf.cons}. % avoid Overfull
\end{itemdescr}

\indexlibraryctor{basic_ostringstream}%
\begin{itemdecl}
template<class T>
  explicit basic_ostringstream(const T& t, ios_base::openmode which = ios_base::out);
template<class T>
  basic_ostringstream(const T& t, const Allocator& a);
template<class T>
  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<const T\&, basic_string_view<charT, traits>>}
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<charT, traits>::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<charT, traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{swap}{basic_ostringstream}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  void swap(basic_ostringstream<charT, traits, Allocator>& x,
            basic_ostringstream<charT, traits, Allocator>& 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<charT, traits, Allocator>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_stringbuf<charT, traits, Allocator>*>(addressof(\exposid{sb}))}.
\end{itemdescr}

\indexlibrarymember{str}{basic_ostringstream}%
\begin{itemdecl}
basic_string<charT, traits, Allocator> str() const &;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return rdbuf()->str();}
\end{itemdescr}

\indexlibrarymember{str}{basic_ostringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_string<charT,traits,SAlloc> 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<charT,traits,Allocator> 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<charT, traits> 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<charT, traits, Allocator>& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(s);}
\end{itemdescr}

\indexlibrarymember{str}{basic_ostringstream}%
\begin{itemdecl}
template<class SAlloc>
  void str(const basic_string<charT, traits, SAlloc>& 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<charT, traits, Allocator>&& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(std::move(s));}
\end{itemdescr}

\indexlibrarymember{str}{basic_ostringstream}%
\begin{itemdecl}
template<class T>
  void str(const T& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const T\&, basic_string_view<charT, traits>>}
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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_stringstream : public basic_iostream<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = traits::int_type;
    using pos_type       = traits::pos_type;
    using off_type       = 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<charT, traits, Allocator>& 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<charT, traits, Allocator>&& s,
      ios_base::openmode which = ios_base::out | ios_base::in);
    template<class SAlloc>
      basic_stringstream(
        const basic_string<charT, traits, SAlloc>& s, const Allocator& a)
        : basic_stringstream(s, ios_base::out | ios_base::in, a) {}
    template<class SAlloc>
      basic_stringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which, const Allocator& a);
    template<class SAlloc>
      explicit basic_stringstream(
        const basic_string<charT, traits, SAlloc>& s,
        ios_base::openmode which = ios_base::out | ios_base::in);
    template<class T>
      explicit basic_stringstream(const T& t,
                                  ios_base::openmode which = ios_base::out | ios_base::in);
    template<class T>
      basic_stringstream(const T& t, const Allocator& a);
    template<class T>
      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<charT, traits, Allocator>* rdbuf() const;

    basic_string<charT, traits, Allocator> str() const &;
    template<class SAlloc>
      basic_string<charT,traits,SAlloc> str(const SAlloc& sa) const;
    basic_string<charT, traits, Allocator> str() &&;
    basic_string_view<charT, traits> view() const noexcept;

    void str(const basic_string<charT, traits, Allocator>& s);
    template<class SAlloc>
      void str(const basic_string<charT, traits, SAlloc>& s);
    void str(basic_string<charT, traits, Allocator>&& s);
    template<class T>
      void str(const T& t);

  private:
    basic_stringbuf<charT, traits, Allocator> @\exposid{sb}@;   // \expos
  };
}
\end{codeblock}

\pnum
The
class template
\tcode{basic_stringstream<charT, traits>}
supports reading and writing from objects of class
\tcode{basic_string<charT, traits, Allocator>}.
It uses a
\tcode{basic_stringbuf<charT, traits, Alloca\-tor>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and
\exposid{sb}
with
\tcode{basic_string\-buf<charT, traits, Allocator>(which)}.
\end{itemdescr}

\indexlibraryctor{basic_stringstream}%
\begin{itemdecl}
explicit basic_stringstream(
  const basic_string<charT, traits, Allocator>& 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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and
\exposid{sb}
with
\tcode{basic_string\-buf<charT, traits, Allocator>(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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(which, a)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_stringstream}%
\begin{itemdecl}
explicit basic_stringstream(
  basic_string<charT, traits, Allocator>&& 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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(std::move(s), which)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_stringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_stringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which, const Allocator& a);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_iostream<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which, a)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_stringstream}%
\begin{itemdecl}
template<class SAlloc>
  explicit basic_stringstream(
    const basic_string<charT, traits, SAlloc>& s,
    ios_base::openmode which = ios_base::out | ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<SAlloc, Allocator>} is \tcode{false}.

\pnum
\effects
Initializes the base class with
\tcode{basic_iostream<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and \exposid{sb} with
\tcode{basic_stringbuf<charT, traits, Allocator>(s, which)}\iref{stringbuf.cons}.
\end{itemdescr}

\indexlibraryctor{basic_stringstream}%
\begin{itemdecl}
template<class T>
  explicit basic_stringstream(const T& t, ios_base::openmode which = ios_base::out | ios_base::in);
template<class T>
  basic_stringstream(const T& t, const Allocator& a);
template<class T>
  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<const T\&, basic_string_view<charT, traits>>}
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<charT, traits>::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<charT,traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{swap}{basic_stringstream}%
\begin{itemdecl}
template<class charT, class traits, class Allocator>
  void swap(basic_stringstream<charT, traits, Allocator>& x,
            basic_stringstream<charT, traits, Allocator>& 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<charT, traits, Allocator>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_stringbuf<charT, traits, Allocator>*>(addressof(\exposid{sb}))}.
\end{itemdescr}

\indexlibrarymember{str}{basic_stringstream}%
\begin{itemdecl}
basic_string<charT, traits, Allocator> str() const &;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return rdbuf()->str();}
\end{itemdescr}

\indexlibrarymember{str}{basic_stringstream}%
\begin{itemdecl}
template<class SAlloc>
  basic_string<charT,traits,SAlloc> 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<charT,traits,Allocator> 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<charT, traits> 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<charT, traits, Allocator>& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(s);}
\end{itemdescr}

\indexlibrarymember{str}{basic_stringstream}%
\begin{itemdecl}
template<class SAlloc>
  void str(const basic_string<charT, traits, SAlloc>& 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<charT, traits, Allocator>&& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rdbuf()->str(std::move(s));}
\end{itemdescr}

\indexlibrarymember{str}{basic_stringstream}%
\begin{itemdecl}
template<class T>
  void str(const T& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const T\&, basic_string_view<charT, traits>>}
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{<spanstream>} 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 charT, class traits = char_traits<charT>>
    class basic_spanbuf;

  template<class charT, class traits>
    void swap(basic_spanbuf<charT, traits>& x, basic_spanbuf<charT, traits>& y);

  using spanbuf = basic_spanbuf<char>;
  using wspanbuf = basic_spanbuf<wchar_t>;

  // \ref{ispanstream}, class template \tcode{basic_ispanstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_ispanstream;

  template<class charT, class traits>
    void swap(basic_ispanstream<charT, traits>& x, basic_ispanstream<charT, traits>& y);

  using ispanstream = basic_ispanstream<char>;
  using wispanstream = basic_ispanstream<wchar_t>;

  // \ref{ospanstream}, class template \tcode{basic_ospanstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_ospanstream;

  template<class charT, class traits>
    void swap(basic_ospanstream<charT, traits>& x, basic_ospanstream<charT, traits>& y);

  using ospanstream = basic_ospanstream<char>;
  using wospanstream = basic_ospanstream<wchar_t>;

  // \ref{spanstream}, class template \tcode{basic_spanstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_spanstream;

  template<class charT, class traits>
    void swap(basic_spanstream<charT, traits>& x, basic_spanstream<charT, traits>& y);

  using spanstream = basic_spanstream<char>;
  using wspanstream = basic_spanstream<wchar_t>;
}
\end{codeblock}

\rSec2[spanbuf]{Class template \tcode{basic_spanbuf}}

\rSec3[spanbuf.general]{General}

\indexlibraryglobal{basic_spanbuf}%
\begin{codeblock}
namespace std {
  template<class charT, class traits = char_traits<charT>>
  class basic_spanbuf
    : public basic_streambuf<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = 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<charT>(), which) {}
    explicit basic_spanbuf(std::span<charT> 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<charT> span() const noexcept;
    void span(std::span<charT> s) noexcept;

  protected:
    // \ref{spanbuf.virtuals}, overridden virtual functions
    basic_streambuf<charT, traits>* 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<charT> @\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<charT>}.

\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<charT> \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<charT> 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<charT, traits>::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<class charT, class traits>
  void swap(basic_spanbuf<charT, traits>& x, basic_spanbuf<charT, traits>& 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<charT> span() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{ios_base::out} is set in \exposid{mode},
returns \tcode{std::span<charT>(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<charT>}.
\end{note}
\end{itemdescr}

\indexlibrarymember{span}{basic_spanbuf}%
\begin{itemdecl}
void span(std::span<charT> 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<charT, traits>* setbuf(charT* s, streamsize n) override;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
this->span(std::span<charT>(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 charT, class traits = char_traits<charT>>
  class basic_ispanstream
    : public basic_istream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{ispanstream.cons}, constructors
    explicit basic_ispanstream(std::span<charT> s,
                               ios_base::openmode which = ios_base::in);
    basic_ispanstream(const basic_ispanstream&) = delete;
    basic_ispanstream(basic_ispanstream&& rhs);
    template<class ROS> 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<charT, traits>* rdbuf() const noexcept;

    std::span<const charT> span() const noexcept;
    void span(std::span<charT> s) noexcept;
    template<class ROS> void span(ROS&& s) noexcept;

  private:
    basic_spanbuf<charT, traits> @\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<charT> s, ios_base::openmode which = ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_istream<charT, traits>(addressof(\exposid{sb}))}
and \exposid{sb} with
\tcode{basic_spanbuf<charT, traits>(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<charT, traits>::set_rdbuf(addressof(\exposid{sb}))} is called
to install the contained \tcode{ba\-sic_\-span\-buf}.
\end{itemdescr}

\indexlibraryctor{basic_ispanstream}%
\begin{itemdecl}
template<class ROS> explicit basic_ispanstream(ROS&& s)
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ROS} models \tcode{ranges::\libconcept{borrowed_range}}.
\tcode{!\libconcept{convertible_to}<ROS, std::span<charT>> \&\& \libconcept{convertible_to}<ROS, std::span<charT const>>}
is \tcode{true}.

\pnum
\effects
Let \tcode{sp} be \tcode{std::span<const charT>(std::forward<ROS>(s))}.
Equivalent to:
\begin{codeblock}
basic_ispanstream(std::span<charT>(const_cast<charT*>(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<charT, traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{swap}{basic_ispanstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_ispanstream<charT, traits>& x, basic_ispanstream<charT, traits>& 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<charT, traits>* rdbuf() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return const_cast<basic_spanbuf<charT, traits>*>(addressof(@\exposid{sb}@));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{span}{basic_ispanstream}%
\begin{itemdecl}
std::span<const charT> 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<charT> s) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{rdbuf()->span(s)}.
\end{itemdescr}

\begin{itemdecl}
template<class ROS> void span(ROS&& s) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ROS} models \tcode{ranges::\libconcept{borrowed_range}}.
\tcode{(!\libconcept{convertible_to}<ROS, std::span<charT>>) \&\& \libconcept{convertible_to}<ROS, std::span<const charT>>}
is \tcode{true}.

\pnum
\effects
Let \tcode{sp} be \tcode{std::span<const charT>(std::forward<ROS>(s))}.
Equivalent to:
\begin{codeblock}
this->span(std::span<charT>(const_cast<charT*>(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 charT, class traits = char_traits<charT>>
  class basic_ospanstream
    : public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{ospanstream.cons}, constructors
    explicit basic_ospanstream(std::span<charT> 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<charT, traits>* rdbuf() const noexcept;

    std::span<charT> span() const noexcept;
    void span(std::span<charT> s) noexcept;

  private:
    basic_spanbuf<charT, traits> @\exposid{sb}@;    // \expos
  };
}
\end{codeblock}

\rSec3[ospanstream.cons]{Constructors}

\indexlibraryctor{basic_ospanstream}%
\begin{itemdecl}
explicit basic_ospanstream(std::span<charT> s,
                           ios_base::openmode which = ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes the base class with
\tcode{basic_ostream<charT, traits>(addressof(\exposid{sb}))}
and \exposid{sb} with
\tcode{basic_spanbuf<charT, traits>(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<charT, traits>::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<charT, traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{swap}{basic_ospanstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_ospanstream<charT, traits>& x, basic_ospanstream<charT, traits>& 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<charT, traits>* rdbuf() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return const_cast<basic_spanbuf<charT, traits>*>(addressof(@\exposid{sb}@));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{span}{basic_ospanstream}%
\begin{itemdecl}
std::span<charT> 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<charT> 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 charT, class traits = char_traits<charT>>
  class basic_spanstream
    : public basic_iostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    // \ref{spanstream.cons}, constructors
    explicit basic_spanstream(std::span<charT> 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<charT, traits>* rdbuf() const noexcept;

    std::span<charT> span() const noexcept;
    void span(std::span<charT> s) noexcept;

  private:
    basic_spanbuf<charT, traits> @\exposid{sb}@;    // \expos
  };
}
\end{codeblock}

\rSec3[spanstream.cons]{Constructors}

\indexlibraryctor{basic_spanstream}%
\begin{itemdecl}
explicit basic_spanstream(std::span<charT> 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<charT, traits>(addressof(\exposid{sb}))}
and \exposid{sb} with
\tcode{basic_spanbuf<charT, traits>(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<charT, traits>::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<charT, traits>::swap(rhs);
@\exposid{sb}@.swap(rhs.@\exposid{sb}@);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{swap}{basic_spanstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_spanstream<charT, traits>& x, basic_spanstream<charT, traits>& 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<charT, traits>* rdbuf() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return const_cast<basic_spanbuf<charT, traits>*>(addressof(@\exposid{sb}@));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{span}{basic_spanstream}%
\begin{itemdecl}
std::span<charT> 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<charT> 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{<fstream>} synopsis}

\indexheader{fstream}%
\indexlibraryglobal{filebuf}%
\indexlibraryglobal{basic_filebuf<char>}%
\indexlibraryglobal{wfilebuf}%
\indexlibraryglobal{basic_filebuf<wchar_t>}%
\indexlibraryglobal{ifstream}%
\indexlibraryglobal{basic_ifstream<char>}%
\indexlibraryglobal{wifstream}%
\indexlibraryglobal{basic_ifstream<wchar_t>}%
\indexlibraryglobal{ofstream}%
\indexlibraryglobal{basic_ofstream<char>}%
\indexlibraryglobal{wofstream}%
\indexlibraryglobal{basic_ofstream<wchar_t>}%
\indexlibraryglobal{fstream}%
\indexlibraryglobal{basic_fstream<char>}%
\indexlibraryglobal{wfstream}%
\indexlibraryglobal{basic_fstream<wchar_t>}%
\begin{codeblock}
namespace std {
  // \ref{filebuf}, class template \tcode{basic_filebuf}
  template<class charT, class traits = char_traits<charT>>
    class basic_filebuf;

  template<class charT, class traits>
    void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& y);

  using filebuf  = basic_filebuf<char>;
  using wfilebuf = basic_filebuf<wchar_t>;

  // \ref{ifstream}, class template \tcode{basic_ifstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_ifstream;

  template<class charT, class traits>
    void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& y);

  using ifstream  = basic_ifstream<char>;
  using wifstream = basic_ifstream<wchar_t>;

  // \ref{ofstream}, class template \tcode{basic_ofstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_ofstream;

  template<class charT, class traits>
    void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& y);

  using ofstream  = basic_ofstream<char>;
  using wofstream = basic_ofstream<wchar_t>;

  // \ref{fstream}, class template \tcode{basic_fstream}
  template<class charT, class traits = char_traits<charT>>
    class basic_fstream;

  template<class charT, class traits>
    void swap(basic_fstream<charT, traits>& x, basic_fstream<charT, traits>& y);

  using fstream  = basic_fstream<char>;
  using wfstream = basic_fstream<wchar_t>;
}
\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 charT, class traits = char_traits<charT>>
  class basic_filebuf : public basic_streambuf<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = 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<charT, traits>* 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<charT, traits>}
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<charT, traits>}
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<traits::\brk{}state_type>}.
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<charT, char, typename traits::state_type>& a_codecvt =
  use_facet<codecvt<charT, char, typename traits::state_type>>(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<charT, traits>()}\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<class charT, class traits>
  void swap(basic_filebuf<charT, traits>& x, basic_filebuf<charT, traits>& 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 an 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<charT, traits>::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];
const 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<charT, traits>::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<charT, traits>::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();
const 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}
Then establishes an observable checkpoint\iref{intro.abstract}.

\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 charT, class traits = char_traits<charT>>
  class basic_ifstream : public basic_istream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;
    using native_handle_type = basic_filebuf<charT, traits>::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<class T>
      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<charT, traits>* 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<charT, traits> @\exposid{sb}@;    // \expos
  };
}
\end{codeblock}

\pnum
The class
\tcode{basic_ifstream<charT, traits>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{istream.cons}
and \exposid{sb} with
\tcode{basic_filebuf<charT, traits>()}\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<charT, traits>(addressof(\exposid{sb}))}\iref{istream.cons}
and \exposid{sb} with
\tcode{basic_filebuf<charT, traits>()}\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<class T>
  explicit basic_ifstream(const T& s, ios_base::openmode mode = ios_base::in);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<T, filesystem::path>} 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<charT, traits>::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<charT, traits>::swap(rhs)} and
\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}.
\end{itemdescr}

\indexlibrarymember{swap}{basic_ifstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_ifstream<charT, traits>& x, basic_ifstream<charT, traits>& 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<charT, traits>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_filebuf<charT, traits>*>(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 charT, class traits = char_traits<charT>>
  class basic_ofstream : public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;
    using native_handle_type = basic_filebuf<charT, traits>::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<class T>
      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<charT, traits>* 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<charT, traits> @\exposid{sb}@;    // \expos
  };
}
\end{codeblock}

\pnum
The class
\tcode{basic_ofstream<charT, traits>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{ostream.cons}
and \exposid{sb} with
\tcode{basic_filebuf<charT, traits>()}\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<charT, traits>(addressof(\exposid{sb}))}\iref{ostream.cons}
and \exposid{sb} with
\tcode{basic_filebuf<charT, traits>()}\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<class T>
  explicit basic_ofstream(const T& s, ios_base::openmode mode = ios_base::out);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_same_v<T, filesystem::path>} 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<charT, traits>::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<charT, traits>::swap(rhs)} and
\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}.
\end{itemdescr}

\indexlibrarymember{swap}{basic_ofstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_ofstream<charT, traits>& x, basic_ofstream<charT, traits>& 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<charT, traits>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_filebuf<charT, traits>*>(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 charT, class traits = char_traits<charT>>
  class basic_fstream : public basic_iostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;
    using native_handle_type = basic_filebuf<charT, traits>::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<class T>
      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<charT, traits>* 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<charT, traits> @\exposid{sb}@;    // \expos
  };
}
\end{codeblock}

\pnum
The
class template
\tcode{basic_fstream<charT, traits>}
supports reading and writing from named files.
It uses a
\tcode{basic_filebuf<charT, traits>}
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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and
\exposid{sb} with \tcode{basic_filebuf<charT, traits>()}.
\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<charT, traits>(addressof(\exposid{sb}))}\iref{iostream.cons}
and
\exposid{sb} with \tcode{basic_filebuf<charT, traits>()}.
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<class T>
  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<T, filesystem::path>} 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<charT, traits>::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<charT,traits>::swap(rhs)} and
\tcode{\exposid{sb}.swap(rhs.\exposid{sb})}.
\end{itemdescr}

\indexlibrarymember{swap}{basic_fstream}%
\begin{itemdecl}
template<class charT, class traits>
  void swap(basic_fstream<charT, traits>& x,
            basic_fstream<charT, traits>& 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<charT, traits>* rdbuf() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{const_cast<basic_filebuf<charT, traits>*>(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{<syncstream>} synopsis}

\indexheader{syncstream}%
\indexlibraryglobal{syncbuf}%
\indexlibraryglobal{wsyncbuf}%
\indexlibraryglobal{osyncstream}%
\indexlibraryglobal{wosyncstream}%
\begin{codeblock}
#include <ostream>  // see \ref{ostream.syn}

namespace std {
  // \ref{syncstream.syncbuf}, class template \tcode{basic_syncbuf}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_syncbuf;

  // \ref{syncstream.syncbuf.special}, specialized algorithms
  template<class charT, class traits, class Allocator>
    void swap(basic_syncbuf<charT, traits, Allocator>&,
              basic_syncbuf<charT, traits, Allocator>&);

  using syncbuf = basic_syncbuf<char>;
  using wsyncbuf = basic_syncbuf<wchar_t>;

  // \ref{syncstream.osyncstream}, class template \tcode{basic_osyncstream}
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
    class basic_osyncstream;

  using osyncstream = basic_osyncstream<char>;
  using wosyncstream = basic_osyncstream<wchar_t>;
}
\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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_syncbuf : public basic_streambuf<charT, traits> {
  public:
    using char_type      = charT;
    using int_type       = traits::int_type;
    using pos_type       = traits::pos_type;
    using off_type       = traits::off_type;
    using traits_type    = traits;
    using allocator_type = Allocator;

    using streambuf_type = basic_streambuf<charT, traits>;

    // \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<Allocator>::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<Allocator>::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<class charT, class traits, class Allocator>
  void swap(basic_syncbuf<charT, traits, Allocator>& a,
            basic_syncbuf<charT, traits, Allocator>& 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 charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
  class basic_osyncstream : public basic_ostream<charT, traits> {
  public:
    using char_type   = charT;
    using int_type    = traits::int_type;
    using pos_type    = traits::pos_type;
    using off_type    = traits::off_type;
    using traits_type = traits;

    using allocator_type = Allocator;
    using streambuf_type = basic_streambuf<charT, traits>;
    using syncbuf_type   = basic_syncbuf<charT, traits, Allocator>;

    // \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<charT, traits>& os, const Allocator& allocator)
      : basic_osyncstream(os.rdbuf(), allocator) {}
    explicit basic_osyncstream(basic_ostream<charT, traits>& 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<syncbuf_type*>(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<charT, traits>(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<charT, traits>::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{<filesystem>} synopsis}

\indexheader{filesystem}%
\begin{codeblock}
#include <compare>              // 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<chrono::file_clock>;

  // \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<class charT> struct formatter<filesystem::path, charT>;

  // \ref{fs.path.hash}, hash support
  template<class T> struct hash;
  template<> struct hash<filesystem::path>;
}

namespace std::ranges {
  template<>
    inline constexpr bool @\libspec{enable_borrowed_range}{directory_iterator}@<filesystem::directory_iterator> = true;
  template<>
    inline constexpr bool @\libspec{enable_borrowed_range}{recursive_directory_iterator}@<filesystem::recursive_directory_iterator> = true;

  template<>
    inline constexpr bool @\libspec{enable_view}{directory_iterator}@<filesystem::directory_iterator> = true;
  template<>
    inline constexpr bool @\libspec{enable_view}{recursive_directory_iterator}@<filesystem::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<value_type>;
    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<class Source>
      path(const Source& source, format fmt = auto_format);
    template<class InputIterator>
      path(InputIterator first, InputIterator last, format fmt = auto_format);
    template<class Source>
      path(const Source& source, const locale& loc, format fmt = auto_format);
    template<class InputIterator>
      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<class Source>
      path& operator=(const Source& source);
    template<class Source>
      path& assign(const Source& source);
    template<class InputIterator>
      path& assign(InputIterator first, InputIterator last);

    // \ref{fs.path.append}, appends
    path& operator/=(const path& p);
    template<class Source>
      path& operator/=(const Source& source);
    template<class Source>
      path& append(const Source& source);
    template<class InputIterator>
      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<value_type> x);
    path& operator+=(const value_type* x);
    path& operator+=(value_type x);
    template<class Source>
      path& operator+=(const Source& x);
    template<class EcharT>
      path& operator+=(EcharT x);
    template<class Source>
      path& concat(const Source& x);
    template<class InputIterator>
      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 EcharT, class traits = char_traits<EcharT>,
             class Allocator = allocator<EcharT>>
      basic_string<EcharT, traits, Allocator>
        string(const Allocator& a = Allocator()) const;
    std::string    display_string() const;
    std::string    native_encoded_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 EcharT, class traits = char_traits<EcharT>,
             class Allocator = allocator<EcharT>>
      basic_string<EcharT, traits, Allocator>
        generic_string(const Allocator& a = Allocator()) const;
    std::string    generic_display_string() const;
    std::string    generic_native_encoded_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<value_type> 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<class charT, class traits>
      friend basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& os, const path& p);
    template<class charT, class traits>
      friend basic_istream<charT, traits>&
        operator>>(basic_istream<charT, traits>& is, path& p);
  };
}
\end{codeblock}

\indexlibrarymember{value_type}{path}%
\pnum
\tcode{value_type} is a \grammarterm{typedef-name} 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
the current locale encoding and the Windows \tcode{AreFileApisANSI} 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<EcharT, traits, Allocator>}. A function
  argument \tcode{const Source\&} \tcode{source} shall have an
  effective range \range{source.begin()}{source.end()}.
\item \tcode{basic_string_view<EcharT, traits>}. 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 an 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<Source>::value_type()}.
\item A character array that after array-to-pointer decay results in a
  pointer to the start of an 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<decay_t<Source>>::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<decay_t<Source>>::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<class Source>
  path(const Source& source, format fmt = auto_format);
template<class InputIterator>
  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<class Source>
  path(const Source& source, const locale& loc, format fmt = auto_format);
template<class InputIterator>
  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<wchar_t, char, mbstate_t>} 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<wchar_t> 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<class Source>
  path& operator=(const Source& source);
template<class Source>
  path& assign(const Source& source);
template<class InputIterator>
  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<class Source>
  path& operator/=(const Source& source);
template<class Source>
  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<class InputIterator>
  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<value_type> x);
path& operator+=(const value_type* x);
template<class Source>
  path& operator+=(const Source& x);
template<class Source>
  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<class EcharT>
  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<class InputIterator>
  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 EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>>
  basic_string<EcharT, traits, Allocator> 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{system_encoded_string}{path}%
\indexlibrarymember{wstring}{path}%
\indexlibrarymember{u8string}{path}%
\indexlibrarymember{u16string}{path}%
\indexlibrarymember{u32string}{path}%
\begin{itemdecl}
std::string native_encoded_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}

\indexlibrarymember{display_string}{path}%
\begin{itemdecl}
std::string display_string() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{std::format("\{\}", *this)}.
\begin{note}
The returned string is suitable for use with formatting\iref{format.functions}
and print functions\iref{print.fun}.
\end{note}
\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 EcharT, class traits = char_traits<EcharT>, class Allocator = allocator<EcharT>>
  basic_string<EcharT, traits, Allocator> 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_system_encoded_string}{path}%
\indexlibrarymember{generic_wstring}{path}%
\indexlibrarymember{generic_u8string}{path}%
\indexlibrarymember{generic_u16string}{path}%
\indexlibrarymember{generic_u32string}{path}%
\begin{itemdecl}
std::string generic_native_encoded_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}

\indexlibrarymember{generic_display_string}{path}%
\begin{itemdecl}
std::string generic_display_string() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{std::format("\{:g\}", *this)}.
\begin{note}
The returned string is suitable for use with formatting\iref{format.functions}
and print functions\iref{print.fun}.
\end{note}
\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<value_type> 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<class charT, class traits>
  friend basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const path& p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to \tcode{os << quoted(p.string<charT, traits>())}.
\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<class charT, class traits>
  friend basic_istream<charT, traits>&
    operator>>(basic_istream<charT, traits>& is, path& p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
basic_string<charT, traits> 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<class charT> struct formatter<filesystem::path, charT> {
    constexpr void set_debug_format();

    constexpr typename basic_format_parse_context<charT>::iterator
      parse(basic_format_parse_context<charT>& ctx);

    template<class FormatContext>
      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<charT>::iterator
  parse(basic_format_parse_context<charT>& 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<class FormatContext>
  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<filesystem::path::value_type>()}
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<filesystem::path>;
\end{itemdecl}

\begin{itemdescr}
\pnum
For an object \tcode{p} of type \tcode{filesystem::path},
\tcode{hash<filesystem::path>()(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<class charT, class traits>
      friend basic_ostream<charT, traits>&
        operator<<(basic_ostream<charT, traits>& 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<class charT, class traits>
  friend basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& 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()} 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{outputblock}
/dir1
  file1
  file2
  dir2
    file3
\end{outputblock}

Calling \tcode{copy("/dir1", "/dir3")} would result in:
\begin{outputblock}
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
\end{outputblock}

Alternatively, calling \tcode{copy("/dir1", "/dir3", copy_options::recursive)} would result in:
\begin{outputblock}
/dir1
  file1
  file2
  dir2
    file3
/dir3
  file1
  file2
  dir2
    file3
\end{outputblock}
\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<int>(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 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<uintmax_t>(-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<uintmax_t>(-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{true} if a file \tcode{p} has been removed and \tcode{false} otherwise.
\begin{note}
Absence of a file \tcode{p} is not an error.
\end{note}

\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<uintmax_t>(-1)}.
  For the signature with argument \tcode{ec}, all members are set to
  \tcode{static_cast<uintmax_t>(-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{<cstdio>} synopsis}

\indexheader{cstdio}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{FILE}%
\indexlibraryglobal{fpos_t}%
\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}
#define __STDC_VERSION_STDIO_H__ 202311L

namespace std {
  using size_t = @\textit{see \ref{support.types.layout}}@;
  using FILE = @\seebelow@;
  using fpos_t = @\seebelow@;
}

#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@
#define @\libmacro{_IOFBF}@ @\seebelow@
#define @\libmacro{_IOLBF}@ @\seebelow@
#define @\libmacro{_IONBF}@ @\seebelow@
#define @\libmacro{BUFSIZ}@ @\seebelow@
#define @\libmacro{EOF}@ @\seebelow@
#define @\libmacro{FOPEN_MAX}@ @\seebelow@
#define @\libmacro{FILENAME_MAX}@ @\seebelow@
#define @\libmacro{_PRINTF_NAN_LEN_MAX}@ @\seebelow@
#define @\libmacro{L_tmpnam}@ @\seebelow@
#define @\libmacro{SEEK_CUR}@ @\seebelow@
#define @\libmacro{SEEK_END}@ @\seebelow@
#define @\libmacro{SEEK_SET}@ @\seebelow@
#define @\libmacro{TMP_MAX}@ @\seebelow@
#define @\libmacro{stderr}@ @\seebelow@
#define @\libmacro{stdin}@ @\seebelow@
#define @\libmacro{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
The return from each function call
that delivers data
to the host environment
to be written to a file (\xrefc{7.23.3})
is an observable checkpoint\iref{intro.abstract}.

\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.23}

\rSec2[cinttypes.syn]{Header \tcode{<cinttypes>} 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{PRIbN}%
\indexlibraryglobal{PRIBN}%
\indexlibraryglobal{SCNdN}%
\indexlibraryglobal{SCNiN}%
\indexlibraryglobal{SCNoN}%
\indexlibraryglobal{SCNuN}%
\indexlibraryglobal{SCNxN}%
\indexlibraryglobal{SCNbN}%
\indexlibraryglobal{PRIdLEASTN}%
\indexlibraryglobal{PRIiLEASTN}%
\indexlibraryglobal{PRIoLEASTN}%
\indexlibraryglobal{PRIuLEASTN}%
\indexlibraryglobal{PRIxLEASTN}%
\indexlibraryglobal{PRIXLEASTN}%
\indexlibraryglobal{PRIbLEASTN}%
\indexlibraryglobal{PRIBLEASTN}%
\indexlibraryglobal{SCNdLEASTN}%
\indexlibraryglobal{SCNiLEASTN}%
\indexlibraryglobal{SCNoLEASTN}%
\indexlibraryglobal{SCNuLEASTN}%
\indexlibraryglobal{SCNxLEASTN}%
\indexlibraryglobal{SCNbLEASTN}%
\indexlibraryglobal{PRIdFASTN}%
\indexlibraryglobal{PRIiFASTN}%
\indexlibraryglobal{PRIoFASTN}%
\indexlibraryglobal{PRIuFASTN}%
\indexlibraryglobal{PRIxFASTN}%
\indexlibraryglobal{PRIXFASTN}%
\indexlibraryglobal{PRIbFASTN}%
\indexlibraryglobal{PRIBFASTN}%
\indexlibraryglobal{SCNdFASTN}%
\indexlibraryglobal{SCNiFASTN}%
\indexlibraryglobal{SCNoFASTN}%
\indexlibraryglobal{SCNuFASTN}%
\indexlibraryglobal{SCNxFASTN}%
\indexlibraryglobal{SCNbFASTN}%
\begin{codeblock}
#include <cstdint>  // 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 __STDC_VERSION_INTTYPES_H__ 202311L

#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 PRIb@\placeholdernc{N}@ @\seebelow@
#define PRIB@\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 SCNb@\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 PRIbLEAST@\placeholdernc{N}@ @\seebelow@
#define PRIBLEAST@\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 SCNbLEAST@\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 PRIbFAST@\placeholdernc{N}@ @\seebelow@
#define PRIBFAST@\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 SCNbFAST@\placeholdernc{N}@ @\seebelow@
#define @\libmacro{PRIdMAX}@ @\seebelow@
#define @\libmacro{PRIiMAX}@ @\seebelow@
#define @\libmacro{PRIoMAX}@ @\seebelow@
#define @\libmacro{PRIuMAX}@ @\seebelow@
#define @\libmacro{PRIxMAX}@ @\seebelow@
#define @\libmacro{PRIXMAX}@ @\seebelow@
#define @\libmacro{PRIbMAX}@ @\seebelow@
#define @\libmacro{PRIBMAX}@ @\seebelow@
#define @\libmacro{SCNdMAX}@ @\seebelow@
#define @\libmacro{SCNiMAX}@ @\seebelow@
#define @\libmacro{SCNoMAX}@ @\seebelow@
#define @\libmacro{SCNuMAX}@ @\seebelow@
#define @\libmacro{SCNxMAX}@ @\seebelow@
#define @\libmacro{SCNbMAX}@ @\seebelow@
#define @\libmacro{PRIdPTR}@ @\seebelow@
#define @\libmacro{PRIiPTR}@ @\seebelow@
#define @\libmacro{PRIoPTR}@ @\seebelow@
#define @\libmacro{PRIuPTR}@ @\seebelow@
#define @\libmacro{PRIxPTR}@ @\seebelow@
#define @\libmacro{PRIXPTR}@ @\seebelow@
#define @\libmacro{PRIbPTR}@ @\seebelow@
#define @\libmacro{PRIBPTR}@ @\seebelow@
#define @\libmacro{SCNdPTR}@ @\seebelow@
#define @\libmacro{SCNiPTR}@ @\seebelow@
#define @\libmacro{SCNoPTR}@ @\seebelow@
#define @\libmacro{SCNuPTR}@ @\seebelow@
#define @\libmacro{SCNxPTR}@ @\seebelow@
#define @\libmacro{SCNbPTR}@ @\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
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.
Each of the \tcode{PRIB} macros listed in this subclause
is defined if and only if \tcode{fprintf} supports
the \tcode{B} conversion specifier.
